C++数据类型
C++数据类型
const限定符
const是C++中一个比#define更好的规定符号常量的关键字语法。
该关键字声明的变量将只被允许初始化而不允许再被修改。
为常量命名时推荐使用全大写。
花括号初始化
可以使用花括号对数据类型进行初始化。在该语法下:
- 只可以使用常量进行初始化
- 在初始化数据超过数据类型表示范围或超出容器尺寸时,编译器将报错
- 。可以省略等号
- 对容器使用花括号初始化时,内部无元素将会为容器设置为全零
char it{998244353}; // nope
int arr[4]{1, 2, 3, 4, 5}; // nope
char it{12}; // yep
int arr[4]{1, 2, 3, 4}; // yep
int arr[4]{}; // all zero
C风格字符串与字符串常量
C风格字符串一般指结尾为'\0'的字符数组
用双引号包裹的一般称为字符串常量,字符串常量隐式的包含'\0',因此不需要再添加'\0'。
使用字符串常量初始化字符数组时,若字符串常量长度不足字符数组长度,其余元素会全部设置为'\0'
切记只包含一个字符的字符串常量也与字符不同。除了字符串常量包含'\0'之外,字符将返回ASCLL值,而字符串常量将返回地址。
所有被空格,制表符,换行符分割的字符串常量将被自动拼接为一个字符串常量。
C风格字符串面向行的输入
cin.getline()
该方法包含两个参数,第一个是用于存储行输入的字符数组(不可使用string),第二个是即将读取的字符数量(需要包含'\0')
cin.get()
该方法与cin.getline方法类似,唯一区别是,cin.get不会读取并丢弃换行符。
但cin.get支持不指定任何参数,此时会直接读取下一个字符就像getchar一样。在使用cin.get方法时,使用无参数的cin.get方法来为下一行的读入做好准备吧
其他
cin.getline与cin.get方法在有参数时返回值都是cin对象,因此你可以在一行一句中连续调用这两个方法(注意cin.get方法在无参数时返回值是所读字符的ASCLL码)
char charr[100];
cin.get(charr, 20).get();
cin.get(charr, 20);
// or
cin.getline(charr, 20).getline(charr, 20);
注意有很多输入都是不会读取空格,换行符之类的分割符的,在混合使用正常读入与行读入时,注意处理正常读入之后的换行符
int num;
(cin >> num).get(); // use get to solve '\n' behind
string str;
getline(cin, str);
string类行输入
getline
该函数包含两个参数,第一个指定输入流,第二个参数指定用于存储的string变量,该函数读入一行时会自动处理换行符,且不用指定字符长度。
原始字符串常量
原始字符串是一种无视任何转义的字符串,是什么字符就是什么字符。
该字符串常量使用R"(your string)"来定义,与众不同的是,原始字符串的定界符不一定需要使用"(和)",你可以在双引号与括号之间添加任意字符,来达到与string内容进行区分的目的
下例程序展示了如何通过自定义定界符输出本该被转义的内容
cout << R"+("(Who wouldn't?"), she whispered.)+";
运行结果如下:
"(Who wouldn't?"), she whispered.
结构体
C++中使用结构体创建变量时,不再需要标明struct关键字
并且同样支持花括号初始化方法,参数位置先后顺序对应即可
C++的结构体也可以拥有成员函数,不过一般会直接用类
共用体
共用体与结构体的语法基本相同,但共用体在同一时间段只可使用其中一个成员变量
枚举类型
枚举类型的语法依然类似结构体,但其成员变量全是一些没有数据类型的名称(实际上是int类型)。
枚举类型会自动为其内部的成员变量赋一个int值,按先后顺序从0开始,每个未赋值成员变量的值是其前一个变量加一
您可以在定义枚举类型时显式的为其内部的成员变量赋值,以达到自定义赋值的效果
可以为多个成员变量赋同一个值,并且C++中可以使用long long 范围进行赋值
enum tempenum
{
zero,
null = 0,
one,
numero_uno = 1
};
枚举类型声明的变量只能在该枚举类型的成员变量里取值(即使是在枚举类型赋值范围内的int值也不可以为枚举类型声明的变量赋值),并且带有对应的int值,当进行算术运算时,该值将被自动类型转换
如果您执意要对枚举类型声明的变量进行int赋值,您当然可以使用强制类型转换,但当int值超出枚举类型有效范围时,将出现不可预测的结果
具体探究枚举类型的有效范围,该有效范围等于枚举类型内部赋值已使用的bit位的对应最大最小值
自由存储空间
new
C++中使用new 关键字来分配空间,该关键字返回一个指定数据类型的内存地址,从堆区。
typeName* pointerName = new typeName;
可以使用new来分配符合类型,比如分配一个数组的空间
int* p=new int [10];
delete
使用delete来释放指定地址的内存,但请注意delete只能用于释放new分配的内存,不可对变量地址进行释放
int num;
int* ptr=#
delete ptr;//nope
int* ptr2=new int;
delete ptr2;//yep
使用delete释放数组空间时,需要相应的加上方括号
int* p=new int [10];
delete [] p;
其他
new与delete的注意事项如下:
- 不要用delete释放不是new分配的空间
- 不要对同一个内存释放两次
- new与delete的方括号使用一定要匹配
- 对空指针应用delete是安全的
指针与数组
关于指针与数组名的等价关系是C语言的核心之一。
本节补充一些细枝末节的知识点
- 在使用sizeof时,数组名将返回数组长度,而指针会返回指针长度,哪怕两者指向的是同一地址
- 数组名不可进行算术运算,而指针却可以,并且有特殊的运算规则,正如c语言中的那样。
- 数组名与数组名地址任然存在差别,数组名是一个指向单一元素的地址,而数组名地址则是一个指向整个数组的地址。在进行指针算术时该差别非常重要
C风格字符串指针
在C语言中我们知道C风格字符串名是首字符的地址,就像数组名那样
对一个字符地址进行cout时,会将其当作C风格字符串进行处理,持续输出字符直到遇到'\0'
实际上字符串常量所传递的也是首字符地址
存储
自动存储
在函数内部定义局部变量将使用自动存储空间,一般在栈区,这种变量被称为自动变量,随着代码块活动开始而产生,随代码块活动终结而消亡
静态存储
想要变量一直存在不受代码块影响?那么使用静态存储,这种方式存储的变量可以持续的作用于全局。在所有代码块外定义或使用static关键字来修饰以进行静态存储
动态存储
上述的new和delete操作被称为动态存储,该方式使得内存的生命周期不受代码块影响,而是独立的由new和delete进行操作。
但这种操作带来了内存泄漏的风险,即使用new分配内存后,不使用delete进行释放.使得被分配的内存在整个程序活动周期内不再可用。再次提醒,new和delete一定要配套使用
vector与array
关于vector与array的使用方式详见
在此补充两点:
- vecotr使用自由存储区或称堆区,而array默认使用静态存储区或称栈区
- vector与array拥有成员函数at,该方法访问指定下标的元素。与方括号访问的区别是,该方法会检查下标是否合法,对不合法的下标,该方法会报错。

浙公网安备 33010602011771号