阅读者你好!?如果您是编程高手,请误笑我的无知。 由于本人是一个编程界菜鸟,希望通过写博客的方式激励自己不断的学习
学无止尽,嘿嘿!?我会继续加油的!
复合类型
- 数组
- 字符串
- 结构体
- 共用体
- 枚举
- 指针
- 数组的代替品
数组
存储多个同类型数据
- 数组声明
- 每个元素的类型
- 数组名
- 数组元素个数
// 声明
int number[10];
// 初始化
number[0] = 100;
// 声明且初始化
int number[5] = {1, 2, 3, 4, 5};
// 访问数组元素,赋值
cout << number[0] << endl;
number[0] = 1000
// sizeof 查询数组变量中,共有多少字节
sizeof num
// sizeof num / sizeof(int) int数组长度
复制代码
字符串
存储在内存的连续字节中的一系列字符
-
C 风格
-
基于 string 类库
C 风格字符串
-
存储在内存的连续字节中的一系列字符
-
cstring 头文件,strlen("") 返回字符串长度
可以将字符串存储在char类型数组中,每个元素就是一个字符,注意:要以空字符结尾(“\0”)
char name[6] = {'h','e','l','l','o','\0'};
cout << name << endl;
输出:hello
复制代码
- 简单的声明初始化,不需要手动加 ‘\0’
char[6] = "hello"; //注意数组长度要加一,给‘\0’留位置
char[] = "hello";
复制代码
注意: "S" 表示:两个字符(‘s’和‘\0’),"S"返回的是字符串内存地址
拼接字符串字面量
“hello” “world” 任何在两个字符串中间(空白、制表符、换行符)都会自动的拼接起来,第一个字符串最后的‘\0’将被第二个字符串第一个字符取代
在数组中使用字符串
- 将数组初始化为字符串常量
char name1[] = "hello";
cout << name1 << endl;
复制代码
- 将键盘或文件输入读入到数组中
const int Msize = 15;
char name[Msize];
cout << "请输入名称:";
cin >> name;
cout << name << endl;
cout << strlen(name) << endl;
复制代码
每次读取一行字符串输入
cin 接收输入,并且以空行、制表符、换行表示结束,想读取一行,cin提供了,getline()、get(),‘\n’表示结束
- getline() 将丢弃‘\n’
// 通过回车键输入的换行符,表示结束
// cin.getline(name, size); // name:数组,size:长度
const int Msize = 20;
char name[Msize];
cout << "请输入姓名: ";
cin.getline(name, Msize);
cout << name << endl;
复制代码
- get() 保留'\n'
因为get()保留'\n',当第一次调用get()后,第二次调用,会读到第一个的‘\n’,所以第二次就直接结束了,现在可以通过get(),读取下一个字符,跳过第一次调用的'\n'
const int Msize = 20;
char name[Msize];
char age[Msize];
cout << "请输入姓名: ";
cin.get(name, Msize).get(); // 跳过'\n'
cout << "请输入年龄: ";
cin.get(age, Msize);
复制代码
- 空行问题
当调用get直接输入空行的话,会被设置失效位,接下来的输入会被阻断,解决:cin.clear()
string类 简介
-
string 头文件
-
std::string,在std空间下
-
string name = "hello world";
-
string name = {"hello"};
-
string name = {'h','a'};
-
.size() 返回长度
-
可以像数组一样通过下标访问 name[0]
-
可以cin输入内容到string对象
注意
-
不能将一个数组赋值给另一个数组,但是可以将string赋值给另一个string
-
C风格字符串,通过cstring头文件,提供的方法处理字符串,比如:strlen() 、 strcat() 、 strcpy(),现在string类操作很简单:如.size() 、 name1 = name2 、 name1 += "adadasd"
string name1;
string name2 = "world";
name1 += "hello ";
cout << name1 + name2 << endl;
cout << (name1 + name2).size() << endl;
复制代码
结构体(struct)
存储多种数据类型,是用户定义的类型
-
可以将结构体,作为参数传递给函数
-
函数可以将结构体,作为返回值
-
定义结构描述
struct person {
string name;
unsigned short age;
};
复制代码
- 创建结构变量
// 声明并初始化
struct person p1 = {
"hello",
99
}
复制代码
- 创建并声明变量
struct person {
string name;
unsigned short age;
} p1, p2;
复制代码
- 结构数组
person ps[10];
person ps = {
{"asd", 29},
{"asd", 20}
}
复制代码
- 结构中的位字段,用于硬件
struct test{
unsigned int SN : 4; // 分配4bit
unsigned int : 4; // 表示间隔
bool isopen : 1; // 分配1bit
} t1;
复制代码
共用体(union)
能过存储不同的数据类型,但是只能是其中的一种,如:
union id {
int a;
long b;
double c;
}mId;
mId.a = 10;
mId.c = 10.0; //这个时候a,b的值将丢失
复制代码
用途:
- 当数据项使用两种或多种格式,但不同时使用的时候,可以节省空间
匿名共用体
struct person{
union {
char[] id_str, // 将成为成员变量
int id_int // 将成为成员变量
}
}
// id_str,id_int在内存中地址一样
复制代码
枚举
-
enum color {red, blue, green}
-
enum color {red = 1, blue = 2}
-
enum color {red, blue = 100, green}
-
color c; 声明枚举变量
color c = blue;
cout << c << endl;
复制代码
指针与自由存储空间
指针是一个变量,存储的是值的地址,不是值本身,指针名表示的是地址
- & 地址运算符,可以获取变量的内存地址
int a = 100;
&a // 变量a返回内存地址 十六进制
复制代码
*
间接值 或者 解除引用 运算符,运用于指针
int a = 1000;
int *p = &a; // p 指针变量
cout << p << endl; // 输出地址
cout << *p << endl; // 输出值
复制代码
- 指针需要知道指向的数据类型
int a = 100;
int *p_a = &a; // 指向int 类型指针
double b = 100.0;
double *b = &b; // 指向double 类型指针
复制代码
注意
-
int* p1, p2; 声明了一个指向int的p1指针,声明了一个变量p2
-
一定要在对指针*解除引用运算之前,将指针初始化为一个确定的、合适的地址
指针真正的作用在于,在运行阶段,分配未命名的内存以存储值,在这种情况下,只能通过指针来访问内存
使用 new 来分配内存
new 运算符
-
new 数据类型; 来分配给类型的内存空间,并返回地址
-
最大的用处是,在运行时,觉得,要不要分配内存空间,用就分配,不用就不分配
-
通常,大型数据(数组、字符串、结构等),需要在运行是觉得是否用,用new来分配内存
int *p = new int;
*p = 1000; //赋值
// 动态创建数组
int *p = new int[10];
cout << p << endl;
*p = 10; // 相当于 p[0] = 10
*(p + 1) = 11; // 相当于 p[1] = 11
cout << *(p + 1) << endl;
delete[] p;
复制代码
new 一定要用 delete 去释放内存
使用delete释放内存
delete 会释放指针指向的内存,但是不会删除指针本身
delete 指针变量
复制代码
注意
-
不要使用delete释放,不是new出来的内存块
-
不要使用delete释放同一个内存两次
-
如果使用new xx []分配的内存,应该使用delete [] 指针名,来释放
-
对空指针应用delete是安全的
指针、数组、指针运算符
- 大多数情况下,C++将数组名解释为数组第一个元素的地址
int num[] = {1,2,3,4}
int *p = num; // p指向num数组的第一个元素地址
复制代码
- p[2] 等价与 *(p+2)
p1 = {
{1, 2, 3, 4, 5, 6, 7},
"hello",
29
};
person *p = &p1;
cout << p->age << endl; // -> 间接成员运算符,结构指针访问属性
复制代码
数组的替代 vector、array (模版类)
vector 效率低
动态数组,可以在最后追加,可以插入,本质上也是通过new delete动态分配内存的
-
头文件vector,在std命名空间中
-
std:vector<类型> vn(长度)
vector<int> vn(2);
vn[0] = 102;
vn[2] = 111;
vn[3] = 1231; // 自动扩容
cout << vn[0] << endl;
cout << vn[1] << endl;
cout << vn[2] << endl;
cout << vn[3] << endl;
复制代码
array (c++11)
-
头文件array,在std命名空间中
-
std::array<类型,长度>
array<int, 2> a = {1,2}
array[0]
array[1]
复制代码