深圳网站建设哪个公司好,试用虚拟主机不能创建网站,wordpress 国内主机,做seo必须有自己网站吗目录
引入结构体 结构的声明
创建和初始化 内部元素的使用#xff1b;
特殊声明#xff1a;
结构体在内存中的对齐
练习#xff1a; 引入结构体 C语言有各种数据类型#xff0c;我们已经对一些数据类型很熟悉#xff1a; 整型#xff08;int#xff09;- 存储整…目录
引入结构体 结构的声明
创建和初始化 内部元素的使用
特殊声明
结构体在内存中的对齐
练习 引入结构体 C语言有各种数据类型我们已经对一些数据类型很熟悉 整型int- 存储整数值包括有符号和无符号两种类型。 浮点型float、double、long double- 存储实数值包括单精度float、双精度double和长双精度long double三种类型。 字符型char- 存储单个字符包括有符号和无符号两种类型。 指针类型pointer- 存储内存地址可以指向其他数据类型。 但是仅仅有这些类型是无法描述一些对象的特征的比如一个人的多个信息一个家庭的多个成员等等那么这时候就要用到结构体类型来描述一个比较复杂的对象。 结构体类型就像其他简单数据类型intfloatdouble一样也是一种数据类型但是它比较复杂可以包含多个 简单的数据类型 这些被包含的数据类型可以是不同的类型。 总之结构体是为了描述复杂对象而引入的一种新的数据类型。 结构的声明 C语言中结构体struct是一种自定义的数据类型可以将不同的数据类型组合在一起形成一个 新的 数据类型。结构体的定义格式如下
struct 结构体名称
{数据类型1 成员变量1;数据类型2 成员变量2;...
} 创建的同类型结构体名称;有了结构体类型我们就可以描述复杂对象的特征。例如要描述一个家庭的成员的信息可以 创建结构体类型Person——包含变量字符串型name, 整型age, 双精度浮点型heignt 创建结构体类型Family——包含结构体类型Person, 字符串型location 代码如下
//声明Person结构体类型struct Person {char name[20];int age;double height;
};//声明Family结构体类型struct Family
{struct Person;char location[10];
}Family_of_my;
从上述代码可以得出 结构体名称 根据具体的实际意义来决定。 成员变量可以有多个每个成员变量的数据类型可以是任意数据类型包括简单数据类型和复杂数据类型。也就是说一个结构体内部可以再嵌套包含一个结构体类型。 总结结构体内部的数据类型多样可以是简单类型也可以是复杂类型。 创建和初始化 结构体的初始化可以按照不同方式进行 1.按照结构体内部元素顺序 2.按照指定顺序 #include stdio.h
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号};int main()
{//按照结构体成员的顺序初始化struct Stu s { 张三, 20, 男, 20230818001 };printf(name: %s\n, s.name);printf(age : %d\n, s.age);printf(sex : %s\n, s.sex);printf(id : %s\n, s.id);//按照指定的顺序初始化struct Stu s2 { .age 18, .name lisi, .id 20230818002, .sex ⼥printf(name: %s\n, s2.name);printf(age : %d\n, s2.age);printf(sex : %s\n, s2.sex);printf(id : %s\n, s2.id);return 0;} 总结 初始化可以按照正常顺序还可按照指定顺序。 内部元素的使用 要用到结构体操作符。
#include stdio.h
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号};int main()
{//按照结构体成员的顺序初始化struct Stu s { 张三, 20, 男, 20230818001 };printf(name: %s\n, s.name);printf(age : %d\n, s.age);printf(sex : %s\n, s.sex);printf(id : %s\n, s.id);//按照指定的顺序初始化struct Stu* s2 s;printf(name: %s\n, s2-name);printf(age : %d\n, s2-age);printf(sex : %s\n, s2-sex);printf(id : %s\n, s2-id);return 0;} 总结要使用结构体内部元素要用到结构体操作符 . 和 - 用例 结构体.成员名 结构体指针-成员名 特殊声明 在声明结构的时候可以不完全的声明。也就是可以省略结构体的标签。
例如
//匿名结构体类型
struct
{
int a;
char b;
float c;
}xstruct
{
int a;
char b;
float c;
}a[20], *p; 但是这两个匿名的类型完全一致的结构体是同一个结构体类型吗
也就是说
p x; 这段代码合法吗 经过测试编译器会把上面的两个声明当成完全不同的两个类型所以是⾮法的。 匿名的结构体类型如果没有对结构体类型重命名的话基本上只能使⽤⼀次。 结构体在内存中的对齐 现在我们已经对结构体有了一个基本的认识那么结构体的大小是如何计算的呢 我们先看一个实例
计算下列两个结构体的大小 //练习1
struct S1
{
char c1;
int i;
char c2;
};
printf(%d\n, sizeof(struct S1));//练习2
struct S2
{
char c1;
char c2;
int i;
};
printf(%d\n, sizeof(struct S2)); 我们可以先猜测 既然两个结构体内部的变量类型和数目完全一致那么我们有理由猜测两个结构体大小相同但是实际情况并不是这样 其实结构体在内存中的存储有一套自己的规则 首先引入一个概念 对齐数 对齐数编译器默认的⼀个对齐数 和 该成员变量长度的较小值 默认对齐数 VS 中默认的值为 8 Linux中gcc没有默认对⻬数对⻬数就是成员⾃⾝的⼤⼩ 结构体的基本对齐方法是 1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处 2.其他成员变量要对齐到对齐数的整数倍的地址处 结构体大小的计算 1.结构体总⼤⼩为最⼤对⻬数结构体中每个成员变量都有⼀个对⻬数所有对⻬数中最⼤的的整数倍。 2.如果嵌套了结构体的情况嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处结构体的整体⼤⼩就是所有最⼤对⻬数含嵌套结构体中成员的对⻬数的整数倍。 这样一来我们分析上两个问题 对于s1先放入char类型由于char类型是1个字节小于8VS默认值所以直接放在0地址处。 值得一提长度是1的char无论何时都不会浪费空间它会直接顶着上一个数据的存储空间放置。 int型大小4字节小于8VS默认值所以放在sizeofint的整数倍的地址处也就是4开始到7结束。 char 紧跟着int型 由于最大对齐数是4此时结构体的最小大小大于8要满足4的整数倍那么这个结构体的大小向上取 是12。 对于s2 放入两个char一个int后的结构体最小大小正好是8那么结构体总大小就是8。 练习
int main(int argc, char* argv[])
{struct tagTest1{short a;char d; long b; long c; };struct tagTest2{long b; short c;char d;long a; };struct tagTest3{short c;long b;char d; long a; };struct tagTest1 stT1;struct tagTest2 stT2;struct tagTest3 stT3;printf(%d %d %d, sizeof(stT1), sizeof(stT2), sizeof(stT3));return 0; 结果 完~
未经作者同意禁止转载