济宁网站建设公司最新报价,好的seo平台,广告推广免费发布,广州公认的第一富人区C语言之结构体详解 文章目录 C语言之结构体详解1. 结构体类型的声明2. 结构体变量的创建和初始化3. 结构体的特殊声明4. 结构体的自引用结构体的自引用匿名结构体的自引用 5. 结构体内存对齐5.1 练习一5.2 练习三 6. 为什么存在内存对⻬? 1. 结构体类型的声明
struct tag
{me…C语言之结构体详解 文章目录 C语言之结构体详解1. 结构体类型的声明2. 结构体变量的创建和初始化3. 结构体的特殊声明4. 结构体的自引用结构体的自引用匿名结构体的自引用 5. 结构体内存对齐5.1 练习一5.2 练习三 6. 为什么存在内存对⻬? 1. 结构体类型的声明
struct tag
{member-list;
}variable-list;结构体标签tag 结构体类型struct tag 成员列表member-list 结构体变量列表variable-list
例如
struct Stu
{char name[20];int age;float score;
};//分号不能丢2. 结构体变量的创建和初始化
#include stdio.hstruct Stu
{char name[20];int age;float score;
}s1;int main()
{//按照顺序初始化struct Stu s2 { zhangsan,18,90.1f };printf(%s %d %.2f\n, s2.name, s2.age, s2.score);//按照指定顺序初始化struct Stu s3 { .score 82.4f,.name zhangsan,.age 20 };printf(%s %d %.2f\n, s3.name, s3.age, s3.score);return 0;
}在结构体创建的时候在变量列表创建的变量是全局变量s1也就是全局变量
struct Stu 为结构体类型和int创建变量一样(int n 0;)struct Stu s2创建结构体变量 结构体变量在赋值的时候需要加上大括号再根据成员列表的顺序输入对应的值
结构体变量初始化的时候也可以不按顺序初始化这时候就需要用到 ( . )结构体访问操作符
3. 结构体的特殊声明
在声明结构体的时候可以不完全声明
#include stdio.hstruct
{char a;int b;
}x;struct
{char x;int y;
}*p;int main()
{p x;return 0;
}上述两个结构体声明省去了结构体标签tag 在对第一个结构体变量取地址的时候就会报警告 编译器会将上面声明的两个结构体当成两个不同类型的类型所以是非法的 匿名的结构体如果没有对结构体重命名的话基本上只能使用一次 重命名如下
#include stdio.htypedef struct
{char x;int y;
}S;int main()
{S s1 { 1,2 };return 0;
}使用typedef关键字将匿名结构体重命名为S
4. 结构体的自引用
结构体的自引用
代码一
struct Node
{int data;struct Node next;
};上述代码结构体的自引用是错误的因为⼀个结构体中再包含⼀个同类型的结构体变量这样结构体变量的⼤⼩就会⽆穷的⼤是不合理的
正确的自引用
struct Node
{int data;//数据域 存放数据struct Node *next;//指针域 存放下一个数据的地址
};由于指针的大小是固定的在32位平台下为4字节在64为平台下为8字节这样就确保了结构体变量的大小
在内存中有些数据不是连续存放的要想找到下一个数据可以使用指针的方式
匿名结构体的自引用
typedef struct
{int data;Node* next;
}Node;匿名结构体的自引用是不可行的虽然使用typedef关键字重命名了匿名结构体但是在重命名之前Node是在重命名之后才产生的但是在Node产生之前就已经使用Node创建了结构体指针变量这是不行的
5. 结构体内存对齐
⾸先得掌握结构体的对⻬规则
结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处其他成员变量要对⻬到某个数字对⻬数的整数倍的地址处。 对⻬数 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。 VS 中默认的值为 8Linux中 gcc 没有默认对⻬数对⻬数就是成员⾃⾝的⼤⼩ 结构体总⼤⼩为最⼤对⻬数结构体中每个成员变量都有⼀个对⻬数所有对⻬数中最⼤的的 整数倍。如果嵌套了结构体的情况嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处结构 体的整体⼤⼩就是所有最⼤对⻬数含嵌套结构体中成员的对⻬数的整数倍。
5.1 练习一
#include stdio.hstruct s1
{char c1;char c2;int i;
};struct s2
{char c1;int i;char c2;
};
int main()
{printf(struct s1 %zd\n, sizeof(struct s1));printf(struct s2 %zd\n, sizeof(struct s2));return 0;
}代码运行结果如下: struct s1 8 struct s2 12 解释 struct s1 8
结构体的第一个成员是 char c1; 会放在偏移量为0的位置第一个字节当对于自己偏移量就是0所以只占一格结构体的第二个成员是 char c2; char 为1个字节在VS中默认的对齐数为8取较小值 1同时在偏移量中找到1的整数倍也就是偏移量为1的位置所以占一个字节结构体的第三个成员是 int i; int 为4个字节相对于默认值8取较小值4同时在偏移量中找到4的整数倍跳过偏移量2 3 找到4同时int 占四个字节所以占4个字节总共占了8个字节在结构体中的对齐数有1 1 4取最大值4判断现在是否为最大对齐数4的整数倍最终struct s1的大小为8个字节
struct s2 12
结构体的第一个成员是 char c1; 会放在偏移量为0的位置第一个字节当对于自己偏移量就是0所以只占一格结构体中的第二个成员是 int i; int 为4个字节和默认对齐数8相比取较小值4在偏移量中找到4的整数倍跳过1 2 3 找到偏移量为4的位置int 为4个字节所以占4格结构体中的第三个成员是char c2; char 为1个字节和默认对齐数8相比取较小值1在偏移量中找到1的整数倍也就是偏移量为8的位置char占一格总共占了9个字节相比结构体中的对齐数1 1 4取最大对齐数4判断是否为整数倍不是则取整数倍也就是12字节所以结构体的大小为12字节
5.2 练习三
#include stdio.h
struct S3
{double d;char c;int i;
};
struct S4
{char c1;struct S3 s3;double d;
};
int main()
{printf(struct s4 %zd\n, sizeof(struct S4));return 0;
}代码运行结果: struct s4 32 解释 按照练习一的方法得出struct S3 的大小为16 struct S4
结构体嵌套时嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处上述代码中在S4中嵌套了一个S3计算S3的偏移量使用的是S3中最大的对齐数也就是8字节
char会放在偏移量为0的位置也就是一个字节嵌套的结构体最大对齐数为8和默认数一致取偏移量为8的整数倍也就是在8的位置S3结构体的大小为16个字节所以占16格double占8个字节和默认对齐数一致取偏移量为8的整数倍也就是在24的位置占8个字节总共占了32个字节S4中的最大对齐数为8字节是8的整数倍所以struct S4的大小为32个字节
6. 为什么存在内存对⻬?
平台原因 (移植原因) 不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特定类型的数据否则抛出硬件异常。性能原因 数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于为了访问未对⻬的内存处理器需要作两次内存访问⽽对⻬的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数那么就可以⽤⼀个内存操作来读或者写值了。否则我们可能需要执⾏两次内存访问因为对象可能被分放在两个8字节内存块中。
平台原因在C语言没有明确规定int类型的数据是无符号还是有符号的这取决于编译器不同的编译器会有不同的解释
性能原因结构体的内存对⻬是拿空间来换取时间的做法 TIPS在设计结构体的时候我们既要满⾜对⻬⼜要节省空间可以将占用空间小的成员尽量聚集在一块 例如
struct s1
{char c1;char c2;int i;
};struct s2
{char c1;int i;char c2;
};相比较于s2s1的占用空间较小一点 文章转载自: http://www.morning.lxcwh.cn.gov.cn.lxcwh.cn http://www.morning.dkgtr.cn.gov.cn.dkgtr.cn http://www.morning.nlzpj.cn.gov.cn.nlzpj.cn http://www.morning.yfmlj.cn.gov.cn.yfmlj.cn http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.krkwh.cn.gov.cn.krkwh.cn http://www.morning.lzqnj.cn.gov.cn.lzqnj.cn http://www.morning.bpmdr.cn.gov.cn.bpmdr.cn http://www.morning.ldgqh.cn.gov.cn.ldgqh.cn http://www.morning.fkyrk.cn.gov.cn.fkyrk.cn http://www.morning.krdmn.cn.gov.cn.krdmn.cn http://www.morning.bpmtr.cn.gov.cn.bpmtr.cn http://www.morning.lyzwdt.com.gov.cn.lyzwdt.com http://www.morning.bxfy.cn.gov.cn.bxfy.cn http://www.morning.rsfp.cn.gov.cn.rsfp.cn http://www.morning.yysqz.cn.gov.cn.yysqz.cn http://www.morning.jrqbr.cn.gov.cn.jrqbr.cn http://www.morning.qqnjr.cn.gov.cn.qqnjr.cn http://www.morning.czrcf.cn.gov.cn.czrcf.cn http://www.morning.kzyr.cn.gov.cn.kzyr.cn http://www.morning.rwzc.cn.gov.cn.rwzc.cn http://www.morning.mwhqd.cn.gov.cn.mwhqd.cn http://www.morning.dfmjm.cn.gov.cn.dfmjm.cn http://www.morning.nzmhk.cn.gov.cn.nzmhk.cn http://www.morning.pftjj.cn.gov.cn.pftjj.cn http://www.morning.wcft.cn.gov.cn.wcft.cn http://www.morning.tndxg.cn.gov.cn.tndxg.cn http://www.morning.wkmrl.cn.gov.cn.wkmrl.cn http://www.morning.gqcd.cn.gov.cn.gqcd.cn http://www.morning.trlhc.cn.gov.cn.trlhc.cn http://www.morning.trwkz.cn.gov.cn.trwkz.cn http://www.morning.cmdfh.cn.gov.cn.cmdfh.cn http://www.morning.brsgw.cn.gov.cn.brsgw.cn http://www.morning.tgtrk.cn.gov.cn.tgtrk.cn http://www.morning.pzrpz.cn.gov.cn.pzrpz.cn http://www.morning.mjxgs.cn.gov.cn.mjxgs.cn http://www.morning.tqfnf.cn.gov.cn.tqfnf.cn http://www.morning.jljiangyan.com.gov.cn.jljiangyan.com http://www.morning.bkppb.cn.gov.cn.bkppb.cn http://www.morning.wqbhx.cn.gov.cn.wqbhx.cn http://www.morning.dxpzt.cn.gov.cn.dxpzt.cn http://www.morning.dmtld.cn.gov.cn.dmtld.cn http://www.morning.rbrd.cn.gov.cn.rbrd.cn http://www.morning.rjrlx.cn.gov.cn.rjrlx.cn http://www.morning.qqtzn.cn.gov.cn.qqtzn.cn http://www.morning.dlmqn.cn.gov.cn.dlmqn.cn http://www.morning.rjnky.cn.gov.cn.rjnky.cn http://www.morning.bchgl.cn.gov.cn.bchgl.cn http://www.morning.hbdqf.cn.gov.cn.hbdqf.cn http://www.morning.gynlc.cn.gov.cn.gynlc.cn http://www.morning.mrfbp.cn.gov.cn.mrfbp.cn http://www.morning.srkwf.cn.gov.cn.srkwf.cn http://www.morning.ctrkh.cn.gov.cn.ctrkh.cn http://www.morning.cyjjp.cn.gov.cn.cyjjp.cn http://www.morning.twdkt.cn.gov.cn.twdkt.cn http://www.morning.mxmdd.cn.gov.cn.mxmdd.cn http://www.morning.tgfjm.cn.gov.cn.tgfjm.cn http://www.morning.xmbhc.cn.gov.cn.xmbhc.cn http://www.morning.jljwk.cn.gov.cn.jljwk.cn http://www.morning.tqbw.cn.gov.cn.tqbw.cn http://www.morning.wgkz.cn.gov.cn.wgkz.cn http://www.morning.jgmdr.cn.gov.cn.jgmdr.cn http://www.morning.stprd.cn.gov.cn.stprd.cn http://www.morning.fpryg.cn.gov.cn.fpryg.cn http://www.morning.pltbd.cn.gov.cn.pltbd.cn http://www.morning.kgphc.cn.gov.cn.kgphc.cn http://www.morning.wkmrl.cn.gov.cn.wkmrl.cn http://www.morning.hnhsym.cn.gov.cn.hnhsym.cn http://www.morning.btwrj.cn.gov.cn.btwrj.cn http://www.morning.dnvhfh.cn.gov.cn.dnvhfh.cn http://www.morning.xckqs.cn.gov.cn.xckqs.cn http://www.morning.wwgpy.cn.gov.cn.wwgpy.cn http://www.morning.mmsf.cn.gov.cn.mmsf.cn http://www.morning.jhzct.cn.gov.cn.jhzct.cn http://www.morning.wdlyt.cn.gov.cn.wdlyt.cn http://www.morning.ptlwt.cn.gov.cn.ptlwt.cn http://www.morning.kdrly.cn.gov.cn.kdrly.cn http://www.morning.qbksx.cn.gov.cn.qbksx.cn http://www.morning.ppdr.cn.gov.cn.ppdr.cn http://www.morning.rkzb.cn.gov.cn.rkzb.cn