C++复杂类型
1. 数组
赋值
- 只有初始化的时候可以使用大括号赋值
- 不能利用数组名直接将一个数组赋值给另一个数组
- 大括号初始化可以只给前几个变量初始化,后面默认初始化为0;所以int a[10] = {0};数组的每个元素都被赋值为0
- 自动生成元素个数 int a[]={0, 1, 2}; 默认生成数组大小为3
- 数组初始化为0 int a[5] = {};
- 可以省略赋值号利用大括号初始化 int a[5] {1, 2, 3, 4, 5};
STL提供了模板类vector来替代array
2. 字符串
字符串的最后一位是空字符’\0’
简便的开启一个字符串的方法:
strlen()需要使用头文件,不计入结尾的空字符
cin
cin
- 直接从缓冲区读取数据,遇到空格、tab、enter结束读入,不对缓冲区做处理,遇到的
'\n'
等字符仍然留在缓冲区中- cin会跳过开头的
'\n'
和空格,直到读取有用信息
#include <iostream>
int main(void) {
using namespace std;
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];
cout << "enter name: " << endl;
cin >> name;
cout << "enter dessert: " << endl;
cin >> dessert;
cout << "I have some delicious " << dessert << "for you " << name << en>
return 0;
}
getline
getline
- 读入一整行,遇到
'\n'
停止读入,并将'\n'
从缓冲区删除- 当从缓冲区读入的读取字符数量超出设置时,会设置失效位(faibit),并且关闭后面的输入,这个时候再用ch=cin.get()是读取不到留在输入队列中的字符的。可以用下面的命令来恢复输入:
cin.clear();
//因为clear()会重置失效位,打开输入。
这个时候ch=cin.get();就可以读取留在输入队列中的字符。- 读取结束会在字符串末尾加上’\0’
读取一整行
#include <iostream>
int main(void) {
using namespace std;
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];
cout << "enter name: " << endl;
cin.getline(name, ArSize);
cout << "enter dessert: " << endl;
cin.getline(dessert, ArSize);
cout << "I have some delicious " << dessert << "for you " << name << en>
return 0;
}
get
get
- 读入一整行,遇到
'\n'
停止读入,'\n'
保留在缓冲区(可以利用cin.get()读取单个字符来解决)- 当从缓冲区读入的读取字符数量超出设置时,不会报错,继续读入
- 读取结束会在字符串末尾加上’\0’
- get可以用于判断当前输入的状态:
1) 停止输入后再次get(),如果读取到换行,则说明读取结束
2) 如果读取到其他字符,则说明上次读取没读完,可能是数组被读满了
#include <iostream>
int main(void) {
using namespace std;
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];
cout << "enter name: " << endl;
cin.get(name, ArSize);
cout << "enter dessert: " << endl;
cin.get(dessert, ArSize);
cout << "I have some delicious " << dessert << "for you " << name << en>
return 0;
}
第一个数组读取了Alistair Dreeb把'\n'
保留在了缓冲区,第二次数组直接读取到'\n'
直接结束读取,相当于读取到了空字符
使用cin.get()
把'\n'
从缓冲区读取掉
cout << "enter name: " << endl;
cin.get(name, ArSize);
cin.get();
cout << "enter dessert: " << endl;
cin.get(dessert, ArSize);
cout << "enter name: " << endl;
cin.get(name, ArSize).get(); // 返回值是一个对象,可以对对象继续使用方法
cout << "enter dessert: " << endl;
cin.get(dessert, ArSize);
数字、字符串混合读入导致的错误
#include <iostream>
int main(void) {
using namespace std;
int year;
cout << "What year was your house built?" << endl;
cin >> year;
cout << "What is its street address?" << endl;
char address[80];
cin.getline(address, 80);
cout << "Year built: " << year << endl;
cout << "Address: " << address << endl;
return 0;
}
由于cin读取完1966后,将换行符留在了缓冲区中,导致下一个字符串读入直接遇到换行符,读取结果为空字符
解决方法1
cout << "What year was your house built?" << endl;
cin >> year;
cin.get();
cout << "What is its street address?" << endl;
char address[80];
cin.getline(address, 80);
解决方法2
cout << "What year was your house built?" << endl;
(cin >> year;).get();
cout << "What is its street address?" << endl;
char address[80];
cin.getline(address, 80);
3. string类
数组不能直接赋值,但是string类可以
可直接使用 + 拼接两个字符串
A += B 将B加在A末尾
用C语言实现字符串拼接
测试1
#include <iostream>
#include <string>
#include <cstring>
int main(void) {
using namespace std;
char charr[20];
string str;
cout << "Length of charr is " << strlen(charr) << endl;
cout << "Length of str is " << str.size() << endl;
return 0;
}
发现charr的长度并不是初始化的20,而是6,这是由于,未初始化charr[20]的内存空间,地址下还存放着之前的数据,恰好在第七个字符的位置是'\0'
,所以读出的长度是6,还可能读出大于20的数
而string类读出的结果就是正确的
使用string类读入一行
int main(void) {
using namespace std;
char charr[20];
string str;
cout << "Length of charr before input: " << strlen(charr) << endl;
cout << "Length of str before input: " << str.size() << endl;
cout << "Enter line of charr: " << endl;
cin.getline(charr, 20);
cout << "charr is " << charr << endl;
cout << "Enter line of str: " << endl;
getline(cin, str);
cout << "str is " << str << endl;
return 0;
}
4. 结构体
结构体的定义和初始化(赋值)
GNU nano 4.8 9.cpp
struct inflatable{
char name[20];
float volume;
double price;
};
int main(void) {
using namespace std;
inflatable guest = {
"Glorious",
1.88,
2.88
};
cout << guest.name << endl << guest.volume << endl;
return 0;
}
结构体中可以定义对象
相同结构体之间可以直接赋值
可以在定义时直接创建变量
结构体数组赋值
结构体中的位字段
可以指定每个变量占用的位数,一般用于底层
共用体(联合体)
联合体更多用在嵌入式等底层,节省空间
常用来操作系统数据结构或硬件数据结构(例如可以查看机器是大端还是小端)
某一时段只能用某一种数据类型
占据的空间为最大成员占据的空间
结构体中定义共用体(联合体)
调用该结构体中的共用体
结构体中使用匿名共用体(联合体)
调用更方便