微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 漫谈c语言结构体

漫谈c语言结构体

时间:12-01 来源:互联网 点击:
相信大家对于结构体都不陌生。在此,分享出本人对C语言结构体的研究和学习的总结。如果你发现这个总结中有你以前所未掌握的,那本文也算是有点价值了。当然,水平有限,若发现不足之处恳请指出。代码文件test.c我放在下面。

在此,我会围绕以下2个问题来分析和应用C语言结构体:

1.C语言中的结构体有何作用

2.结构体成员变量内存对齐有何讲究(重点)

对于一些概念的说明,我就不把C语言教材上的定义搬上来。我们坐下来慢慢聊吧。

==============================================================================================================================================

1.结构体有何作用

三个月前,教研室里一个学长在华为南京研究院的面试中就遇到这个问题。当然,这只是面试中最基础的问题。如果问你你怎么回答?

我的理解是这样的,C语言中结构体至少有以下三个作用:

(1)有机地组织了对象的属性。

比如,在STM32的RTC开发中,我们需要数据来表示日期和时间,这些数据通常是年、月、日、时、分、秒。如果我们不用结构体,那么就需要定义6个变量来表示。这样的话程序的数据结构是松散的,我们的数据结构最好是“高内聚,低耦合”的。所以,用一个结构体来表示更好,无论是从程序的可读性还是可移植性还是可维护性皆是:

typedefstruct//公历日期和时间结构体

{

vu16 year;

vu8 month;

vu8 date;

vu8hour;

vu8min;

vu8sec;

}_calendar_obj;

_calendar_objcalendar;//定义结构体变量

(2)以修改结构体成员变量的方法代替了函数(入口参数)的重新定义。

如果说结构体有机地组织了对象的属性表示结构体“中看”,那么以修改结构体成员变量的方法代替函数(入口参数)的重新定义就表示了结构体“中用”。继续以上面的结构体为例子,我们来分析。假如现在我有如下函数来显示日期和时间:

voidDsipDateTime(_calendar_objDateTimeVal)

那么我们只要将一个_calendar_obj这个结构体类型的变量作为实参调用DsipDateTime()即可,DsipDateTime()通过DateTimeVal的成变量来实现内容的显示。如果不用结构体,我们很可能需要写这样的一个函数:

voidDsipDateTime(vu16 year,vu8 month,vu8 date,vu8hour,vu8min,vu8sec)

显然这样的形参很不可观,数据结构管理起来也很繁琐。如果某个函数的返回值得是一个表示日期和时间的数据,那就更复杂了。这只是一方面。

另一方面,如果用户需要表示日期和时间的数据中还要包含星期(周),这个时候,如果之前没有用机构体,那么应该在DsipDateTime()函数中在增加一个形参vu8week:

voidDsipDateTime(vu16 year,vu8 month,vu8 date,vu8week,vu8hour,vu8min,vu8sec)

可见这种方法来传递参数非常繁琐。所以以结构体作为函数的入口参数的好处之一就是

函数的声明voidDsipDateTime(_calendar_objDateTimeVal)不需要改变,只需要增加结构体的成员变量,然后在函数的内部实现上对calendar.week作相应的处理即可。这样,在程序的修改、维护方面作用显著。

typedefstruct//公历日期和时间结构体

{

vu16 year;

vu8 month;

vu8 date;

vu8 week;

vu8hour;

vu8min;

vu8sec;

}_calendar_obj;

_calendar_objcalendar;//定义结构体变量

(3)结构体的内存对齐原则可以提高CPU对内存的访问速度(以空间换取时间)。
并且,结构体成员变量的地址可以根据基地址(以偏移量offset)计算。我们先来看看下面的一段简单的程序,对于此程序的分析会在第2部分结构体成员变量内存对齐中详细说明。

}

#includeint main(){struct	  //声明结构体char_short_long{char  c;short s;long  l;}char_short_long;struct	  //声明结构体long_short_char{long  l;short s;char  c;}long_short_char;struct	  //声明结构体char_long_short{char  c;long  l;short s;}char_long_short;printf(" ");printf(" Size of char   = %d bytes",sizeof(char));printf(" Size of shrot  = %d bytes",sizeof(short));printf(" Size of long   = %d bytes",sizeof(long));printf(" ");	//char_short_longprintf(" Size of char_short_long       = %d bytes",sizeof(char_short_long));printf("     Addr of char_short_long.c = 0x%p (10进制:%d)",&char_short_long.c,&char_short_long.c);printf("     Addr of char_short_long.s = 0x%p (10进制:%d)",&char_short_long.s,&char_short_long.s);printf("     Addr of char_short_long.l = 0x%p (10进制:%d)",&char_short_long.l,&char_short_long.l);printf(" ");printf(" ");	//long_short_charprintf(" Size of long_short_char       = %d bytes",sizeof(long_short_char));printf("     Addr of long_short_char.l = 0x%p (10进制:%d)",&long_short_char.l,&long_short_char.l);printf("     Addr of long_short_char.s = 0x%p (10进制:%d)",&long_short_char.s,&long_short_char.s);printf("     Addr of long_short_char.c = 0x%p (10进制:%d)",&long_short_char.c,&long_short_char.c);printf(" ");printf(" ");	//char_long_shortprintf(" Size of char_long_short       = %d bytes",sizeof(char_long_short));printf("     Addr of char_long_short.c = 0x%p (10进制:%d)",&char_long_short.c,&char_long_short.c);printf("     Addr of char_long_short.l = 0x%p (10进制:%d)",&char_long_short.l,&char_long_short.l);printf("     Addr of char_long_short.s = 0x%p (10进制:%d)",&char_long_short.s,&char_long_short.s);printf(" ");return 0;}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top