(一)、结构体
1、定义与初始化struct student
{
};
注:注意最后的逗号
注:定义在函数外全局可用
2、定义结构体变量
struct student stu;
(如果结构体变量较多时,可以定义宏:typedf struct student STU)
3、如果 char name[100] 为成员,则可以这样赋值:strcpy(stu.name,"zhangshan");或者scanf("%s",stu.name);
如果 char *name;则赋值时:char stu.name = (char *)malloc(sizeof(char) * 100);scanf("%s",stu.name);
4、结构体指针:
定义:struct student *p_stu = &stu;
初始化:(*p_stu).num = 1;或者p_stu->num = 1;
stu.num = 1 <==> (&stu)->num = 1;
5、
也可以这样初始化:
struct student stu = {
.num = 1;
.name = "zhangshan";
.add = "nanjing";
};
6、结构体的所占内存
1>字对齐:成员中有int类型,四个字节一开辟
2>半字对齐:成员中只有小于两字节成员(short),两个字节一开辟
字对齐:
例子:
char ch;
int num
//因为有int,所以char ch 先开辟4个字节,然后num再开辟4个字节,一共8个字节
char ch;
char ch1;
int num;
//因为有int,所以char ch 先开辟4个字节,然后ch1和ch为同一类型,加入到剩下的3字节中,然后num再开辟4个字节,一共8个字节
特殊情况:
char ch;
char ch1;
short num;
//四个字节
char ch;
char short;
char ch1;
//八个字节
半字对齐:
另外:
char ch3;
char ch[7];
8个字节,因为ch[7]是7个字符型,3个填充到之前剩下的空间中,4个再开辟一个新的
所以,相同类型的要放到一起,减少内存空间。
7、结构体的其他用法
如果要传入多个实参,可以传一个结构体变量进去:
struct message
{
int len;
int type;
……
};
void send_message(struct message msg)
{
}
(二)、共用体
1、定义:union student
{
……
};
int main()
{
……
}
定义和初始化和结构体一样
2、共用体特点:
1>其内存长度等于最长的长度,也遵循字对齐和半字对齐
2>成员赋值会被覆盖
3、例子:
union stu
{
int num;
char ch;
};
int main()
{
stu.num = 1;
stu.ch = 'a';
}
打印结果为97,如图:
例子:
union stu
{
int num;
char ch[2];
};
int main()
{
stu.num = 0;
ch[0] = 0;
ch[1] = 1;
printf("%d",num);
}
打印结果为:256
例子:
union stu
{
int num;
char ch[2];
};
int main()
{
stu.num = 0;
ch[0] = 0;
ch[1] = 1;
printf("%d",num);
}
打印结果为:256
数组为连续赋值:0x00000100 = 256
4、大端字节序,小端字节序
int num = 0x12345678;
(三)、枚举
1、定义:enum node
{
A,
B,
C
};
相当于写了三个宏定义#define A = 0 #define B = 1 #define C = 2
2、初始化
enum node p;
p = A;
枚举类型相当于整型变量,所以可以直接定义为int p;
sizeif(p) = 4
3、
enum node
{
A,
B = 9,
C
};
相当于写了三个宏定义#define A = 0 #define B = 9 #define C = 10
enum node
{
A,
B = 9,
C,
D= 15,
E
};
相当于写了三个宏定义#define A = 0 #define B = 9 #define C = 10 #define D = 15 #define E = 16
4、枚举与宏的区别
1>枚举是数据类型,宏不是数据类型
2>枚举占用空间,宏不占用空间
3>枚举只能定义整数宏