提示:这里可以添加本文要记录的大概内容:
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量 数组:一组相同类型的集合。
在声明结构的时候,可以不完全的声明。
//匿名结构体类型
//匿名结构体类型一般只能用一次
struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}*p ;
int main()
{
p = &x; //err
return 0;
}
上面的两个结构体在声明的时候省略掉了结构体标签(tag) 那么在上面代码的基础上,下面的代码合法吗? p=&x;
警告: 编译器会把上面的两个声明当成完全不同的两个类型。所以是非法的。
代码如下:
//struct Node
//{
// int data;
// struct Node next;
//};
// 不可行,本质上是错误的 Node next --- 4/8
// --- next
// --- 无穷
struct Node
{
int data;
struct Node *next;
};
错误样例:
typedef struct
{
int data;
Node *next;
}Node;
解决方案:
typedef struct Node
{
int data;
struct Node *next;
}Node;
struct SN
{
char c;
int i;
}sn1 = { 'q',100 }, sn2 = {.i=200,.c='w'};//全局变量
int main()
{
printf("%c %d\n", sn2.c, sn2.i);
return 0;
}
struct SN
{
char c;
int i;
}sn1 = { 'q',100 }, sn2 = {.i=200,.c='w'};//全局变量
struct S
{
double d;
struct SN sn ;
int arr[10];
};
int main()
{
//printf("%c %d\n", sn2.c, sn2.i);
struct S s = { 3.14,{'a',99},{1,2,3} };
printf("%lf %c %d\n", s.d, s.sn.c, s.sn.c, s.sn.i);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", s.arr[i]);
}
return 0;
}
运行结果:
上面的现象分析,我们发先结构体成员不是按照顺序在内存中连续存放的,而是有一定的对齐规则的。 结构体内存对齐的规则:
对齐数:结构体成员自身的大小和默认对齐数的较小值。 VS上默认对齐数是8; gcc没有默认对齐数,对齐数就是结构体成员的自身大小。
#pragma 这个预处理指令,这里我们在次使用,可以改变我们的默认对齐数。
首选print2函数,函数传参的时候,参数需要压栈,会有时间和空间上的系统开销。 如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。
总结:跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是跨平台的问题存在。
枚举顾名思义就是一一列举。 把我们的取值一一列举。
枚举,里面是枚举的可能取值,逗号。
联合也是一种特殊的自定义类型。 这种类型的定义的变量包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)