01.c++基础

文章目录

一、第一个C++程序

1 编译方式
  • 1)gcc xx.cpp -lstdc++

    tarena@ubuntu:~/me/C++/day01$ gcc first01.cpp -lstdc++

    @ubuntu:~/me/C++/day01$ a.out

    hello world!

    2)g++ xx.cpp //推荐

    tarena@ubuntu:~/me/C++/day01$ g++ first01.cpp

    tarena@ubuntu:~/me/C++/day01$ a.out

    hello world!

2 文件扩展名
  • 1) .cpp //推荐

    2) .cxx

    3) .cc

    4) .C

3 头文件
  • #include<iostream>

    --> C++中和I/O相关的类型,对象,函数都在该头文件中

    --> C++中绝大多数头文件没有.h后缀

    --> C++开发中,可以直接使用c语言头文件中,同时还提供了一套不带.h的替换版本

    eg:

    #include <stdio.h> ==> #include<cstdio>

    #include <stdlib.h> ==> #include<cstdlib>

    #include <string.h> ==> #include<cstring>

4 标准的输入输出
  • 1) 使用cin对象表示标准输入//类似scanf()

    int i;

    scanf("%d",&i);//C

    cin >> i; //C++

    -------------------------------------------------------

    int i,double d;

    scanf("%d%lf",&i,&d);//c

    cin >> i >> d;//c++

    注:">>"输入操作符

     

    2) 用cout对象表示标准输出//类似printf()

    int i=123;

    printf("%d\n",i);//C

    count << i << endl;//C++

    注:"<<"输出操作符

    --------------------------------------

    int i = 123,double d = 4.56;

    printf("%d,%lf\n",i,d);//C

    cout << i <<','<< d << endl;//C++

二、名字空间(命名空间) 改变作用域

1 功能:
  • 1) 避免名字冲突

    2) 划分逻辑单元

2 定义名字空间
  • namespace 空间名{

    名字空间成员1;

    名字空间成员2;

    ...............

    }

    注:名字空间成员可以是全局函数,全局变量,自定义类型,名字空间.

3 名字空间成员使用
  • 1)通过作用域限定操作符"::"

    空间名::要访问成员;

    eg:

    "std::cout" 表示使用标准名字空间里面cout

    2)名字空间指令

    using namespace 空间名;

    在该条指令以后的代码中,指定名字空间成员都可以见,可以直接访问,省略"空间名::"

    3)名字空间声明

    using 空间名::名字空间成员;

    将名字空间中特定一个成员引入到声明所在的作用域中,在该作用域访问这个成员就如同是访问自己的成员一样,可以直接访问,省略"空间::"

4 全局作用域和无名(匿名)名字空间 //了解
  • 1) 没有放在任何名字空间的成员,属于全局作用域,可以直接访问,如果和局部作用域的成员名字一样,局部优先;这时如果还希望访问到全局作用域的成员

    可以通过"::成员"形式来显式指明

    2) 定义名字空间时,可以没有名字,即为无名名字空间,对于无名空间里面的成员和全局作用域的成员一样,也可以直接访问,只是被局限在当前文件中

    全局可在整个程序内使用

    匿名名字空间只可以在本文件中使用

    ::变量名或函数名,是访问全局变量和全局函数的方法.

5 名字空间嵌套//了解
    eg:
        namespace ns1{
            int num = 10;
            namespace ns2{
                int num = 20;
                namespace ns3{
                    int num = 30;
                }
            }
        }
        cout << ns1::num << endl;
        cout << ns1::ns2::num << endl;
        cout << ns1::ns2::ns3::num << endl;

三、C++的结构体,联合体,枚举

1 结构体
  • 1)当定义结构体变量时可以省略struct关键字

    2)在结构体内部可以直接定义函数,称为成员函数(方法),成员函数中可以直接访问当前结构体中的其它成员

2 联合体(union)//了解
  • 1)当定义联合体变量时可以省略union关键字

    2)支持匿名联合

3 枚举
  • 1)当定义枚举变量时,可以省略枚举关键字.

    2)C++中枚举被看做是独立的数据类型,而c语言中枚举本质就是整型数.

    enum STATE{SLEEP,RUN,STOP};
    STATE s;
    s = STOP;//C:ok,C++:ok
    s = 2;//C:ok,C++:error
  • 枚举可以当做返回类型.

四、C++的字符串

1 回顾c中字符串
  • 1) 字面值常量 "hello"

    2) 字符指针 char*

    3) 字符数组 char[]

eg:
	char* p1 = "abcdef";
	char* p2 = "123456";
	strcpy(p1,p2);//段错误
	段错误信号 11
	---------------------------
	char arr1[] = "hello";
	char arr2[] = "wangjianli";
	strcpy(arr1,arr2);//内存越界,结果未知,危险!
	--------------------------------
	char arr[] = "hello";
	char *p="world";
	p = arr;//OK
	arr = p;//error
	---------------------------------------
2 C++可以完全兼容c中字符串表示方式,同时增加了string类型转换表示字符串.
  • 1)字符串的定义
 	string s;//定义空字符串
 	string s = "xxxx"; //定义同时初始化
 	----------------------------------------------------
 	//下面两种写法实际初始化和上面相同
 	string s("xx");
 	string s = string("xx");
 	
 	//char*类型指针,指向了一块在堆区动态分配的内存,这块内存存放了字符串的值.
 	namespace std{
 		struct string{
 			char *;
 		}
 	}
  • 1) 字符串拷贝: =
	string s1 = "hello";
	string s2;
	s2 = s1;//拷贝
  • 2) 字符串的连接: + +=
	string s1 ="abc";
	string s2 = s1 + "def";
	cout << s2 <<endl;//"abcdef"
  • 3) 字符串比较: == != > < >= <=
	if(s1 == s2){.....}
  • 4) 随机访问: []
	string s ="hello";
	s[0] = 'H';
  • 5) 成员函数
	size()/length();//获取字符串长度	
	string str = "xxx";
	str.size();
	str.length();
	
	c_str();//获取c风格的字符串(const char *)
	string s1 ="xxx";
	const char* s2 = "xxx";
	s1 = s2;//OK
	s2 = s1.c_str();//ok
	void cfunc(const char* str){}
	cfunc(str);

五、C++的布尔类型: bool

  • 1 bool类型是C++中基本数据类型,专门表示逻辑值,逻辑值真为true,逻辑假为false

    2 bool类型在内存占一个字节:1表示true,0表示false

    3 bool类型变量可以接收任何类型表达式的结果,数值非零则为真,为零则为假.

六、操作符别名 //了解

	&& <==> and
	|| <==> or
	^  <==> xor
	{  <==> <% 
	}  <==> %>
	...

七、C++的函数

1 函数重载(overload)
  • 1)定义

    在相同作用域中,可定义同名函数,但是它们的形参必须有所区分(参数个数,参数类型,和形参变量名无关),这样的函数关系称为函数重载.

    注:函数重载和返回类型无关

    eg:图形库中绘图函数

	void drawRect(int x,int y,int w,int h){....}
	void drawCircle(int x,int y,int r){....}
	......
	--------------------------------------------------------
	void draw(int x,int y,int w,int h){...}
	void draw(int x,int y,int r){...}
	......
  •  

    2)函数重载匹配

    • 调用函数时,编译器根据实参和形参匹配程度,自动选择最好的重载版本.

      当前g++编译器匹配的优先级:(优先级以编译器的结果为准)

      完全匹配>=常量转换>升级转换>降级转换>省略号匹配

	char* > const char *
	char = const char
  • 当通过函数指针调用重载关系的函数时,根据指针类型选择匹配的重载版本.(函数指针在定义时已经匹配完成,函数指针是什么类型,调用什么类型的函数)
  •  

    3)函数重载的原理 (函数的重入是什么????)

    nm x.0

    g++ 在编译函数,会进行函数换名

    void func(int i,double j){}

    _Z4funcid 4是函数名字符数 i 形参类型int d 形参类型double

    C++的编译器是通过函数换名,将参数表的类型信息整合到新的函数名中,实现解决函数重载和名字冲突的矛盾.

    (笔试题):C++中extern "C"声明作用?

    可以在函数声明前面加入 extern "C" ,要求C++编译器不要对该函数进行换名,便于C程序直接调用.

    注:被extern "C"声明的函数无法被重载.

    --------------------------------------------

    vi -O 用竖屏方式打开多个文件

    vi -o 用横屏方式打开

    vs

    sp

    Ctrl + W + W 进行换屏

 

2 函数的哑元参数 (C语言直接报错)
  • 1)定义

    定义函数时,只有类型而没有变量名形参被称为哑元.

    void func(int /*哑元*/) {...}

    2)使用哑元的场景

    -->操作符重载,通过哑元区分前后++/--(后面讲)

    -->兼容旧代码

    eg:
	//算法库:
	void math_func(int a,int b){...}
	//使用者:
	int main(void){
		math_func(10,20);
		...
		math_func(30,40);
	}
	--------------------------------------------
	//算法库升级
	//哑元作为一个显示标记,告诉程序员这个参数没用
	void math_func(int a,int /*哑元*/){...}
	//使用者:
	int main(void){
		math_func(10,20);
		...
		math_func(30,40);
	}

 

3 函数的缺省参数(默认实参)
  • 1) 可以为函数的参数指定缺省值,调用该函数时,如果不给实参,就会取缺省值作为默认实参.

	void func(int a,int b=0/*缺省参数*/){...}
  • 2) 靠右原则

    如果函数的某个参数有缺省值,那么该参数右侧的所有参数都必须带有缺省值.

    3) 如果函数声明和定义分开写,缺省参数应该写在函数声明部分,而定义部分不写(加注释标明);

	void func(...);//函数声明
	void func(...){...}//函数定义
  • 4) 不要和函数重载形成歧义
	void func(int a,int b=20,int c=30);
	void func(int a);
	func(10);

 

4 内联函数(inline) (笔试题)
  • 1) 使用inline关键字修饰的函数即为内联函数,编译器将会 尝试 进行内联优化,可以避免函数的调用开销,提高代码的执行效率.

    开销:保护现场,恢复现场......增加执行时间.

	inline void func(void) {...}
  • 内联关键字对程序的实现没有影响,影响的是编译器的执行.

    内联是在编译时直接用函数机器指令替换调用语句的机器指令,避免调用的跳出跳入的时间耗费.(以空间换时间)

     

    2) 使用说明

    --> 多次调用的小而简单的函数适合内联函数

    --> 调用次数极少或大而复杂的函数不适合内联

    --> 递归函数不能内联(递归函数是否结束依赖于上一次的执行结果,执行次数不确定)

    --> 虚函数不能内联(后面讲)

    • 注: 内联优化只是一种建议,而不是强制要求,对于一个函数能否内联优化主要取决于编译器,有些函数不加inline修饰也会默认处理为内联优化;

      有些函数即便加了inline修饰也会被编译器忽略掉.

     

八、C++的动态内存管理(什么是内存泄露,有什么危害)

1 回顾C语言中的动态内存管理
  • 1)分配:

    malloc()(calloc/realloc/brk/sbrk/mmap)
  • 2)释放:
    free()

 

2 C++的动态内存管理
  • 1) 分配:

    new,new[]
  • 2) 释放:
    delete,delete[]
  • 内存分配时可以同时初始化 new int(200) 将存储区的值初始化为200

new[]分配,必须用delete[]释放,否则会发生内存泄露.

-std=c++11 使用C++11语法

笔试题(new,delete和malloc,free的区别)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值