C语言基础篇 —— 4.3 结构体详解
admin
2024-01-25 03:04:18
0

文章目录

    • 结构体发展史
    • 结构体属于自定义类型还是原生类型?
    • 结构体变量中的元素如何访问?
    • 结构体的对齐访问
    • 结构体对齐访问扩展


结构体发展史

1、结构体可以认为是数组发展而来的。数组和结构体是最简单的数据结构。
2、数组特点(缺陷):
(1)定义时必须明确给出大小,且这个大小在后面不能再更改
(2)数组要求所有元素的类型必须一致
更复杂的数据结构就是为了解决数组的这两个缺陷。
3、结构体是用来解决数组的第二个缺陷,结构体中元素类型可以不相同。结构体完全可以取代数组,只是在数组可用的范围内数组比结构体更简单。


结构体属于自定义类型还是原生类型?

C语言中有2中类型:原生类型和自定义类型。结构体就是其中一种自定义类型。
1、结构体定义时需要先定义结构体类型,然后再用类型来定义变量。
2、在定义结构体类型的同时定义结构体变量。

// 定义结构体类型
struct student
{char name[20];int age;  
};// 在函数中使用结构体类型定义变量
struct student p2;// 定义类型的同时定义变量
struct people
{char name[20];int age;  
}p1;// 在函数中直接使用变量
p1.age = 23;// 将类型struct people结构体重命名为p1,这里的p1就不是变量了
typedef struct people
{char name[20];int age;  
}p1;

结构体变量中的元素如何访问?

1、数组中元素的访问方式:表面上有2中方式(数组下标方式和指针方式),访问的实质都是通过指针访问的
2、结构体变量中的元素访问方式只有一种,用 ‘.’ 或者 ’->‘ 的方式访问。这两种方式访问实质是一样的(都是用指针访问的),只是C语言规定用结构体变量来访问用 ‘.’ 用结构体变量的指针来访问元素用 ’->‘ (高级语言中已经不区分都用.)

// 结构体定义
struct test
{int a;        // 4double b;     // 8char c;
};// 结构体访问
struct test s1;
s1.a = 12;         // int *p = (int *)&s1; *p = 12;
s1.b = 3.4;        // double *p = (double *)((int)&s + 4 );  *p = 3.4;
s1.c = 'a';        // char *p = (char *)((int)&s + 12 ); *p ='a';

结构体的对齐访问

带着问题了解下结构体对齐访问与非对齐访问:
1、结构体为什么要对齐访问?
      答: 结构体元素对齐访问主要原因是为了配合硬件,也就是说硬件本身有物理上的限制,如果对齐排布和访问会提高效率
             内存本身是一个物理器件(DDR内存芯片,SOC上DDR控制器),本身有一定的局限性:如果内存每次访问时按照4字节对齐访问,效率是最高的。
2、结构体对齐访问与非对齐访问哪个好?
      答: 结构体对齐访问与非对齐访问需要看程序员注重的是内存空间还是速度性能。本质上两者并无好坏之分。
              对齐访问:牺牲了内存空间,换取速度性能
             非对齐访问:牺牲了访问速度性能,换取了内存空间的完全利用。
3、结构体在内存中究竟是怎样一个访问过程
      答: 结构体中元素的访问本质上还是指针方式,结合这个元素在结构体的偏移量和这个元素的类型来进行访问。
4、应如何考虑结构体对齐问题?
      答: 结构体要考虑元素的对齐访问,每个元素实际占用的字节数和自己本身的类型所占的字节数不一定完全一样。
5、在访问结构体成员时,需要考虑元素对齐问题吗?
       答: 用’.'方式来访问结构体中元素时,我们是不用考虑结构体的元素对齐。因为编译器会将这些元素对齐并知道每个元素在对齐后占多少字节。

分析结构体对齐关键:
1、结构体整体本身必须放在4字节对齐处,结构体对齐后的大小必须是4的倍数(编译器设置为4字节对齐时)。
2、结构体中每个元素本身都必须对其存放,而每个元素本身都有自己的对齐规则。

// 分析:
// 1、整个结构体变量4字节对齐是由编译器保证的
// 2、第一元素a,a的开始地址就是整个结构体的开始地址,所以自然是4字节对齐的,但是a的结束地址要由下一元素决定。
// 3、第二元素b,因为上个元素a本身占4字节,本身就是对齐的。所以留给b的开始地址是4字节地址,所以直接放。(b放的位置决定a一共占4字节,不需要填充)
//    b的开始地址确定,结束地址要根据下一个元素来决定
// 4、第三元素c,short类型需要2字节对齐(short类型元素必须放在类似0/2/4/6.....这样的地址处),因此不能紧挨着b放,需要在b之后添加1字节的填充,然后再开始放c
// 5、整个结构体的所有元素都对齐存放后,整个结构体大小还要是4的倍数
struct s
{int a;char b;short c;  
};

结构体对齐访问扩展

gcc支持但不推荐的对齐指令:
      #pragma pack()
       #pragma pack(n) (n = 1/2/3/4)

1、#pragma是用来指挥编译器,或者说设置编译器的对齐方式的。编译器默认对齐方式是4。现在不希望编译器对齐方式的4字节对齐,希望是1字节对齐。
这时gcc提供两种对齐命令:#pragma pack(),这种就是设置成1字节对齐;#pragma pack(1),这个括号中的数字是希望多少字节对齐

2、以 #pragma pack(n) 开头,#pragma pack() 结尾,这区间内自定义字节对齐生效。
#pragma pack的方式在很多C环境下都是支持的,gcc也可以用但是不推荐。

gcc推荐的对齐命令:
       __ attribute__((packed));
       __ attribute__((aligned(n)));
1、__ attribute__((packed)); 使用时直接放在要进行内存对齐的类型定义后面,起作用的范围只有加了这个东西的这一个类型。packed的作用就是取消对齐访问。
2、__ attribute__((aligned(n))); 使用时直接放在要进行内存对齐的类型定义后面,起作用的范围只有加了这个东西的这一个类型。作用是让整个结构体变量整体进行n字节对齐。(作用针对的是整体的结构体起效果,对结构体内元素不起效果)

相关内容

热门资讯

女朋友快生日了我不在她身边想说... 女朋友快生日了我不在她身边想说几句浪漫点得祝福语,请各位帮忙...亲爱的,距离永远阻挡不了我对你爱,...
我18岁了,想献血,请问献血有... 我18岁了,想献血,请问献血有什么规定?无传染性疾病
即便心再痛,也愿意因为爱而停下... 即便心再痛,也愿意因为爱而停下来等待前任回头的星座有哪些?摩羯座,金牛座还有白羊座就这个星座他是非常...
第一个字是从的成语大全,从字开... 第一个字是从的成语大全,从字开头的四字词语 第一个字是从的成语大全 从容应对、 从容自若、 从天...
谁能给我紫藤萝瀑布课后练习第1... 谁能给我紫藤萝瀑布课后练习第1题的答案!自己写。原先,焦虑和悲痛“一直压在我心上”,在繁花盛开的藤萝...
冷笑话的定义是什么? 冷笑话的定义是什么?怎么样的话才算冷笑话?不好笑的笑话吧.定义1:就是讲的人挺平静的,基本上面无表情...
感觉自己失去了目标,现在不知道... 感觉自己失去了目标,现在不知道该怎么生存下去了。人生中没有一帆风顺,现成的路可走,总会遇到一些困难,...
我都24了,还没有男朋友,我真... 我都24了,还没有男朋友,我真的很慌。怎么办?身边也没有男生说喜欢我你愿意网恋吗缘分 不要宅在家里那...
我有一个朋友,我们总是出去玩,... 我有一个朋友,我们总是出去玩,喝酒。但是他每次出来都要炫耀他赚了多少钱,我觉得他很爱炫,我就不想和炫...
林永健拍过什么电视剧 林永健拍过什么电视剧金婚喜耕田的故事城里城外马文的战争
斑马s6有必要学吗 斑马s6有必要学吗有。1、激发兴趣:通过有趣的故事、游戏和其他互动活动,斑马儿童英语S6可以激发孩子...
甜蜜乐章 撮合不了子奇和慕容啊... 甜蜜乐章 撮合不了子奇和慕容啊~~~~!必须是金曲奖的最佳演唱人,不然触发不了
暮光之城3 暮光之城3现在没有出呢!有也是骗人的!起码要国内上映之后吧!我和你一样期待呢!
学生会查寝收走了东西,要用什么... 学生会查寝收走了东西,要用什么法律武器把收走的东西要回来?和学校讲法律,劝你还是别这么冲动了。拿到明...
信任无价主要讲了一个什么故事 信任无价主要讲了一个什么故事主要讲了:一位女老师通过绝食的办法,让那位偷了快译通的学生自己主动交出。
什么叫奴隶社会 什么叫奴隶社会 奴隶社会:从公元前21世纪夏朝建立开始,到公元前221年秦王嬴政统一中国结束。[1...
中级经济师人力资源专业怎么才能... 中级经济师人力资源专业怎么才能考过啊?只是看指定的那两本书《经济基础》和《人力资源管理》,然后再把上...
为什么海里都是水啊 为什么海里都是水啊海里没水 海就不叫海了不难怎么叫海水 嘿嘿。海里没水 海就不叫海了
14岁两个女生,一米深的河里手... 14岁两个女生,一米深的河里手绑手溺亡,疑点重重,怎么回事?这个是因为她们忍受不了家里面的重男轻女,...
帮解几道五年级数学题!急急急~... 帮解几道五年级数学题!急急急~快快快!(要解)52=2*2*13