自定义类型(结构体,结构体的存储大小如何计算)

简介: 结构:是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。结构体定义由关键字 struct和结构体名组成,结构体名可以根据需要自行定义。其中的struct是定义结构体类型的关键字(必须要写);Stu是当前结构体的字名(可以不写);大括号里面的age,name是成员变量。


当我们想在C语言中定义一个学生类型时就会发现如果用char,int等基础的数据类型来定义的话就实现不了,因为一个学生类型会有学号,姓名……而此时就会用到C语言中的自定义类型中的结构体了。

什么是结构体:

结构:是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

结构体定义由关键字 struct和结构体名组成,结构体名可以根据需要自行定义。

如何声明结构体:

例如你想要定义一个学生类型就可以写成:

structStu{
intage;
charname[10];
};

image.gif

其中的struct是定义结构体类型的关键字 (必须要写);

Stu是当前结构体的字名(可以不写);

大括号里面的age,name是成员变量


结构体的定义:

一种就是和普通变量一样定义比如变量a:

structStu{
intage;
charname[10];
};
intmain()
{
structStua= {18, "zhangsan"};
return0;
}

image.gif

还有一种就是在声明结构体时就定义比如s1(这种方法定义的结构体变量它的生存周期和该结构体类型相同) 如果没有写结构体的名字那么就只能用这种方法才能定义该类型的变量如s2:

structStu{
intage;
charname[10];
}s1;
struct{
intage;
charname[10];
}s2;

image.gif

如何计算结构体类型的大小?

我们就用上面的那个结构体来举例子,下面这幅图画的应该就是我们最容易想到的然后我们就会得出这个类型的大小为4+10=14个字节


image.png

可是我们用sizeof进行计算之后发现并不是这样真正的结果是16;

image.png

那么我们为了可以得到结构体成员变量在内存中的存储的相对位置就需要使用offsetof它可以计算结构体成员相较于结构体起始位置的偏移量, 它不是函数是宏

例一:

image.png

例二:

image.png

从这两个例子就可以看出结构体成员变量在内存中并不是连续存储的。

而这被称为:

结构体内存对齐

对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8 ;Linux中没有默认对齐数,对齐数就是成员自身的大小
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

现在就可以根据规则对对上面两个例子进行解释了

例一:

image.png

age的偏移量为0,name的类型是char所以紧接着存储,但是整个结构体类型的大小因为14不是4(因为int的大小为4字节)的倍数所以要浪费两个字节变为16个字节。而跟据对齐规则也可以算出例二的大小

例二:

image.png

image.png

目录
相关文章
|
7月前
|
存储 C#
C#数据类型之结构体介绍
C#数据类型之结构体介绍
|
编译器 Linux C++
自定义类型结构体(中)
自定义类型结构体(中)
45 0
|
存储 编译器 C语言
结构体的声明使用及存储方式
本篇文章对C语言中的结构体进行了深度剖析。对结构体的声明、使用、内存存储方式等等重点内容进行详细介绍。
108 0
|
7月前
|
存储 编译器 Linux
匿名结构体类型、结构体的自引用、结构体的内存对齐以及结构体传参
匿名结构体类型、结构体的自引用、结构体的内存对齐以及结构体传参
|
7月前
|
编译器 Linux C语言
自定义类型:结构体(2)
自定义类型:结构体(2)
47 1
|
7月前
|
存储
结构体和结构体指针的区别
结构体和结构体指针的区别
240 1
|
7月前
函数与结构体
函数与结构体
42 3
|
编译器 Linux C++
计算结构体的大小
计算结构体的大小
76 0
|
网络协议 编译器 C语言
自定义类型:结构体
自定义类型:结构体
93 0
|
存储 编译器 C语言
自定义类型:结构体-2
自定义类型:结构体
68 0