平时我们要求函数的参数尽量不多于四个,如果函数的参数多于四个使用起开非常容易出错(包括每个参数的意义和顺序都容易弄错),效率也会降低(与具体CPU有关)。这个时候,就可以用结构体压缩参数个数。
空结构体多大
结构体所占的内存大小是其成员内存之和,如果成员内存为0,例如:
struct student
{
}stu;
sizeof(stu)的值是多少?
在Visual C++上测试结果是1 。GCC里计算出来为0。
C99(C语言的官方标准第二版)中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员,但结构中的柔性数组成员前面必须至少有一一个其他成员。柔性数组成员允许结构中包含一个大小可变的数组。sizeof返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
柔性数组的使用:
typedef struct st_type
{
int i;
int a[0];
}type_a;
有些编译器会报错无法编译可以改成:
typedef struct st_type
{
int i;
int a[];
}type_a;
这样我们就可以定义一个可变长的结构体,用sizeof(type_ a) 得到的只有4,就是sizeof(i) = sizeof(int)。0个元素的数组没有占用空间,而后我们可以进行变长操作了。通过如下表达式给结构体分配内存:
type_a *p = (type_a *)malloc(sizeof(type_a)+100*sizeof(int));
这样我们为结构体指针p分配了一块内存。用p->item[n]就能简单地访问可变长元素。但是这时候我们再用sizeof(¥p)测试结构体的大小,发现仍然为4。
在定义这个结构体的时候,模子的大小就已经确定不包含柔性数组的内存大小。柔性数组只是编外人员,不占结构体的编制,只是说在使用柔性数组时需要把它当作结构体的一个成员,仅此而已。再说得直白点,柔性数组其实与结构体没什么关系,只是“挂羊头卖狗肉”而已,算不得结构体的正式成员。
需要说明的是:C89不支持这种东西,C99把它作为一-种特例加人了标准。但是,C99支持的而不是zeroarray,形同intitem[0],这种形式是非法的;C99支持的是incomplete type ,形同int item[],只不过有些编译器把int item[0]作为非标准扩展来支持,而且在C99发布之前已经有了这种非标准扩展了。C99发布之后,有些编泽器把两者合而为一。
当然,上面既然用malloc函数分配了内存,肯定就需要用free函数来释放内存:
free(p);
struct的成员默认情况下的属性是public,而class成员的却是private。
union关键字的用法与struct的用法非常类似。
union维护足够的空间来放置多个数据成员中的“一种”,而不是为每一个数据成员配置空间。在union中所以的数据成员公用一个空间,同一时间只能储存其中一个数据成员,所以的数据成员具有相同的起始地址。例如:
union StateMachine
{
char character;
int number;
char *str;
double exp;
};
一个union只配置一个足够大的空间来容纳最大长度的数据成员,以本例而言,最大长度是double类型,所以StateMachine的空间大小就是double数据类型的大小。
大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节
则存放在高地址中。
小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字
节则存放在低地址中。
union型数据所占的空间等于其最大的成员所占的空间。对union型成员的存取都
从相对于该联合体基地址的偏移量为0处开始,也就是联合体的访问不论对哪个变量的
存取都是从union的首地址位置开始。
写一个C函数,若处理器是大端,返回0;处理器是小端,返回1。
int checkSystem()
{
union check
{
int i;
char ch;
}c;
c.88i = 1;
return(c.ch == 1);
}
枚举类型的使用方法
enum enum_type_name
{
ENUM_CONST_1,
ENUM_CONST_2,
...
ENUM_CONST_n,
}enum_variable_name;
#define宏常量是在预编译阶段进行简单替换;枚举常量则是在编译的时候确实其值。
一般在调试器里,可以调试枚举常量,但是不能调试宏常量。
枚举可以一次定义大量相关的常量,而#define宏一次只能定义一个。
typedef
typedef struct student
{
//code
}Stu_st,*Stu_pst;
struct student stu1 和 Stu_st stu1——没有区别
struct student *stu、Stu_pst 和 Stu_st *stu2——没有区别