C++PrimerPlus跟读记录【第四章】复合类型(上)基本类型

第4章 复合类型

目录

第4章 复合类型

1、数组

2、字符串

3、string 类

4、结构struct

5、共用体 union

6、枚举 enum


1、数组

typeName arrayName[arraySize];
  • 存储相同类型的值。每个值都存储在一个独立的元素中,在内存中依次存储
  • 声明,arraySize不能是变量,变量是在程序运行时设置的。其值必须在编译时已知
  • 编译器不会检查下标是否有效,运行会异常。
  • sizeof() 数组名,得到整个数组的字节数。

初始化

  • 只有定义数组时才能初始化,也不能将一个数组赋值给另一个数组。
  • 可以使用下标的方式对元素赋值。

  • 如果只对一部分元素初始化,则编译器会将其他元素置为0。
  • 只要显示地将第一个元素初始化为0,编译器会将其他元素都初始化为0。
  • 大括号不含任何元素,将默认置为0。
  • [] 为空,编译器会计算元素个数。
  • 初始化可省略 = 。
long plifs[] = { 25, 92, 3.0}; //错误,将浮点数转为整型时缩窄操作
char slifs[4] = { 'h', 'i', 1122011, '\0' }; // 错误,超出char表示范围
char slifs[4] = {'h', 'i', 112, '\0'}; //正确,虽然112是int值,但在char变量的取值范围内0~255
  • 列表初始化禁止缩窄转换。 

2、字符串

字符数组

char dog[8] = {'d', 'o', 'g', '', 'd', 'o', 'g', 'd'}; //不是字符串
char cat[8] = {'c', 'a', 't', 'c', 'a', 't', 'c', '\0'}; //是字符串
  • 字符串是存储在内存的连续字节中的一系列字符。
  • 可以存储在char数组中。以空字符(null character)结尾。
  • 空字符被写作 \0,其ASCII码为0(NULL),用来标记字符串结尾。

打印

  • cout 打印字符串,会逐个处理字符串中的字符,直到遇到空字符为止。
  • 如果定义的字符数组中间出现了 '\0' ,则后面的不打印。
  • 如果定义的字符数组没有定义 '\0',则会继续打印后续内存中各个字节解释为要打印的字符,直到遇到空字符。(好在空字符很常见)
int variSize = 10;
char name[variSize] = "123450678";  //  error: variable-sized object may not be initialized
cout << name;

const int size = 10;

char name[size] = "123450678";
cout << name << endl; // 123450678

char name2[size] = "123 45678";
cout << name2 <<endl;  // 123 45678

char name1[size] = "123\045678";
cout << name1 <<endl;  // 123%678

char arrName[size] = {'1', '2', '3', '4', '5', '\0', '6', '7', '\0'};
cout << arrName << endl; // 12345

字符串常量

char bird[11] = "Mr. Fan";
char fish[] = "Rice";
  • 初始化采用双引号表示,隐式地包括结尾的空字符,不用显式声明。
  • 应保证数组足够大,可以保存所有字符(包括结尾的空字符),因此需定义  [字符长度+1] 。
  • 在确定存储字符串所需最短数组时,需要计算结尾空字符。[] 为空让编译器自动计算更为安全。
  • C++对字符串长度没有限制。
  • 数组比字符串长没有害处,只会占用空间。

字符串常量 与 字符常量 区别

     

  

  • 字符串常量使用双引号,字符常量使用单引号,不能互换。
  • 字符常量'S',是字符串编码的简写,在ASCII系统上,只是83的另一种写法。
  • 字符串常量 "S",是 'S' + '\0' 组成的字符串。"S" 实际上表示的是字符串所在内存地址。

  • 拼接时,任何两个由“空格、制表符、换行符”分隔的字符串常量都将自动拼接成一个,中间没有空格。
  • 前一个字符串中的 '\0' 将被下一字符串的第一个字符取代。

sizeof 与 strlen 

  • sizeof 返回整个数组的长度:10字节。
  • strlen 返回实际长度,指存储在数组中的字符串的长度,只计算可见字符,且不包含结尾的空字符 '\0' 。
  • 注意:未初始化的字符数组包含的内容是随机的,即使定义了size,使用strlen()时,从第一个元素开始,遇到'\0'结束,返回的长度是随机的。
  • strlen 是库函数,包含在头文件<cstring>中。
const int size = 10;

// char name[size] = "0123456789"; // error: initializer-string for char array is too long

char name[size] = "123";
char name2[size] = "1 2";
char arrname[size] {'1', '2', '3'};
char arrname1[size] {'1', '2', '3', '\0'};
char arrname2[size] {'1', '2', '3', '\0', '4'};
char arrname3[size] {'1', '2', '3', ' ', '4'};

cout << sizeof(name) << endl; // 10
cout << sizeof(name2) << endl; // 10
cout << sizeof(arrname) << endl; // 10
cout << sizeof(arrname1) << endl; // 10
cout << sizeof(arrname2) << endl; // 10
cout << sizeof(arrname3) << endl; // 10

cout << strlen(name) << endl; // 3
cout << strlen(name2) << endl; // 3
cout << strlen(arrname) << endl; // 3
cout << strlen(arrname1) << endl; // 3
cout << strlen(arrname2) << endl; // 3
cout << strlen(arrname3) << endl; // 5

字符串输入

// 输入内容小于容器
const int Size = 10;
char name[Size];
cin >> name; // fan
cout << sizeof(name) << endl; //10
cout << strlen(name) << endl; //3

// 输入内容大于容器
const int Size = 10;
char name[Size];
cin >> name; // 123456789101112
cout << sizeof(name) << endl; //10
cout << strlen(name) << endl; //15
  • 将键盘输入读入到char数组中时,cin 将自动加上结尾的空字符。
    const int Size = 10;
    char name[Size];
    cin >> name; // 12345678 9
    cout << sizeof(name) << endl; //10
    cout << strlen(name) << endl; //8
  • cin :键盘无法输入空字符,cin将空白(空格、制表符、换行符)作为字符串结束位置,自动在空白处填入结束符放入数组,每次只能读取一个单词。 
  • 不会读取换行符,将其留在输入队列中

getline() 和 get()

  • 面向行的输入,通过回车键输入的换行符来决定输入结束。

  • cin.getline(para, size) :每次读取一行,读取到指定字符数或读取到换行符停止。将换行符读取到数组中,并用空字符替换。
  • cin.getline(para, size) 最多读取size-1个字符,自动在结尾添加空字符。

  • cin.get(para, size) :每次读取一行,不会读取换行符。
  • 如果连续调用cin.get();由于第一次调用会遗留换行符在队列中,导致第二个get读取的第一个参数就是换行符,不再get后续参数。
  • 不带参数的cin.get() : 可以读取下一个字符,即使是换行符。
  • 通过添加无参的读取换行符,为读取下一行做准备。

区别:

  • getline()简单,get()检查错误更细。通过使用get()读取,可以通过下一个字符是否为换行符判断,是换行符表示已读取了整行,不是换行符说明已读取到指定长度字符,还有其他输入。
  • 读取到空行时,get()会设置失效位。
  • 输入字符长度大于分配内存时,均会保留剩余字符在输入队列中,getline()会设置失效位。
  • 失效位需要通过 cin.clear(); 恢复输入

  • cin();  cin.getline(); cin.get()  返回对象,通过对象调用无参数的 cin.get(); 跳过换行符。
// 单独调用
int year;
cin >> year; // 会留下换行符
cin.get(); // 读取换行符
cin >> month; // 再进行读取

// 拼接对象调用
(cin >> year ).get();

3、string 类

  • string 类位于命名空间std中。
  • 程序可以自动调整string的大小。
  • char数组存储字符串的存储单元,string类变量时表示字符串的实体。
  • 未被初始化的string对象的长度被自动设置为0 。
  • 可以用string对象给string对象赋值。

初始化

拼接

// 字符串类直接+
str1 = str2 + str3;

输入

cin.getline(chrr, 20); // .getline是istream类的类方法
cin.getline(cin, str); // getline不是
void test_str(){
    string str1 = "string";
    char chr[10] = "string";
    cout << str1.size() << endl;
    cout << strlen(chr) << endl; //strlen只接受char数组
}

4、结构struct

  • 结构可以存储多种类型的数据。定义新类型后,便可以创建对应的变量。用关键字struct声明。注意结尾;
  • 用成员运算符(.)访问各个成员。
struct inflatable
{
    char name[20];
    float volume;
    double price;
};

inlatable hat;
hat.name = "rice";
  • 结构声明的位置很重要,外部声明可以被后面的任何函数使用。
  • C++不提倡使用外部变量,支持外部声明符号常量。

初始化

  • 结构初始化可以放在同一行中 inflatable duck { "Daphne", 0.12, 9.98};
  • 括号中无内容,各成员将被置为0 。不允许缩窄。
struct perks
{
    int key_number;
    char car[12];
} mr_smith, mr_jones;
inflatable gifts[100];
inflatable guests[2] = 
{
    {"rice", 0.1, 1.32},
    {"fan", 0.2, 2.32}
};

5、共用体 union

  • 存储不同数据类型,但只能同时存一种。

  • 共用体用处:当数据项使用两种或多种格式,但不会同时使用时,可节省空间。
  • 共用体长度为其最大成员的长度。
union one4all
{
    int int_val;
    long long_val;
    double double_val;
} one, two;

6、枚举 enum

  • enum 提供了另一种创建符号常量的方式,可以代替const。

  • 枚举值定义了赋值运算,没有算术运算,所以最常用来定义符号常量。

  • 显式声明可以创建多个值相同的枚举量。
  • 只有声明中指出的值是有效的,bs取值只有3个有效值。除非强制类型转换:bs = bigstep(4); 4 不是枚举值,但在取值范围内。
  • 枚举值的取值范围:上限:由于third=101,大于且最接近此值的2的幂次值为128,则上限范围为127。下限同理:若不小于0,下限为0,否则,例最小枚举量为-6,2的幂次8最接近,则取值范围的下限为-8。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值