结构的初始化与作函数参数
结构的初始化
结构的初始化与数组的初始化类似,一个位于一对花括号内部、由逗号分隔的初始值列表可用于结构各个成员的初始化。这些值根据结果成员列表写出。如果初始化列表的值不够,剩余的结构成员将使用缺省的值进行初始化。
例如:
struct INT_EX
{
int a;
short b[10];
Simple c;
}x=
{
10,{1,2,3,4,5}
{25,'x',1.9}
};
结构体的存储分配
考虑下面的结构:
struct ALIGN
{
char a;
int b;
char c;
};
如果某个机器的整型值长度为4个字节,并且它的起始存储位置必须能够被4整除,那么这体格结构在内存中的存储将如下图所示:
系统禁止编译器在一个结构的起始位置跳过几个字节来满足边界对齐要求,因此所有结构的起始存储位置必须是结构中边界要求最严格的数据类型所要求的位置。因此,成员a必须存储于一个能被4整除的地址,结构的下一个成员是整型值,必须跳过三个字节到达合适的边界才能存储。在整型值之后是一个字符。
若声明成:
struct ALIGN
{
int b;
char a;
char c;
};
则只需要8个字节存储。
sizeof能够得出一个结构的整体长度,包括因为边界对齐跳过的那些字节。如果你必须确定结构某个成员的实际位置,应该考虑边界对齐因素,可以使用offsetof宏,定义在stddef.h中。
offsetof(type,member)type是结构的类型,member是你需要的那个成员名。表达式的结果是一个size_t值,表示这个指定成员开始存储的位置距离结构体开始存储位置的偏移字节。
作为函数参数的结构
使用结构体变量作为函数的实参时,采用的是值传递,会将结构体变量所占内存单元的内容全部顺序传递给形参,形参必须是同类型的结构体变量。但是这种方法效率很低,因为C语言的参数是传值调用方式,要求把参数的一份拷贝传递给函数。
使用指向结构体变量的指针作为函数参数,指针要比整个结构小得多,所以把它压到堆栈上效率提升很多。传递指针另外需要付出的代价是我们必须在函数中使用间接访问来访问结构的成员。结构越大,把指向它的指针传递给函数的效率就越高。