Lazy loaded image
考研
C++ 学习笔记——二、复合类型
字数 3074阅读时长≈ 8 分钟
2026-10-15
2026-10-15

目录:点我

一、数组

数组采用大括号进行初始化,可以省略等号,但是禁止缩窄转换(例如浮点类型转整型、取值超限等)。

二、字符串

1. C 风格

  • C 风格字符串必须以 \0 结尾,如果采用双引号初始化则不用显式的指明空字符,程序会自动填补,因此要确定存储字符串所需的最短数组时,需要加上空字符。
  • 'S' 表示的是 ASCII 码值,而 "S" 表示该字符串的地址,前者可赋给 char 类型,后者不可。
  • cout 可以自动拼接多个字符串:cout << "a section" " b section" << endl; 。
  • cin 会在遇到空字符时停止并将其留在缓冲区(此时若调用 getline 则会导致错误),cin.get(name, size) 和 cin.getline(name, size) 会在遇到换行符时停止,前者不会丢弃换行符并将其留在缓冲区,后者则使用空字符替换。
  • strcpy(char1,char2):将char2复制给char1,要求char1的空间不能小于char2的空间。
  • strncpy(char1,char2,max_length):第三个参数为最大字符数,用于防止char1的内存较小时复制出错,也可理解为将char2中前max_length个字符复制到char1中。
  • strcat(char1,char2):把char2的内容扩展到char1中。
  • strlen(char1):获取char1的长度,不计空字符。

2. C++ 风格

  • cin 用于 string 时每次读取一行而不是一个单词,同时为防止越界可以采用 getline(cin, str); 。
  • w_char: L"example"、char_16: u"example"、char_32: U"example"、raw: R"(example)"、UTF-8: u8"example" ,其中 R"tmp()tmp" 表示定界符,tmp 表示自定义的定界符,不能是空格、括号、斜杠和控制字符,多种前缀可复合使用。

三、结构

1. 结构体

  • struct:允许设定变量表示位数,例如:

    2. 共用体

    • union:不同变量共享同一空间,因此需分时使用

      3. 枚举

      • enum:枚举类型,性质如下:
        • 枚举在取值范围内即有效,因此如果定义一个枚举:enum bits{one=1, two=2, four=4, eight=8}; ,那么语句 bits myflag = bits(6); 是合法的。考虑到内存物理结构,枚举类型的最大值通常是枚举定义中最大值小于最小的 2 的幂指数的值减一(符号占位),例如某个定义中有最大值 101 ,那么该枚举类型最大取值范围为 127 ,最小取值范围同理。

        四、指针

        对于一个数据,必须追踪其 3 种基本属性:数据存储地址、数据类型、数据的值。对于传统的程序,通常在编译阶段进行决策,即在编译阶段就确定所采用数组的内存大小;而 OOP 则在运行阶段进行决策,即在程序运行时根据需要分配内存大小。这样能够更好的节省空间,使程序更灵活。

        1. 声明指针

        • 声明格式:
          • 示例:

            2. 指针赋值

            • 将内存地址赋给指针,可以用取地址符&获取变量地址,用new运算符申请未命名内存地址,示例如下:

              3. 对指针解除引用

              • 解除引用即将地址变换为实际值,可以使用间接值运算符或数组表示法,示例如下:

                4. 区分指针和指针所指向的值

                • 如果pt是指向int的指针,则pt不是指向int的指针,而是等同于一个int型的变量,pt才是指针。

                5. 数组名

                • 大多数情况下C++将数组名视为数组的第一个元素的地址。
                • 但是sizeof运算符用于数组名时,将返回整个数组的长度;用于指针时,将返回指针的长度。单位均为字节。

                6. 指针算数

                • 指针可以与整数进行运算,其意义为指针对应地址值的带权整数偏移量,示例如下:

                  7. 数组的动态联编和静态联编

                  • 使用数组声明来创建数组时,将采用静态联编,即数组的长度在编译时的设置:
                    • 使用new[]运算符创建数组时,将采用动态联编,在运行时分配空间,使用完该数组后需使用delete[]释放内存:
                      • delete:销毁指针,只是销毁new为指针所分配的空间,并不销毁指针变量本身,特别注意 new 与 delete 要配对使用,否则会引发未知后果,对空指针使用delete是安全的。
                      • delete []:销毁new []创建的动态数组指针的空间。
                      • 如果只用 new 而不使用 delete ,则会发生内存泄漏,即已分配的内存再也无法使用,造成系统不断寻找更多内存而终止。

                      8. 数组表示法和指针表示法

                      • 使用方括号数组表示法等同于对指针解除引用:
                        • 区别在于,指针是变量,因此可以进行运算与赋值,而数组名是常量。若使用 sizeof 运算符,对于数组将得到数组的长度,对于指针将得到指针的长度。
                        • 共同点在于,指针和数组名使用括号访问元素时,都执行以下转换: cpp arrayname[i] becomes *(arrayname + i) pointername[i] becomes *(pointername + i)
                        • 对于一个数组 short tell[10]; ,tell 表示 tell[0] 的地址,&tell 表示整个数组的地址,从数字上来看二者相等,但从概念来讲有所区别。tell + 1 表示 tell[1] 的地址,而 &tell + 1 则表示 tell[10] 的后一个地址,也就是说两者的变量类型是不同的。tell 是 short 型指针,而 &tell 是 short[10] 型指针。若要定义一个指向 &tell 的指针变量,则使用语句 short (*pas)[10] = &tell ,括号表示这是一个指针,而不是指针数组,若省略括号,则 pas 先与 [20] 结合,导致 pas 是一个 short 指针数组,包含 10 个元素。另外,由于 pas 等价于 &tell ,因此 pas 等价于 tell ,所以 (*pas)[0] 为 tell 的第一个元素。

                        9. 指针用于结构

                        • 由于指针表示地址,地址中并没有成员的名称,因此不能使用.运算符直接访问结构中的成员。C++为指针提供了>运算符来帮助指针访问结构中的成员,或者对指针解除引用可以采用点来访问结构中的成员,但由于优先级的规则,必须采用括号,示例如下:

                          五、内存问题

                          1. 自动存储、静态存储和动态存储

                          • 自动存储:即在函数内部定义的常规变量使用自动存储空间,这意味着它们在所属的函数被调用时自动产生,在函数结束时消亡。简单来讲自动变量就是局部变量,通常存储在栈中。
                          • 静态存储:整个程序执行期间都存在的存储方式,有两种定义方式,一种是在函数外部定义它,另一种是在声明变量时使用关键字static 简单来说静态变量就是全局变量: cpp static double example = 1.0;
                          • 动态存储:即使用new、delete来管理内存,在运行阶段采用动态联编,程序员对其的控制权更大,不受编译器限制。

                          2. 内存泄漏

                          • 如果使用new运算符在自由存储空间(或堆)中创建变量后,没有调用delete,则很可能出现以下情况:包含指针的内存由于作用域规则和对象生命周期的原因被释放,在自由存储空间上动态分配的变量或结构也将继续存在。 这将因为指向这些内存的指针无效,进而导致无法访问自由存储空间中的结构。简单来说,就是记录指针信息的内存被释放了,但是指针原本指向(占用)的内存未被释放。 这部分内存在整个程序运行过程中将无法被发现、使用和释放,这就导致了内存泄漏。因此养成new与delete关键字配对使用的好习惯十分重要。

                          附录:C++转义序列的编码

                          字符名称
                          ASCII符号
                          C++代码
                          十进制ASCII码
                          十六进制ASCII码
                          换行符
                          NL(LF)
                          \n
                          10
                          0xA
                          水平制表符
                          HT
                          \t
                          9
                          0x9
                          垂直制表符
                          VT
                          \v
                          11
                          0xB
                          退格
                          BS
                          \b
                          8
                          0x8
                          回车
                          CR
                          \r
                          13
                          0xD
                          振铃
                          BEL
                          \a
                          7
                          0x7
                          反斜杠
                          |\|92
                          0x5C
                          ㅤ
                          ㅤ
                          问号
                          ?
                          \?
                          63
                          0x3F
                          单引号
                          ’
                          \’
                          39
                          0x27
                          双引号
                          "
                          \"
                          34
                          0x22
                          原创存证 · 本地哈希 · cf560f8adac9...
                          算法:SHA-256
                          时间:2026-10-15
                          哈希:cf560f8adac9f2b01c7fe955f30de7578a4fd2e1faf3cab5e7f09d9b3de677df

                          该信息用于辅助证明当前内容版本,不等同于法律公证或版权登记。


                          评论
                          Loading...