基础类型
类型 | 表示 | 样例 |
---|---|---|
整型 | int | 10 |
单精度 | float | 2.1f |
双精度 | double | 2.2 |
字符(也是整型) | char | ‘a’ |
… | … | … |
复合类型
数组
数组会被分配一大块空间,数组和指针操作很像,但是指针是可以相互赋值的,但是数组名却不可以(这导致数组不能作为函数的参数进行传递)!
int nums1[10];
int nums2[3] = {1,2,3}
int nums3[10] = {1,2,3}
int nums4[] = {1,2,3}
字符串(数组)
字符串其实本质上就是字符数组,但是其末尾必须是’\0’(当然,字符串中间包括’\0’也会使得字符串后面部分全部被忽略掉),计算字符串长度时’\0’也必须包括其中。
char str[4] = {'a', 'b', 'c', '\0'}
char str1[4] = "abc" // 包括'\0'
char str2[] = "abc"
注:如果按"abc"
双引号表示则默认结尾省略了"\0"
,在计算数组长度时"\0"
要计算在内!
cout << "I am very " "smart\n"; // 字符串拼接,将第二个字符串直接接在第一个后面,不会考虑'\0'
字符串通常需要被存储到数组中,常用方法——将数组初始化为字符串常量、将键盘或文件输入读入到数组。
#include<iostram>
int main(){
using namespace std;
const int Size = 15;
char name1[Size];
// 将字符串常量存储到数组
char name2[Size] = "TFBoys"
// 读取键盘输入
cin >> name1;
cout << "name1: " << name1 << endl;
cout << "name2: " << name2 << endl;
return 0
}
值得注意的是,cin使用空白来确定字符串的结束位置。也就是说,如果你想输入的字符串中间包括空白,那么cin只会将第一个空白的前面的字符串部分读入,其它的被保留在输入队列中,等待后续的被读取。
string类
包含再string头文件中,使用起来比数组简单。(类比python和java的string)(未被初始化的string自动被设置长度为0)
- 可以使用C-style字符串初始化string;
- 可以利用cin将键盘输入存储到string对象中;
- 可以使用cout显示string对象;
可以使用数组表示法来访问储存再string中的字符;
string str1 = "my name";
赋值、拼接和附加
一个数组不能赋值给另一个数组,但是string类型却可以:
string str1 = "hello!";
string str2 = str1;
string类型通过重载”+”,实现了拼接操作:
string str3 = str1 + str2
字符串其它操作
对于C-style的字符串,可以利用cstring里面的函数进行处理,例如:
strlen();
- strcat();
- strcpy();
- …
与之对应的string头文件里面的方法:
- str1.size();
- str1 += str2;
- str1 = str2;
-
string类IO
读取单词时:可以采用cin和cout类似字符数组的方式;
- 事实上cin来自于istream,并没有考虑string类。cin能够对string类处理的原因:处理string的代码使用string的一个友元函数。
读取一行时:getline(cin, str)方法实现;(string类会根据字符串长度自动调整自己的大小)
其他形式的字符串字面值
原始字符串:
cout << R("hello\n");
“R(“…”)”表示的是原始字符串,所以就会忽略转义操作。”\n”不代表换行符!
注意不能用”来做定界符了,因为在字符串内部可以包括”,容易产生误解;
-
结构体
目的:希望将不同类型的数据进行组合。
- 可以定义结构体数组;
- 结构体是OOP的基础;
结构体定义过程:
- 定义结构描述;
- 创建结构变量; ```cpp struct person{ char name[20]; char address[30]; int age; };
// 在C语言中定义结构体变量 struct person dhh; // 在C++中定义结构体变量 person zyr;
<a name="LXf9S"></a>
#### 结构体初始化
1、定义结构体变量时初始化
```cpp
person dhh = {
"daihonghui",
"ZJU",
23
};
2、之后修改结构体成员
dhh.name = "DaiFengHui"
其他结构属性
同时定义结构体和定义变量同时进行。
struct person{
char name[20];
char address[30];
int age;
}dhh;
struct teacher{
char name[20];
char address[30];
int age;
}dhh1={
"zyr",
"ZJU",
23
};
// 同时可以不用结构体名
// 不推荐
struct {
char name[20];
char address[30];
int age;
}dhh2={
"zyr",
"ZJU",
23
};
结构数组
person mates[2] = {
{"daihonghui", "ZJU", 23},
{"zyr", "ZJU", 22}
};
共用体
共用体(union)是一种数据格式,能够存储不同类型的数据类型,但是只能同时储存其中的一种类型。
union choice{
int int_val;
double double_val;
std::string string_val;
};
struct person{
std::string name;
int type; // 利用type控制到底是哪个类型的id有效
union id{
int id; // 两种类型的id都可以通过结构体访问
double d_id;
}id_val;
};
choice mychoice; // 有名共用体访问需要定义变量
person dhh;
cin >> dhh.id_val.id;
union中的多个变量每次只能一个有效(多个变量公用同一个空间),所以一个union的长度是其最大成员的长度。(但是经过测试发现,对intval赋值之后,仍旧能够访问double_val,应该是把int_val当成double_val对待了)。
目的:可以节省空间;
案例:商品的ID,有的是string类型,有的是整数类型,这时候可以将两种的ID利用union类型来表示。
特点:union里面的每个变量名都能被访问到,其中只有一个是真正有意义的。_
匿名共用体
有名共用体需要定义中间标识符(类似于定义union变量),但是对于无名的共用体,无需定义中间标识符,他们被当作普通的变量定义对待,能够同时访问到其内部定义的多个变量(公用空间)
struct person{
std::string name;
int type; // 利用type控制到底是哪个类型的id有效
union{
int id; // 两种类型的id都可以通过结构体访问
double d_id;
};
};
person dhh;
cin >> dhh.id; // 访问整型id
枚举
枚举是另一种创建符号常量的方式,可以替代const,并且它还定义了常量的所有可能取值。
enum Color {red, orange, yellow, green}; // red == 0, 之后的每个依次加一
Color my_color = red;
enum完成的两个事情:
- 定义enum类型:Color;
- 将red、orange、yellow等定义为常量0-n;
- 虽然red和0相等,但是Color类型的变量不能直接赋值0等(需要red等);
- 但是可以利用强制类型转换:(Color)0或者Color(0);
- red等能够参与整数等运算;
- 确定了enum类型Color的取值范围;
设置枚举量的值
enum bits {one=1, two=2, eight=8}; // 不再是从0开始
enum number {zero, null=0, one, number_one=1}; // zero和null都为0,
枚举量取值范围
不是枚举值,但是在枚举量范围内的赋值都是合法的(整数进行强制类型转换)
上限:找到最大值,然后找到大于这个最大值、最小的2的幂,将它减去1;比如:最大值卫115,那么最小2的幂为128,将去1之后卫127.
下限:找到最小值,如果比0大,则下限为0,如果比0小,则找到小于该值的最大2的幂,然后加1。比如最小值卫-6,那么最大2的幂卫-8,然后加1为-7.