漫谈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;}
c语言结构 相关文章:
- c语言结构体数组初始化(11-27)
- c语言结构体定义结构体(11-27)
- c语言定义结构体指针(11-27)
- 51单片机之C语言-4.3结构体(11-21)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)