书接上文
简单了解一下C++有哪一些复合类型
C++复合类型由数组,字符串,结构,共用体,枚举,指针组成,学习了复合类型之后,需要了解如何通过new和delete管理动态内存,这是C++的精髓之一。
数组
数组(Array)是一种数据格式,能够存储多个同类型的值;
数组声明和使用
C++数组跟大多数语言一样,都是从0开始的,而且定义的时候也是通过“[]”定义数组长度或者通过“{}”对数组进行初始化,使用sizeof(array)填入数组名称时,打印出的是数组中所占用的内存大小。 代码:
using namespace std;
#include <iostream>
#include <climits>
// 数组声明
int yams[100];
int main()
{
// 数组使用
yams[0] = 1;
yams[1] = 2;
cout << yams[0] << endl;
cout << yams[1] << endl;
// 数组声明
int arrays[]{3,4,5};
cout << arrays[0] << endl;
cout << arrays[1] << endl;
cout<<"数组总字节长度是: "<<sizeof(arrays)<<endl;
return 0;
}
输出结果:
每个int占用4个字节,所以sizeof输出的是3*int = 12字节。
C++数组初始化的一些规则
C++数组初始化时,例如 int array [4]={1},则默认array[0] = 1,其他则是初始化为0,初始化的数目是不能超过数组定义的长度的。 C++11数组初始化时,可以省略等号,例如:int array[4]{1,2,3,4}。 数组初始化时,禁止缩窄操作,例如:int array[4]{1,1.0,3.14}中3.14为浮点类型转换为整数是一种缩窄的操作。
字符串
字符串是存在在连续内存中的一系列字符,C++处理字符串的方式有两种,第一种是来自于C语言的,第二种是来自于C++标准库的string。
C语言的字符串
C语言的字符串有一个特殊的性质,就是字符串末尾是以空字符结尾"\0";这个特性对C语言的字符串来说至关重要,许多函数包括C++对字符串的处理(兼容C语言)都会处理达到空字符串为止。主要学习C++所以C类型字符串了解一下就行。
定义C语言的字符串
代码:
using namespace std;
#include <iostream>
int main()
{
char h[] = "hello world";
cout << h << endl;
cout << sizeof h << endl; // 输出12
}
有同学好奇,“hello world”一共加上空格也就11个字符,怎么会输出12个呢?原因是因为“\0”空字符也占用了一个字符。
C++语言的字符串
C++98标准通过添加string类扩展了C++标准库,通过面向对象的方式去使用string对象,隐藏了字符串实现的细节。
C++字符串定义和使用
C++字符串定义能够类似定义基础变量的形式进行定义,例如string str = "a",通过“+”号进行两个字符串的拼接。 代码:
using namespace std;
#include <iostream>
int main()
{
// 字符串定义
string s1 = "Hello";
string s2 = "World";
// 拼接字符串
string s3 = s1 + s2;
cout << s3 << endl;
cout << s3 + "a" << endl;
}
输出结果;
C++字符串的Api----后续去官网补充
结构体
结构是用户自定义的类型,结构体定义了这种类型之后,就能够通过结构体定义变量。
结构体的定义与使用
结构体定义后,可以直接通过变量定义的方式进行初始化,后续通过“.”访问成员属性。
using namespace std;
#include <iostream>
struct student
{
string name;
int age;
};
int main()
{
// 定义结构体
student st{
"小智",
18
};
// 使用结构体
cout << "我的名字是:" + st.name<<" 今年 " + std::to_string(st.age) + "岁" << endl;
}
输出结果:
结构体声明的位置
结构体声明的位置是比较重要的,在函数内声明只能在函数内使用,函数外声明可能所有函数都共用。
using namespace std;
#include <iostream>
// 函数外声明,任何人都可以使用
struct student
{
string name;
int age;
};
int main()
{
// 函数内声明,只有函数内可用
struct teacher
{
string name;
int age;
};
}
结构体的其他属性
C++的结构体与内置类型基本相似,可以作为函数的参数传递,也可以作为函数返回值进行返回,也可以通过“=”号对相同的类型的结构体进行赋值。
匿名结构体
匿名结构体是指声明一个没有名字的结构体,后续通过结构变量名进行访问,注意下面代码的“teacher”不是结构体名,而是变量名;这样声明的结构体,后续无法服用,不太建议用这种方法声明结构体。
using namespace std;
#include <iostream>
int main()
{
// 匿名结构体
struct
{
string name;
int age{};
}teacher;
teacher.name = "Teacher";
teacher.age = 18;
cout<<"Name: "<<teacher.name<<endl;
cout<<"Age: "<<teacher.age<<endl;
}
结构体数组
既然基础变量可以声明为数组,那结构体也是可以的,初始化方法与基础变量类似。
using namespace std;
#include <iostream>
// 函数外声明,任何人都可以使用
struct student
{
string name;
int age;
};
int main()
{
student stuArray[2]{
{
"小智", 18
},{
"小雅",17
}};
for(int i=0;i<2;i++)
{
cout<<"我的名字是: "+stuArray[i].name<<endl;
cout<<"今年: "<<to_string(stuArray[i].age)+"岁"<<endl;
}
}
代码输出:
结构体的位字段
C++允许指定占用特定位数的结构体成员,字段类型必须是枚举和整形,通过“:”指定使用的位数;如下代码所示,age为8位占用1字节,范围是-128-127,所以小智年龄是“正常”(127岁也不正常- -!)的,小雅的是溢出的。 代码:
using namespace std;
#include <iostream>
// 函数外声明,任何人都可以使用
struct student
{
string name;
int age:8;
};
int main()
{
student stuArray[2]{
{
// 正常
"小智", 127
},{
// 溢出
"小雅",128
}};
for(int i=0;i<2;i++)
{
cout<<"我的名字是: "+stuArray[i].name<<endl;
cout<<"今年: "<<to_string(stuArray[i].age)+"岁"<<endl;
}
}
输出结果:
共用体
共用体是一种数据格式,它能够存储不同的数据类型,但同时!同时!同时!只能存储1种。
共用体的定义和使用
共用体的定义方式和结构体类似,但定义的成员是共用一片内存的,当一个成员赋值时,会覆盖掉前一个成员的数值;下面代码是由两个int,一个double组成的,第一次给year赋值时,由于year和month都是int,共用内存所以输出的是同样的值,但是day就奇奇怪怪了;相反给day赋值,year和month看起来也是奇奇怪怪,不能工作;共用体通常用于节省内存,在嵌入式编程中比较常用,游戏服务器嘛...emmmm,当然自己能熟练使用也不错。 代码:
using namespace std;
#include <iostream>
// 函数外声明,任何人都可以使用
union date
{
int year;
int month;
double day;
};
int main()
{
date d1;
d1.year = 12;
cout <<"year: "<< d1.year << endl;
cout <<"month: "<< d1.month << endl;
cout <<"day: "<< d1.day << endl;
d1.month = 28;
cout <<"year: "<< d1.year << endl;
cout <<"month: "<< d1.month << endl;
cout <<"day: "<< d1.day << endl;
d1.day = 3.14;
cout <<"year: "<< d1.year << endl;
cout <<"month: "<< d1.month << endl;
cout <<"day: "<< d1.day << endl;
}
输出结果:
枚举
什么是枚举,有过编程经验的小伙伴自然是知道了,枚举就是一个可以有穷列举出来的常量咯,比如颜色{红,橙,黄}。
C++枚举定义和使用
C++定义枚举也跟结构体类似,只不过不需要填写类型,而是直接填写枚举参数名;正常情况下,枚举初始值从0开始,后续紧跟着初始值+1; 代码:
using namespace std;
#include <iostream>
enum color { red, green, blue };
int main()
{
color r = red;
color g = green;
color b = blue;
cout << r << endl;
cout << g << endl;
cout << b << endl;
}
代码输出:
枚举使用注意事项
枚举只是实现了“=”赋值运算符的重载,也就是说枚举之间不能使用+号进行赋值,但枚举会转换成int类型进行符号运算,运算后的值也是int类型;同理不能将int类型转换为枚举类型。
代码:
using namespace std;
#include <iostream>
enum color { red, green, blue };
int main()
{
color r = red;
color g = green;
color b = blue;
// color c = 1 + red; // 非法,编译报错
// color c1 = 1; // 非法报错
int a = red + green + blue; // 合法,输出3
cout<<a<<endl;
}
输出结果:
枚举设置值
枚举是可以设置值的,默认情况下从0开始递增,如果遇到设置的值,则从设置的值开始递增;例如{red, green = 1001, blue} red为0,green为1001,blue为1002;
using namespace std;
#include <iostream>
enum color { red, green= 1001, blue };
int main()
{
color r = red;
color g = green;
color b = blue;
cout << r << " " << g << " " << b << endl;
}
输出结果: