C语言---自定义类型:结构体(2)

简介: C语言---自定义类型:结构体

C语言---自定义类型:结构体(1)https://developer.aliyun.com/article/1544448

结构体对其的规则:

1.结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处

2.其他的成员变量要对齐到某个数字(对齐数)的整数倍的地址处

对齐数=编译器默认的一个对齐数与该成员变量大小的较小值

--vs中,默认对其的值是8

--Linux中qcc没有默认对齐数,对齐数就是成员自身的大小



3.结构体总大小为最大对齐数。(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)整数倍

4.如果嵌套了结构体的情况。嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整数大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍

//那么结构体是如何对齐的呢?
//结构体成员在内存中到底是怎么存放对齐的?
//那么我们就了解一下结构体对其的规则
 
 
 
//struct S1
//{
//    char c1;
//    char c2;
//    int n;
//};
//
//int main()
//{
//    struct S1 s1;
//
//    return 0;
//}
//1.结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处
 
/*
2.对齐数=编译器默认的一个对齐数与该成员变量大小的较小值
 
--vs中,默认对其的值是8
 
*/
//在这个代码中,c1就是第一个成员,占一个字节,那么c1就占了内存中第0行的空间位置
//c2是1个字节,小于vs规定的对齐数8,所以c2要对齐在1的倍数的位置
//那么刚好1是1的倍数,那么c2就占了第1行的空间位置
 
//因为除了第一个成员,剩下的都是其他成员
 
//因为n的大小是4个字节,vs默认对齐数是8,4<8,那么c2的对齐数就是4
 
//所以n此时此刻要对齐在4的倍数上面,就是偏移量是4的倍数就行了
//所以我们是从第4行开始占的,占4个字节
 
//中间的2 3行是被空着的,因为这两个字节我们用不上了
 
 
/*
现在我们将所有成员都放进内存去了,占了8个字节
 
但是结构体的大小还不能因此判断
我们还要根据第三条进行判断
 
 
3.结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,
所有对齐数中最大的)的整数倍
 
 
这三个成员的默对齐数是最大对齐数是4,
那么在这里结构体的大小就是4的倍数,因为这里刚好8是4的倍数,所以我们直接进行判断结构体的大小是8个字节
 
*/
 
 
 
 
//对s2进行讲解
struct S2
{
 
    char c1;
    int n;
    char c2;
};
 
int main()
{
    struct S2 s2;
 
    return 0;
}
 
/*
根据规则
结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处
因为c1占一个字节,那么c1就放在第一行的位置
 
对于n,n的大小是4个字节,vs上默认对齐数是8,因为4<8
那么取这两个数的较小数就是4作为n的对齐数,所以n要对齐4的倍数
那么我们就只能从第四行开始,因为是4个字节大小,所以从第4行到第7行都是n的范围
 
在这里我们又发现中间的1 2 3行是空的,说明我们又浪费三个字节
 
 
对于c2,因为c2的字节大小是1,vs默认对齐数是8,1<8,所以c2的对齐数是1
所以c2找到1的倍数就行了
 
刚好第8行是1的倍数,那么c2就将第8行占了
 
到目前为止S2占了9个字节了
但是真的是9个字节吗?
 
我们还得根据后面的规则进行判断
在S2中,最大的对齐数是4,那么结构体的总大小是4的倍数
但是9 10 11行都不是4的倍数,所以我们只能取第12行,
所以我们中间又浪费了3个字节的大小
所以最终S2结构体的大小是12
 
*/
struct S3
{
    double d;//0-7
    char c;//8
    int i;//10-12
    //最大对齐数是8,那么最后的位置固定在8的倍数上面,就是16
};
int main()
{
    printf("%d\n", sizeof(struct S3));//16
    return 0;
}
 
//因为double类型是8个字节,根据结构体对其的规则,构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处
//那么0-就是d占了
 
/*
对于c来说,c大小1个字节,vs默认对齐数是8,因为1<8,所以c的对齐数是1
那么只要是1的倍数就行了
所以c就将第8行占了
 
 
对于i,i是4个字节,vs默认对齐数是8,4<8所以i的对齐数是4的倍数
所以 9 10 11这三块字节浪费了,直接从12开始,因为是4个字节大小,所以i的空间就是12-15行
 
因为这三个数据的最大对齐数是8,所以最后的结构体的大小要取8的倍数,,那么我们只能取16了
 
所以最后这个结构体大小就是16
 
*/
//练习4-结构体嵌套问题
struct S3
    {
        double d;
        char c;
        int i;
 
    };
 
 
struct S4
{
 char c1;
 struct S3 s3;
 double d;
};
int main()
{
    struct S4 s4;
    printf("%d\n", sizeof(struct S4));//32
    return 0;
}
 
/*
这种就是结构体嵌套了一种其他类型的结构体变量
 
我们在之前就将S3的大小算出来了,是16个字节的大小
S4成员c1因为是第一个成员,肯定是放在偏移量为0的地址处
因为c1类型是char类型,一个字节大小,所以第0行被c1占了
 
c1放完我们放s3
因为我们计算出的s3是16个字节,但是这个16个字节从哪里开始放呢?
 
 
根据规则4
如果嵌套了结构体的情况。嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,
结构体的整数大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍
 
所以s3要对齐到字节的结构体内最大对齐数8的整数倍处
 
所以s3对齐到8的倍数就行了,因为第一个8的倍数是8
所以s3是从第8行开始对齐的,因为大小是16个字节
 
所以s3占了8-23行
 
所以中间的1-7行的7个字节被浪费了 
 
对于d来说,因为类型是double,大小是8个字节,vs默认对齐数是8,
那么d的对齐数是8,所以d要对齐8的倍数位
因为24是8的对齐数,所以d从24行开始对齐,d的大小是8个字节
所以24-31行是d占了
 
现在我们已经占了32个字节了,从0-31行
那么32是不是我们最终的大小呢?
 
 
 
在规则4中我们还说到
结构体的整数大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍
 
因为这哥结构体所有成员中对齐数里面最大对齐数是8
并且我们结构的大小最终还是要取决最大对齐数的倍数,
因为最大对齐数的倍数是8
所以最终这个结构体的大小我们取32
 
*/

C语言---自定义类型:结构体(3)https://developer.aliyun.com/article/1544453

相关文章
|
26天前
|
存储 C语言
如何在 C 语言中实现结构体的深拷贝
在C语言中实现结构体的深拷贝,需要手动分配内存并逐个复制成员变量,确保新结构体与原结构体完全独立,避免浅拷贝导致的数据共享问题。具体方法包括使用 `malloc` 分配内存和 `memcpy` 或手动赋值。
34 10
|
26天前
|
安全 编译器 Linux
【c语言】轻松拿捏自定义类型
本文介绍了C语言中的三种自定义类型:结构体、联合体和枚举类型。结构体可以包含多个不同类型的成员,支持自引用和内存对齐。联合体的所有成员共享同一块内存,适用于判断机器的大小端。枚举类型用于列举固定值,增加代码的可读性和安全性。文中详细讲解了每种类型的声明、特点和使用方法,并提供了示例代码。
24 3
|
26天前
|
存储 大数据 编译器
C语言:结构体对齐规则
C语言中,结构体对齐规则是指编译器为了提高数据访问效率,会根据成员变量的类型对结构体中的成员进行内存对齐。通常遵循编译器默认的对齐方式或使用特定的对齐指令来优化结构体布局,以减少内存浪费并提升性能。
|
30天前
|
编译器 C语言
共用体和结构体在 C 语言中的优先级是怎样的
在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。
|
30天前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
1月前
|
编译器 C语言 C++
C语言结构体
C语言结构体
27 5
|
1月前
|
编译器 Linux C语言
C语言 之 结构体超详细总结
C语言 之 结构体超详细总结
20 0
|
1月前
|
存储 编译器 Linux
深入C语言:探索结构体的奥秘
深入C语言:探索结构体的奥秘
|
1月前
|
存储 编译器 C语言
c语言回顾-结构体(2)(下)
c语言回顾-结构体(2)(下)
30 0
|
1月前
|
存储 编译器 程序员
c语言回顾-结构体(2)(上)
c语言回顾-结构体(2)(上)
29 0