叶灼hua 2023-11-23 13:20 采纳率: 30.8%
浏览 3
已结题

C语言关于数据在计算机中占用内存大小的问题

C语言,结果为啥是12和8?可以解释一下吗?谢谢

#include <stdio.h>
#include <stdlib.h>

struct CharAndInt{
    int data;
    char s[5];
};
union CharOrInt{
    int data;
    char s[5];
};
int main()
{
    printf("CharAndInt占用%d个字节\n",sizeof(struct CharAndInt));
    printf("CharOrInt占用%d个字节\n",sizeof(union CharOrInt));
    return(0);
}

  • 写回答

4条回答 默认 最新

  • K_n_i_g_h_t_1990 2023-11-23 14:02
    关注

    这可能是因为你使用的编译器的原因,导致了结构体和联合体的内存对齐方式不同。内存对齐是一种优化内存访问速度的技术,它会根据数据类型的大小来调整数据在内存中的位置,使得数据的起始地址是它的大小的整数倍。例如,如果一个int类型的数据占4个字节,那么它的起始地址应该是4的整数倍,比如0,4,8,12等。如果一个char类型的数据占1个字节,那么它的起始地址可以是任意的,比如0,1,2,3等。内存对齐的好处是可以提高内存访问的效率,但是也会造成一些内存空间的浪费。

    在你的代码中,你定义了一个结构体类型CharAndInt,它包含了一个int类型的成员data和一个char类型的数组s[5]。你定义了一个联合体类型CharOrInt,它也包含了一个int类型的成员data和一个char类型的数组s[5]。在我的编译器中,结构体和联合体的内存对齐方式是这样的:

    // 结构体类型CharAndInt的内存布局
    | data | s[0] | s[1] | s[2] | s[3] | s[4] |
    |  0   |  4   |  5   |  6   |  7   |  8   |
    
    // 联合体类型CharOrInt的内存布局
    | data | s[0] | s[1] | s[2] | s[3] | s[4] |
    |  0   |  0   |  1   |  2   |  3   |  4   |
    

    可以看到,结构体类型CharAndInt的大小是9个字节,因为它的最后一个成员s[4]的地址是8,加上它的大小1,就是9。联合体类型CharOrInt的大小是5个字节,因为它的最大的成员是s[5],它的大小是5。所以,我的输出结果是:

    CharAndInt占用9个字节
    CharOrInt占用5个字节
    

    但是,在你的编译器中,结构体和联合体的内存对齐方式可能是这样的:

    // 结构体类型CharAndInt的内存布局
    | data | s[0] | s[1] | s[2] | s[3] | s[4] |
    |  0   |  4   |  5   |  6   |  7   |  8   |
    |      |      |      |      |      |      |
    |      |      |      |      |      |      |
    
    // 联合体类型CharOrInt的内存布局
    | data | s[0] | s[1] | s[2] | s[3] | s[4] |
    |  0   |  0   |  1   |  2   |  3   |  4   |
    |      |      |      |      |      |      |
    

    可以看到,结构体类型CharAndInt的大小是12个字节,因为它的最后一个成员s[4]的地址是8,加上它的大小1,再加上3个字节的空白,就是12。联合体类型CharOrInt的大小是8个字节,因为它的最大的成员是s[5],它的大小是5,再加上3个字节的空白,就是8。所以,你的输出结果是:

    CharAndInt占用12个字节
    CharOrInt占用8个字节
    

    这就是为什么你的输出结果和我预测的不一样的原因。内存对齐的方式取决于编译器的设置,不同的编译器可能有不同的内存对齐规则

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 12月26日
  • 已采纳回答 12月18日
  • 创建了问题 11月23日

悬赏问题

  • ¥15 matlab数据降噪处理,提高数据的可信度,确保峰值信号的不损失?
  • ¥15 怎么看我在bios每次修改的日志
  • ¥15 python+mysql图书管理系统
  • ¥15 Questasim Error: (vcom-13)
  • ¥15 船舶旋回实验matlab
  • ¥30 SQL 数组,游标,递归覆盖原值
  • ¥15 为什么我的数据接收的那么慢呀有没有完整的 hal 库并 代码呀有的话能不能发我一份并且我用 printf 函数显示处理之后的数据,用 debug 就不能运行了呢
  • ¥20 gitlab 中文路径,无法下载
  • ¥15 用动态规划算法均分纸牌
  • ¥30 udp socket,bind 0.0.0.0 ,如何自动选取用户访问的服务器IP来回复数据