鱼C论坛

 找回密码
 立即注册
查看: 2254|回复: 4

[已解决]求助想知道这里打印的值是什么

[复制链接]
发表于 2022-10-21 10:08:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>

  2. typedef struct type_a
  3. {
  4.     int a;
  5.     int b;
  6.     int c;
  7.     char d;
  8.     int e;
  9. }type_a_t;

  10. typedef struct type_b
  11. {
  12.     int a;
  13.     int b;
  14.     char d;
  15.     int e;
  16. }type_b_t;

  17. void print(type_a_t *a)
  18. {
  19.     printf("a->a = %d\n", a->a);
  20.     printf("a->b = %d\n", a->b);
  21.     printf("a->c = %d\n", a->c);
  22.     printf("a->d = %c\n", a->d);
  23.     printf("a->e = %d\n", a->e);
  24. }

  25. int main()
  26. {
  27.     type_b_t b;
  28.     b.a = 1;
  29.     b.b = 2;
  30.     b.d = 'c';
  31.     b.e = 72;
  32.     print((type_a_t*)&b);
  33.     return 0;
  34. }
复制代码

打印"a->e = %d\n"为什么结果是1呢?
最佳答案
2022-10-21 12:26:22
本帖最后由 jackz007 于 2022-10-21 13:54 编辑
是fafa也是花花 发表于 2022-10-21 11:57
您好,我是用的VS Code编译的,编译结果如下:
a->a = 1
a->b = 2

  1. #include <stdio.h>

  2. typedef struct type_a
  3. {
  4.     int a;
  5.     int b;
  6.     int c;
  7.     char d;        // d 本来应该只占用 1 个字节,但是,由于后面的 e 是 int,需要在 4 字节对齐位置保存,所以,d 实际占用 4 个字节
  8.     int e;         
  9. }type_a_t;

  10. typedef struct type_b
  11. {
  12.     int a;
  13.     int b;
  14.     char d;        // d 本来应该只占用 1 个字节,但是,由于后面的 e 是 int,需要在 4 字节对齐位置保存,所以,d 实际占用 4 个字节
  15.     int e;
  16. }type_b_t;
复制代码

        由于代码中注释的原因,实际上,type_a 就是拥有 5 个整型数成员的结构,而 type_b 则是拥有 4 个整型数成员的结构,关于这一点,只要分别打印 sizeof(type_a) 和 sizeof(type_b) 就可以看到,type_a 比 type_b 多占用 4 个字节的内存空间。变量 b 按 type_b 进行定义和赋值,却要按 type_a 打印,那么,相当于 type_a 结构的前 4 个成员都有赋值,第 5 个成员 e 已经超出了 type_b 的结构体范围,处于未赋值的状态(也就是野值),在不同的机器上或使用不同的编译器编译,打印出的这个值(type_a 的成员 e)都不相同,比如,楼主打印的是 1,在我这里,使用 tdm-gcc 5.1.0 编译,打印出的 a -> e 的值为 3;使用 VC6.0 编译,打印出的 a -> e 是 1245120。
        【tdm-gcc 5.1.0】:
  1. D:\[00.Exerciese.2022]\C>g++ -o x x.c

  2. D:\[00.Exerciese.2022]\C>x
  3. a->a = 1
  4. a->b = 2
  5. a->c = 99
  6. a->d = H
  7. a->e = 3

  8. D:\[00.Exerciese.2022]\C>
复制代码

    【VC 6.0】
  1. D:\[00.Exerciese.2022]\C>cl x.c
  2. Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
  3. Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

  4. x.c
  5. Microsoft (R) Incremental Linker Version 6.00.8447
  6. Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

  7. /out:x.exe
  8. x.obj

  9. D:\[00.Exerciese.2022]\C>x
  10. a->a = 1
  11. a->b = 2
  12. a->c = 99
  13. a->d = H
  14. a->e = 1245120

  15. D:\[00.Exerciese.2022]\C>
复制代码

        所以,答案就是,a -> e  是野值
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-10-21 10:55:03 | 显示全部楼层
应该是因为内存对齐吧,具体你可能要发下所有的输出结果,还有你的编译器,我没推出来你这对齐方法
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-21 11:57:52 | 显示全部楼层
kishere 发表于 2022-10-21 10:55
应该是因为内存对齐吧,具体你可能要发下所有的输出结果,还有你的编译器,我没推出来你这对齐方法

您好,我是用的VS Code编译的,编译结果如下:
a->a = 1
a->b = 2
a->c = 99
a->d = H
a->e = 1
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-21 12:26:22 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-10-21 13:54 编辑
是fafa也是花花 发表于 2022-10-21 11:57
您好,我是用的VS Code编译的,编译结果如下:
a->a = 1
a->b = 2

  1. #include <stdio.h>

  2. typedef struct type_a
  3. {
  4.     int a;
  5.     int b;
  6.     int c;
  7.     char d;        // d 本来应该只占用 1 个字节,但是,由于后面的 e 是 int,需要在 4 字节对齐位置保存,所以,d 实际占用 4 个字节
  8.     int e;         
  9. }type_a_t;

  10. typedef struct type_b
  11. {
  12.     int a;
  13.     int b;
  14.     char d;        // d 本来应该只占用 1 个字节,但是,由于后面的 e 是 int,需要在 4 字节对齐位置保存,所以,d 实际占用 4 个字节
  15.     int e;
  16. }type_b_t;
复制代码

        由于代码中注释的原因,实际上,type_a 就是拥有 5 个整型数成员的结构,而 type_b 则是拥有 4 个整型数成员的结构,关于这一点,只要分别打印 sizeof(type_a) 和 sizeof(type_b) 就可以看到,type_a 比 type_b 多占用 4 个字节的内存空间。变量 b 按 type_b 进行定义和赋值,却要按 type_a 打印,那么,相当于 type_a 结构的前 4 个成员都有赋值,第 5 个成员 e 已经超出了 type_b 的结构体范围,处于未赋值的状态(也就是野值),在不同的机器上或使用不同的编译器编译,打印出的这个值(type_a 的成员 e)都不相同,比如,楼主打印的是 1,在我这里,使用 tdm-gcc 5.1.0 编译,打印出的 a -> e 的值为 3;使用 VC6.0 编译,打印出的 a -> e 是 1245120。
        【tdm-gcc 5.1.0】:
  1. D:\[00.Exerciese.2022]\C>g++ -o x x.c

  2. D:\[00.Exerciese.2022]\C>x
  3. a->a = 1
  4. a->b = 2
  5. a->c = 99
  6. a->d = H
  7. a->e = 3

  8. D:\[00.Exerciese.2022]\C>
复制代码

    【VC 6.0】
  1. D:\[00.Exerciese.2022]\C>cl x.c
  2. Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
  3. Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

  4. x.c
  5. Microsoft (R) Incremental Linker Version 6.00.8447
  6. Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

  7. /out:x.exe
  8. x.obj

  9. D:\[00.Exerciese.2022]\C>x
  10. a->a = 1
  11. a->b = 2
  12. a->c = 99
  13. a->d = H
  14. a->e = 1245120

  15. D:\[00.Exerciese.2022]\C>
复制代码

        所以,答案就是,a -> e  是野值
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-21 14:00:38 | 显示全部楼层
jackz007 发表于 2022-10-21 12:26
由于代码中注释的原因,实际上,type_a 就是拥有 5 个整型数成员的结构,而 type_b 则是拥有 ...

谢谢您,我理解了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-23 02:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表