构造类型

一、结构体

将不同类型的数据存储在同一个内存空间

类型描述

1
2
3
4
5
6
7
8
9
10
11
12
struct 结构体名字
{
数据类型 成员1;
数据类型 成员2;
};
// 结构体的类型描述(只是表明这种数据结构由哪些类型的数据组成)不占用存储空间,无法直接用等号初始化
如;
struct Student
{
int id;
char name[10];
};

定义结构体

1
2
3
struct 结构体名字 变量名
如:
struct Student zxz;


1.结构体的内存(地址对齐)

对于内存中放置不同类型的数据的对齐信息都有考量—因为有了该对齐信息—可以让CPU很快的找到数据,地址对齐方便硬件取地址

代码1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>

int NAMESIZE = 8;

struct student_st
{
int i;
char ch;
float f;

};

int main()
{
struct student_st st;
struct student_st *p = &st;

printf("struct(p) = %ld\n",sizeof(p));
printf("struct(st) = %ld\n",sizeof(st));
return 0;

}

运行结果 因为当前运行程序的机器环境为64位,所以指针大小为8个字节,而结构体st的大小为12字节

image-20230305095236954

代码2

在结构体中,添加一个字节 ch2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>

int NAMESIZE = 8;

struct student_st
{
int i;
char ch;
char ch2;
float f;
};

int main()
{
struct student_st st;
struct student_st *p = &st;

printf("struct(p) = %ld\n",sizeof(p));
printf("struct(st) = %ld\n",sizeof(st));
return 0;

}

运行结果,与代码1结果相同

image-20230305095900069

代码3

float f放到chch1之间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>

int NAMESIZE = 8;

struct student_st
{
int i;
char ch;
float f;
char ch2;
};

int main()
{
struct student_st st;
struct student_st *p = &st;

printf("struct(p) = %ld\n",sizeof(p));
printf("struct(st) = %ld\n",sizeof(st));
return 0;

}

运行结果存在不同,指针仍是8字节,但是结构体不同,为16字节

image-20230305100140476

出现上面的情况是由于机器的地址对齐造成的

参考公式addr % sizeof(i) 如可以整除则变量i存储在该地址处

image-20230305102810599让机器不地址对齐

在结构体后声明关键词__attributr__((packed))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>

int NAMESIZE = 8;

struct student_st
{
int i;
char ch;
float f;
char ch2;
}__attributr__((packed));

int main()
{
struct student_st st;
struct student_st *p = &st;

printf("struct(p) = %ld\n",sizeof(p));
printf("struct(st) = %ld\n",sizeof(st));
return 0;

}

运行结果,结构体内存大小发生了变化,为10字节,即4+1+4+1 = 12

image-20230305102157819




二、共用体

1. 共用体

形式:

1
2
3
4
5
6
7
8
9
union un
{
int a;
char ch;
};
// 该共用体a为4字节 ch为1字节 因此un大小为4字节
// 创建对象 共用体a
union un a

共用体的所占内存为:共用体内存大小为 共用体所包含的数据中所占内存最大的数据的内存大小

实例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>

union test_un
{
int i;
float f; // 4字节
double d; // 共用体中内存最大的8字节
char ch;
};

int main()
{
union test_un a;
a.f = 345.678;
printf("%f\n",a.f);
printf("%ld\n",sizeof(a));
return 0;
}

运行结果 该共用体变量此时的内存大小为8字节,即double变量的内存大小

image-20230306092726474



2. 硬件存储

硬件存储数据两种方式:

大端:数据的第一位存在高地址中

小端:数据的第一位存在低地址中




三、枚举

枚举类型可以视作有值的宏进行使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>

enum day{
MON = 1,
TUS,
THR,
WES
};

int main()
{
enum day a = MON;
enum day b = WES;
printf("%d\n",a);
printf("%d\n",b);
return 0;
}

运行结果

image-20230307213542982