【31】C语言 | 自定义类型 | 结构体
创始人
2024-05-21 03:31:18
0

目录

结构体

1【结构体类型的声明】

2【结构体类型的声明】

3【结构体变量的定义和初始化】

4【结构体内存对齐】

5【结构体传参】

6【结构体实现位段的能力 】


1、结构体

  • 生活中对象是复杂的,比如书、书名、作者、出版社、定价、书号等。怎么描述这一类对象呢?于是就出现了结构体。
  • 结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量。

1【结构体类型的声明】

struct tag
{member-list;
}variable-list;

 【举例理解一下:】

//相当于自己创建了一个类型Book
struct Book    //struct 是结构体的关键字,Book是结构体的标签名
{char name[20];   // {}里面放的是描述这个对象的成员变量列表int price;char id[12];
}b3,b4,b5;           // b3,b4,b5这里创建的实体是全局的,而b1,b2在{}里面所以是局部的
int main()
{struct Book b1;  //拿自己创建的类型Book创建了个b1,b1就是一个实体struct Book b2;return 0;
}

【不完全声明】

//匿名结构体类型,只能用一次,用完就不能用了
struct 
{char c;int i;char ch;
}s;

2【结构体类型的声明】

结构体类型的声明:就是结构体包含结构体

【举例理解一下】 

struct A
{int ret;char w;
};struct B
{char t;struct A aa; //结构体B包含了结构体Adouble f;
}
int main()
{return 0;
}

【结构体的自引用】

struct Node
{int data;struct Node next;
};
//这种是错误的引用
//结构体不能引用同一结构体的成员变量,而是引用同一结构体的指针struct Node
{int data;struct Node* next;
};
//这种引用同一结构体的指针是正确的

3【结构体变量的定义和初始化】

【举例理解一下】

struct A
{int x;char y;
}p1;                 // 声明类型的同时定义变量p1struct B
{double b;struct A s;
};
int main()
{struct A p2;     // 定义结构体变量p2struct A P3 = {0,'c'};//初始化:定义变量的同时赋初值struct B p4 = {3.14,{0,'y'}};//. 是针对结构体变量的//->是针对结构体指针的printf("%lf %d %c\n",p4.b,p4.s.x,p4.s.y);return 0;
}

4【结构体内存对齐】

先看下面代码,结构体的大小是多少

struct  S
{char c1;int i;char c2;
};int main()
{struct S s = {0};printf("%d\n",sizeof(s));return 0;
}
//输出为12

输出为:12,为什么是12呢,然后引出结构体内存对齐

  • 1.第一个成员在与结构体变量偏移量为0的地址处。
  • 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处对齐数 = 编译器默认的一个对齐数 与该成员大小的较小值(VS中默认的值为8)。
  • 3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
  • 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数 )的整数倍。

下图:

  • 1 + 3(浪费) + 4 + 1 + 3(浪费)  = 12
  • 12刚好是最大对其数4的整数倍
  • 所以就是12

C1

i

C2

 为什么存在内存对齐?
大部分的参考资料都是如是说的:

  • 1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
  • 2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次访问。

总体来说
结构体的内存对齐是拿空间来换取时间的做法

【指定对齐值】 

  • #pragma pack (n),C 编译器将按照 n 个字节对齐。
  • #pragma pack (),取消自定义字节对齐方式。 
#pragma pack(2)
struct  S
{char c1;int i;char c2;
};
#pragma pack()
int main()
{struct S s = {0};printf("%d\n",sizeof(s));return 0;
}//输出为8

【offsetof宏】

#include
struct  S
{char c1;int i;char c2;
};int main()
{printf("%d\n",offsetof(struct S,c1));printf("%d\n",offsetof(struct S,i));printf("%d\n",offsetof(struct S,c2));return 0;
}//输出为://0//4//8//请按任意键继续. .

5【结构体传参】

下面的print1和print2函数哪个好些?

struct S
{int data[1000];int num;
};struct S s = {{1,2,3,4,},1000};//结构体传参
void print1(struct S s)
{printf("%d\n",s.num);
}//结构体地址传参
void print2(struct S* ps)
{printf("%d\n",ps->num);
}int main()
{print1(s);  //传结构体print2(&s); //传地址return 0;
}

答案是:首选print2函数。原因:

  • 函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。
  • 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。

结论:结构体传参的时候,要传结构体的地址。

6【结构体实现位段的能力 】

位段的内存分配

  • 1.位段的成员可以是int unsigned int signed int 或者是char (属于整形家族)类型。
  • 2.位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
  • 3.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

位段的跨平台问题

  • 1.int位段被当成有符号数还是无符号数是不确定的
  • 2.位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机
  • 器会出问题。
  • 3位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。 

跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。

相关内容

热门资讯

男子身上发痒一查竟是肝癌?身体... 近日,“男子身上发痒检查后确诊肝癌”的话题引发关注。据报道,40多岁的王先生(化名)觉得身体发痒,以...
国际领先,我国“自主可控智能发... IT之家 5 月 11 日消息,由国家能源投资集团有限责任公司牵头,中国华能集团有限公司、中国华电集...
“亲们”“家人们”怎么就成了网... 来源:光明日报 日常生活中,我们基本不用“亲们”“家人们”来呼喊他人。但在互联网环境下尤其是网络直播...
以爱为名:三位母亲与她们的星辰 中新网呼和浩特5月11日电 题:以爱为名:三位母亲与她们的星辰作者 尚虹波 康懿 云祥5月的风裹挟着...
动物园发悬赏公告找寻越狱卡皮巴... 扬州1只卡皮巴拉出逃40天未归5月11日,扬州茱萸湾风景区发布园区历史上首张悬赏公告!卡皮巴拉豆包于...
苹果宣布降价,涉及多款iPho... 苹果发布iPhone16系列之后已多次降价。 日前,苹果向渠道商下发了调价通知...
新鸿基香港西沙SIERRA S... 观点网讯:5月10日,新鸿基地产旗下香港新界西沙“SIERRA SEA”第1B期加推88伙单位,折实...
舍弃旧能源、拥抱新能源,“地产... 卧龙地产跨界转型步伐持续推进。5月10日,卧龙地产发布公告称,拟将持有的卧龙矿业(上海)有限公司(以...
四水八硼酸钠商品报价动态(20... 生意社05月11日讯 交易商品牌/产地交货地最新报价四水八硼酸钠 种类:工业级; 产品...
上海今日26℃+微风,初夏感拉... 上海今天天气晴好微风轻拂很是舒服今天的你是不是被母亲节温馨的礼物刷屏了在此祝各位妈妈们节日快乐早晨全...
华东政法大学丛立先:中国产业和...   2025世界IP经济发展大会暨全球IP授权博览会于5月10日-5月12日在广州举行。华东政法大学...
红星小学三年级语文组开展寓言故... 阳光讯(记者 杨小娟 文/图)2025年5月9日,西安市雁塔区红星小学三年级语文组成功举办"悦读筑梦...
“民告官”案件立得进立得准立得... 江西法院为减轻当事人诉累、避免“程序空转”,强化行政案件立案与审判的有效衔接——“民告官”案件立得进...
卡皮巴拉出逃40天动物园发悬赏... 【#卡皮巴拉出逃40天动物园发悬赏公告#】5月11日,扬州市茱萸湾风景区管理处发布悬赏公告:卡皮巴拉...
锲而不舍落实中央八项规定精神|... 据新华社重庆5月11日电 “我在镇上负责民政救助工作,要对接上级多个部门。以前要填报各种年报、月报、...
驾驭不可见菌株,造福人类 制造可自然降解的塑料,让盐碱地重新焕发生机,使农作物显著增产……能够帮助人类实现这些目标的,居然是肉...
约500款上海应用已上架,政企... 从鸿蒙手机到鸿蒙电脑,华为终端已全面迈入鸿蒙时代。但从实际意义来看,鸿蒙绝不是华为的独角戏,它实现了...
兄弟,你的手动“马赛克”有点“... 常看《国门说法》克服“侥幸心理”2025年了还有人把护照玩成 “整活道具”?给验讫章手动“打码”出境...
加拿大女子吐槽就医难痛到想死 【#加拿大女子吐槽就医难痛到想死# 】#越来越多加拿大人被迫出国寻医# 加拿大多伦多居民爱丽森·范登...
上海机电相关公司中标一项128... (转自:快查一企业中标了)快查APP显示,上海机电相关公司上海三菱电梯有限公司于2025年5月9日发...