c++中的复合类型

c++中的复合类型(数组,字符串,结构体,共用体,枚举)

本文为本人阅读c++ primer plus第4章复合类型做的小笔记,只是记录本人不熟悉或者容易出错的地方

数组

  1. 声明数组:typeName arrayName[arraySize]

    • arraySize必须是整性常数或者const值,也可以是常量表达式,所有的值在编译的时候都是已知的,不可以是变量
  2. sizeof运算符返回类型或者数据对象的长度

    • 如果用于数组名如sizeof foobar,得到的是整个数组的字节数
    • 如果用于数组元素如sizeof foobar[0],得到的是数组元素的大小
    • 因此可以通过sizeof foobar / sizeof foobar[0]得到未知数组的长度
  3. 初始化原则:

    • 如果只对数组一部分初始化,那么编译器会将其它元素设置为0(如 float a[5] = {2.0, 5.0});因此对数组的所有元素都初始化为0十分简单,只需要显式将第一个元素初始化为0即可
  4. c++11的数组初始化方法

    • 初始化数组可以省略=:int a[2] {1, 2}
    • 大括号可以没有东西,表示这些元素全都设置为0: int a[5]{}

字符串

  1. c++处理字符串的方法

    • c风格
    • 基于string

c风格

  1. 以空字符结尾,写为\0,ASCII码为0,用来标记字符串的结尾。

    • 这是易错点之一:例如,如果想储存并打印一个长度为n的字符串,那么char数组至少为n+1,最后一位需要置为\0,否则打印过程中,会一直将内存中随后的各个字节解释为字符并打印,知道遇到\0为止
  2. 字符串常量: 会隐式地包括\0,当然这是在数组长度足够的情况下

    char foobar[6] = "test"; // 实际为{'t', 'e', 's', 't', '\0', '\0'}
    char foobar[] = "test";
    
  3. 不可以将字符串常量(双引号)和字符常量(单引号)互换,如char a = “s”, 因为”S”实际表示的是字符串所在的内存地址,相当于将一个内存地址赋给a

  4. 字符串长度: strlen(), 需引入头文件sctring,返回的是储存在数组中的字符串长度,不是数组本身长度,也不包括\0
c风格字符串输入
  1. 例子

    char name[30]; 
    cin >> name[30];
    
  2. cin判断已经完成字符串输入:空白(空格,制表符,换行符);因此上面的程序输如Zhang Yi时可能会出现问题
  3. iostream中的类如cin提供了面向行的输入的成员函数:getline()和get()
getline()
  1. 参数:getline(char[] str, int length),同理,如果length为n,那么函数最多读取19个字符,余下空间添加\0
  2. 每一次读取一行,通过换行符来确定行尾,但是不保存换行符(储存在字符串时将换行符换为\0)
  3. 运用例子:cin.getline
get()
  1. 同getline类似,接收的参数相同,解释参数方式也相同,也读到行尾,但是并不再读取并丢弃换行符,而是让它留在输入队列中,故若不借助任何帮助,get是不能跨过换行符的,因为只要换行符存在,用多少次get函数都认为没有任何内容读取,但换行符任在输入队列中

    cin.get(name, ArSize);
    cin.get(name, ArSize); // a problem
    
  2. 使用不带任何参数的cin.get()可以读取下一个字符(即使是换行符),故可以使用它来处理换行符

    cin.get(name, ArSize);
    cin.get();
    cin.get(name, ArSize);
    cin.get();
    
  3. 简化:由于cin.get()返回cin对象,故可以简化为

    cin.get(name, ArSize).get();
    cin.get(name, ArSize).get();
    
  4. 关于读取字符串还可能会有各种问题,将在书本后面专门讲述

混合输入字符串和数字
  1. 问题例子

    cin >> year;
    cin.getline(address, 80);
    
  2. 问题:用户根本没有输入地址的机会
  3. 原因:

    • cin读取年份,将回车键生成的换行符留在输入队列
    • cin.getline()看到换行符,认为是空行,将空字符串赋给address数组
  4. 解决:处理掉回车键产生的换行符

    cin >> year;
    cin.get();
    cin.getline(address, 80);
    

基于string

  1. 基本用法类似于c风格的char数组,变化不大
  2. 读取一行

    string str;
    getline(cin, str);
    
  3. 读取一行的函数getline不同于读取c风格的cin.getline

    • 没有使用句点表示法,说明getline()不是类方法
    • 将cin作为参数,指出到哪里查找输入
    • 没有指定str的长度,因为string对象根据字符串长度自动调整自己的大小

结构

  1. 声明

    struct person
    {
        char name[30];
        int age;
    }; // 别忘了分号表示声明结束
    
  2. 创建: person child;;
  3. 创建并初始化:

    person child = 
    {
        "Tom",
        2
    };
    
  4. 访问成员:句点。child.name

  5. c++11结构初始化

    • 等号省略
    • {}
    • 不允许缩窄类型

共用体

  1. union,可以储存不同的数据结构,但是只能同时储存一种类型,即结构可以同时储存int,long,double,共用体只能储存int或者long或者double;union和struct结构相似,含义不同

    union one4all
    {
        int int_val;
        double double_val;
        long long_val;
    };
    
  2. 例子

    one4all pail;
    pail.int_val = 15;
    cout << pail.int_val;
    pail.double_val = 1.23;
    cout << pail.double_val;
    cout << pail.int_val << endl; // a problem
    
  3. pail有时可以是int变量,有时可以为double变量,union的长度为其最大成员的长度

枚举

  1. 定义:enum color{red, green, yellow}

    • color变为新类型,称为枚举(enumeration)
    • red, green, yellow作为符号常量,依次对应数值0-2,称为枚举量
  2. 声明变量:color light;

  3. 赋值:在不进行强制类型转换的情况下,只可以将定义枚举时使用的枚举量赋给这种枚举的变量

    light = red; // ok
    light = 2000; // invalid
    
  4. 对于枚举,只定义了赋值运算符,没有定义算术运算
  5. 枚举量是整形,可以被提升为int类型,但是int类型不可以自动转换为枚举类型,但是可以强制转换(int 的值有效)

    int crayon = red; // valid, color type promoted to int
    light = 3; // invalid, int not converted to color
    light = 1 + red; // valid
    light = red + green; // invalid, no '+' operation for enumeration. Werid !!!
    light = color(2);
    
  6. 设置枚举量的值:enum { zero, null = 0, one = 1, numero_uno = 1},可以看出

    • 可以使用赋值运算符显式设置枚举量(必须为整数)
    • 可以选择只对部分枚举量进行显式赋值
    • 可以创建多个多个值相同的枚举量
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值