五、字符串
string类型(可以理解成结构体类型),专门表示字符串,与C中不同,字符串在堆区维护
1、定义字符串
string s;//定义空字符串
string s="hello";//定义同时初始化
也可以这样写
string s("hello");
string s= string("hello");
2、字符串的拷贝:=
c++中字符串的拷贝就是“=”,不再需要调用函数
string s1="hello";
s1=s2;不再会出现段错误,因为在堆区维护,会动态检测,如果空间不够会释放原有空间再分配新空间
3、字符串的连接:+
string s1="hello";
string s2="world";
string s3=s1+s3;//这就完成了字符串的连接
4、字符串的比较 == != >= <= < >
就是用逻辑运算符进行比较,比较方式和C中没什么区别
if(s1==s2){....};
5、随机访问
由于在堆区创建,即可随机访问进行修改了
string s="hello world";
s[0]='H';
这样就可以把h变成H
6、常用的成员函数
size()/length();//这两个都可以获取字符串长度
string s="hello";
cout<<s.size()<<","<<s.length()<<endl;//结果是5,5
7、返回C风格的字符串(const char*)
c_str();
例如:
string cp="abc";
const char* c="def";
cp=c;//warning
c=cp;//error
c=cp.c_str();//ok,但是c如果不加const编译过不去
8、输入字符串
string s;
cin>>s;//遇空格即结束输入
getline(cin,s);//遇"\n"才结束
六、C++布尔类型(bool)
1、bool类型在C++中是基本的数据类型,专门表示逻辑值,逻辑真用true表示,逻辑假用false表示
2、bool类型在内存上占一个字节,数值1表示ture,数值0表示false;
3、bool类型变量可以接受任意类型的表达式结果,结果非零则为true,零为false
七、操作符别名
C语言---------------->C++
&& and
|| or
^ xor
{ <%
} %>
八、C++中的函数
1、函数重载(overload)
①定义:在相同作用域下定义的同名函数,但是他们的参数必须有所区分,这样的函数将构成重载关系,注意与函数的返回类型无关
②调用重载关系的函数时,编译器会根据实参与形参的匹配程度自动选择最优的匹配版本,一般规则:完全匹配>=常量转换>升级转换>降级转换>省略号匹配
所谓升级匹配就是原本数据类型所占字节比要转换的小,浪费空间但能保证精度,反之即是降级转换,无法保证精度。
这里会输出完全匹配的结果,这里的升级匹配和降级匹配都不够好,如果没有完全匹配将会报错,因为升级匹配也不能过度升级,short类型->int类型是可以优于short->char的
注:char*->const char*(稍差与完全匹配)
③函数重载原理
C++编译器通过对函数进行换名,将参数表的类型整合到新的函数名中,解决函数重载名字冲突的矛盾
用nm查看可执行文件,可以看到刚才的test函数都被C++编译后改为_Z4test(参数类型首字母)
有时候我们要在C文件中引用C++中的函数,但是由于C++编译后文件名就被改变了,那么C文件就连接不到cpp文件的函数,我们可以在编译cpp文件时在函数名前加上extern "C",这样要求C++编译器不对该函数进行重命名
注:被extern "C"声明的函数无法重载了
2、哑元参数
①定义:定义函数时,只有类型而没有变量名的形参称为哑元参数
void func(int/*哑元*/){} //函数定义
②使用哑元的场景
-》在操作符重载时,区分前后++,--;(后面操作符重载时说)
-》为了兼容以前的旧代码(升级算法库时)
当升级算法库时,经常会删掉一些不需要的形参以优化函数,这时以前的代码由于多了参数函数无法使用了,加上哑元即可兼容以前的旧代码
3、缺省参数(默认实参)
①定义:可以为函数的部分或全部参数指定缺省值,调用该函数时,如果不给实参的话,就会取缺省值作为默认实参
②靠右原则:如果函数一个参数有缺省值,那么该函数右侧所有参数都必须带有缺省值
③如果需要函数声明,缺省值写在函数声明中,就不写在函数定义中了,但是为了代码可读性,应当在函数定义时加入注释,告知使用函数的人缺省值已经被定义
void func(int a,int b=1,int c=2);
void func(int,int=1,int=2);//和上面完全等价
但是不能再定义void fun(int i){}了,否则会出现歧义错误
4、内联函数
①定义:使用inline关键字修饰的函数称为内联函数,编译器会尝试进行内联优化,可以避免函数调用的开销,提高代码的执行效率
②使用说明
-》多次调用的,小而简单的函数适合内联
-》调用次数极少或大而复杂的函数不适合内联
-》递归函数和虚函数不能内联优化
内联不内联其实是由编译器决定的,并不是加了inline就会内联优化,仅仅是提示编译器而已
九、C++动态内存管理
1、C语言中的动态内存管理
①分配:malloc、calloc、realloc...
②释放:free...
2、C++的动态内存分配
①分配:new、new[]
②释放:delete、delete[]
new和delete不同于c中的malloc和free,new申请空间时会调用构造函数,返回对象类型的指针,和delete释放空间时会可调用析构函数,并且他们都支持操作符重载,但malloc和free没有这样的功能,毕竟C++是面向对象的编程语言,因此在C++中不推荐使用malloc和free
③不能连续delete同一个指针,会出现double free的错误
int *p=new int(321);//动态分配同时初始化
new数组直接初始化,需要用C++11标准,否则会报警告直接在编译后加上 -std=c++11即可