目录
一.C和C++的区别
i)头文件的区别
C++中的头文件一般没有.h,C++对C语法做了兼容
所以C中的头文件,仍然可以在C++文件中使用,一般去掉C中头文件的.h,在前面加上c
例: stdio.h ----> cstdio
ii)拓展名的区别
C语言:.c ----->使用gcc编译器
C++: .cpp , .C ------>使用g++编译器,g++比gcc编译器语法更加严格(主函数的返回值类型不能修改)
iii)语法区别(语法的扩充)
- 命名空间
- 函数重载(一名多用)
- 字符串的使用(string类型)
- 引用(和C中的指针类似)
- 面向对象的特征(封装、继承和多态) C++是面向对象语言
- STL标准模板库(前面C写的所有数据结构C++中可以直接使用)
- 模板编程
- 智能指针(C++11开始的新特性)
- lambda表达式
二.输入输出流类
2.1输出cout
1)cout的基本使用
cout是ostream类提供的类对象,printf()是C库中的函数
cout可以实现级联的输出(连续输出多个)
如果使用cout,需要导入头文件,引入命名空间std
cout << a << endl;
2)cout控制格式的输出
通过关键字控制输出格式,或者通过函数控制输出格式 #include
setbase(); 控制进制输出
setw(); 控制宽度输出 ---->left关键字
setprecison(); 控制包含小数点位数输出
2.2输入cin
是istream输入流提供的类对象
在istream中对>>运算符进行了运算符重载,>>变成输入运算符
仍然不需要格式符,会根据类型自动推导
cin >> a;
三.命名空间
在C++中,命名空间(Namespace)是一种避免命名冲突的方式,它可以把一组具有相似功能的实体(包括类、函数、变量等)封装在一起,形成一个独立的区域。命名空间可以有效地防止在大型程序中因命名重复而导致的冲突问题。
namespace 命名空间名 { //标识符(变量名、函数名、类型名) }
2.1使用命名空间中的标识符
定义在命名空间中的标识符,不能直接使用,需要导入后再使用
i)全局导入命名空间
using namespace 命名空间名; ---->该语句表示,导入命名空间中的所有标识符,在该语句后面,命名空间中的所有标识符可以任意使用(一般写在头文件下方,主函数上方)
ii)局部导入命名空间中标识符
:: ----->域限定符
在哪里使用标识符,就在哪个位置导入标识符
std::cout << "hello" << std::endl; //只在使用cout的位置导入标识符std
iii)导入命名空间中的部分标识符
使用using 命名空间名::标识符名; ----->在该语句后,可以使用导入的指定标识符
2.2命名空间中声明函数
在命名空间中声明函数,在命名空间外定义函数,需要在函数名前加上命名空间名::函数名
namespace Test { //存放标识符 //定义变量 int num = 100; //定义结构体类型 struct Stu { int age; }; //声明函数 void show(); } //定义命名空间中的show()函数 void Test::show() { cout << "hello" << std::endl; }
2.3命名冲突问题
何时发生命名冲突,当同时可以访问到两个同名标识符时发生命名冲突
i)命名空间和局部变量冲突
如果不导入命名空间,不会发生冲突
即使导入了命名空间,默认访问局部变量,也不发生访问的冲突
如果导入命名空间后,想要访问命名空间中的标识符,在标识符前加上命名空间名::
ii)命名空间和全局变量冲突
如果不导入命名空间中的标识符,不会发生冲突,直接访问全局变量
导入命名空间中标识符后发生冲突:
- 访问命名空间中的标识符: 命名空间名::标识符名
- 访问全局变量: ::标示符名(访问全局变量)iii)两个命名空间中的标识符冲突
iii)两个命名空间中的标识符冲突
必须是在同时导入了两个命名空间时才会发生标识符冲突问题
解决方式: 命名空间名::标识符 ----->直接指定访问某一个命名空间中的标识符
2.4匿名空间
没有名字的命名空间就叫做匿名空间
namespace { //标识符 }
匿名空间中的标识符,无需使用using导入,也可以访问
如果发生命名冲突,可以使用 ::标识符名,来访问匿名空间中的标识符
如果存在命名空间和匿名空间标识符冲突的情况,(尽量不要导入有名字的命名空间中的标识符)
如果匿名空间和全局变量冲突 ::标识符名(默认访问全局变量)
2.5命名空间添加,嵌套,重命名
1)命名空间的添加
如果定义了同名的命名空间,会自动合并成同一个命名空间
(将后续定义的内容添加到原有的命名空间中)
2)命名空间的嵌套
存在嵌套命名空间时,只需要根据定义顺序,通过域限定符一层一层访问下去即可
3)命名空间的重命名
格式
namespace 新名字 = 旧名字;
四.字符串的使用
4.1string类
string类
是C++中封装好的一个类(可以理解为是一种数据类型)
定义字符串:string 变量名;
#include <iostream> using namespace std; int main() { string s1; //定义了一个字符串变量s1 string s2 = "hello"; //定义了一个字符串变量s2使用hello初始化 cout << "s1 = " << s1 << endl; cout << "s2 = " << s2 << endl; string s3(5,'a'); //定义了一个字符串变量s3使用5个a进行初始化 cout << "s3 = " << s3 << endl; string s4("hi"); //定义了一个字符串变量s4使用hi字符串初始化 cout << "s4 = " << s4 << endl; string s5 = s4; //定义了一个字符串变量s5使用s4初始化 cout << "s5 = " << s5 << endl; cout << s3+s2 << endl; //stringl类对象,可以直接通过运算符完成拼接 return 0; }
4.2C风格和C++风格字符串的转化
C风格的字符串可以直接转换成C++风格
C++风格的字符串,不能直接转换成C风格的字符串,需要借助于特殊的函数
data(),c_str(); //这两个函数的返回值,都是char*类型的指针
#include <iostream> #include <cstring> using namespace std; int main() { string s1 = "a"; //定义了一个字符串变量s1 string s2 = "hello"; //定义了一个字符串变量s2使用hello初始化 cout << "s1 = " << s1 << endl; cout << "s2 = " << s2 << endl; cout << strcmp(s1.data(),s2.c_str()) << endl; return 0; }
4.3string类中常用的函数
i)at()
按位置访问字符串
使用at访问字符串时超出字符串范围代码会抛出异常
#include <iostream> using namespace std; int main() { string s1 = "abcdefg"; cout << s1[0] << endl; //通过下标的方式访问字符串中的字符 cout << s1[100] << endl; cout << s1.at(100) << endl; //直接代码抛出异常,不继续向后执行 cout << s1.at(0) << endl; //不会输出 return 0; }
ii)empty()/clear()
empty():判断字符串是否为空
clear():清空字符串
iii) length()/size()
求字符串的长度
输入字符串
getline()的两个参数,第一个参数是输入流对象,第二个参数输入的字符串变量
string s1; getline(cin,s1);
五.bool类型
常用在函数的返回值
- C语言中不直接支持bool类型,但是C++中直接支持bool类型,结果是一个逻辑值
非0即1,true和false
- bool类型的变量可以使用true和false赋值,也可以使用数值赋值
- cout输出时,默认使用数字表示法输出bool类型的值
- 如果想要使用单词输出bool类型的值,在输出时加上boolalpha,想要恢复数字表示法加上noboolalpha
- bool类型的大小1Byte,因为计算机分配内存的基本单位是字节
#include <iostream> using namespace std; int main() { bool t = 0.01; cout << t << endl; cout << boolalpha << t << endl; //true cout << noboolalpha << t << endl; //1 cout << sizeof(t) << endl; //1Byte return 0; }