C++笔记
C++ Primer Plus笔记,学校编的教材讲的一言难尽
第二章
C语言中只写main()
默认int main()
。
C++ main()与main(void)等效,而C语言则表示对是否接受参数保持沉默。
主函数的return 0;
可以省略
注释
//
是C++风格,/* */
是C风格。
命名空间
using namespace std;
using std::cout;
格式化
一行代码中不可分割的元素叫做标记(token)。通常必须用空白(空格、制表符和回车)将两个标记分开。
第三章
以两个下划线或下划线和大写字母打头的名称保留给实现。以一个下划线开头的名称保留给实现,用作全局标识符。
命名约定俗成的一些规矩:n表示整型,str或sz表示字符串,b表示布尔值,p表示指针,c表示单个字符。
整数
C++提供了一种灵活的标准,确保了最小长度。
长度
使用sizeof
运算符查看类型名或变量名长度
sizeof(int)
或sizeof test
当查看变量名时,括号是可选的。
声明
C++在C之上增加了新的声明语法
1 | int a(5); |
1 | int enum{5}; |
unsigned是unsigned int的缩写;
进制
第一位为1~9,则为十进制;第一位为0,第二位为1~7,则为8进制;前两位为0x或0X,则为16进制。
编译器通过数字后缀来分配变量长度
1 | cout << sizeof 114514uLL << endl; |
常见的后缀有u(unsigned int),l(long),ul(顺序无所谓,unsigned long),ull(unsigned long long)。
C++中,对不带后缀的十进制整数,将使用能够存储该整数的最小类型来表示,int,long,long long;对不带后缀的八进制或十六进制整数,将采用int,unsigned int,unsigned long,unsigned long long。
字符
可以使用八进制和十六进制编码表示转义序列,如\032
,\x1a
。
char
在默认情况下既不是没有符号,也不是有符号。是否有符号由C++实现决定。
wchar_t
表示宽字符类型,宽字符可以在字符或字符串前加个L标识,如L'p'
,输出显示字符串时使用wcout
常量
C++中使用const定义常量,不推荐使用#define
浮点数
浮点数有E表示法,如3.14E4
等。
类型转换
在计算表达式时,C++将bool、char、unsigned char和short值转换为int。
强制类型转换有两种方式,
1 | (long) thorn |
C++还引入了4个强制类型转换的运算符
1 | static_cast<long>(thorn) |
auto声明自动判断变量类型。
第四章
C++11初始化数组时可省略=
1 | double a[2] {112,1123}; |
字符串拼接
任何两个由空白分隔的字符串常量将自动拼接成一个,第一个字符串末尾的\0
会被取代。
字符串输入
cin
使用空白作为分隔符,处理字符串输入。
读取中间含有空格的字符串可使用cin.getline()
。
一种变体
1 cin.get(a,20).get()
string类型
C++98添加了string类型
1 | string str1; |
string可直接赋值,并且可通过+操作实现字符串拼接
1 | string str1, str2, str3; |
C++使用前缀u8表示Unicode字符串类型,还新增了原始字符串类型,原始字符串中的回车输出到屏幕上也是回车。
1 | cout<<R"(1"\n")"<<endl; |
如果想在原始字符串中包含”(、)”,可以通过在”和(之间添加其他字符修改标识符。
1 | cout << R"1("()")1" << endl; |
结构类型
1 | struct abc |
C++中定义结构可以省略struct,初始化时,等号可省略,使用空的大括号时,表示将所有元素初始化为0。
两个相同的结构之间可以互相赋值。
1 | struct abc |
定义结构时,可以同时声明变量并进行赋值。还可以省略结构名称。
结构数组
1 | abc x4[2] = {{'d', 2, "CC"}, {'e', 4, "DD"}}; |
结构中的位字段
1 | struct def |
共用体(节省空间)
1 | union a |
共用体的长度为其最大成员长度。
匿名共用体
1 | struct unitest |
a1和a2位于相同的地址。
枚举
1 | enum spec |
设置枚举类型的值
1 | enum spec |
这样red为0,orange为1,green为101;
可以创建多个值相同的枚举变量。
取值范围
枚举变量可取的值不一定是枚举定义中的值,可根据上界和下界确定枚举变量的取值范围。上界确定方法为,120->128,最大为127。如果枚举变量中最小值为正数,则下界为0,否则,下界确定的方法和上界相同。
指针
分配空间
1 | int *p=new int; |
在C++中,值为0的指针成为空指针。
使用delete释放内存只会释放内存空间,不会删除指针本身,可以指向别的内存地址。
不要重复释放内存(除非指针是空指针,这种情况可以)。
静态联编(编译时分配内存) VS 动态联编(运行时分配内存)
分配数组
1 | int *p=new int [10]; |
用引号括起来的字符串传递的是字符串首字符的地址。
动态结构
1 | struct test |
内存管理
C++中有三种管理数据内存的方法,自动存储、静态存储和动态存储。
自动存储
在函数内部定义的常规变量使用自动存储空间,被称为自动变量,通常存储在栈中。
静态存储
静态存储是整个程序执行期间都存在的存储方式,有两种方式,一是定义在函数外部,另一种方式是使用关键词static。
动态存储
使用new和delete分配和释放内存空间。
vector 和 array
1 | vector<int> a(3); |
1 | array<int, 5> a1 = {1, 2, 3, 4, 5}; |
vector存储在堆中,array存储在栈中,两者均存在索引越界的问题,使用at方法可在索引前进行检查,但是会增加程序执行时间。
第五章
C++将赋值表达式的值定义为左侧成员的值。
递增/递减运算符
对于类而言,前缀版本效率比后缀版本高。
++p执行先将p指针++再取值,++\p表示先取值再++,*p++表示先取值,再对地址++。
逗号表达式
先计算第一个表达式,再计算第二个表达式。逗号表达式的值是第二部分的值。所有运算符中,逗号表达式的优先级是最低的。
关系运算符
关系运算符的优先级比算术运算符低。
类型别名
1 | typedef typeName aliasName; |
typedef不会创建新类型,只会为已有的类型创建一个新名称。
基于范围的for循环
1 | double price[5] = {1.0, 2.0, 3.0, 4.0}; |
如果检测到EOF,则将eofbit和failbit设置为1,因此可将cin.eof和cin.fail放在读取后。
第七章
当用于函数头和函数原型时,int * arr
和int arr[]
是相同的。
传递数组时,函数中使用的是原数组。
可以使用void test(const int a [],int n)
这样的方式禁止在函数内修改原数组的值。
1 | int age=50; |
上边的这段代码无法通过p指针修改age变量的值,但是可以通过age变量进行修改。另外,
1 | const int age=50; |
这种情况是不允许的。
1 | int age=50; |
这样声明的p指针只能指向age,但是age的值能通过p指针进行xiu’gai