鱼C论坛

 找回密码
 立即注册
查看: 2591|回复: 15

[已解决]新人求助

[复制链接]
发表于 2020-5-4 00:12:19 | 显示全部楼层 |阅读模式

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

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

x
新人头很大
这边贴了一点图,最近学校c要考试
共用体这边实在不懂
union
{
int a;
float b;
char c;
double d;
}
书上说共用体共用同一块内存谁大用谁
且不能同时应用2个以上共用体
但是看到题目我发现是我太单纯了
我电脑64位Devc++测试的
问题1:上穿了3道题目附答案 想问一下这是为什么
问题2:为什么我测试时,int double char 很多时候共用数值但是float一直显示是0
问题3:为什么赋值double 和float的时候 int 和char 输出的是地址也不知道什么乱七八糟的
问题4:
union
{
int a;
float b;
char c;
double d;
}
例如这样定义了一个共用体,那么其存储空间是否是double也就是8个字节?

最佳答案
2020-5-4 00:57:10
首先,把代码写好,该回车的地方回车,该换行的地方换行,不要把代码揉成一团


自己尝试着分析这个程序,如果那里看不懂再提问
#include <stdio.h>
#include <string.h>

void view_byte(void *obj, int size) {
    for(int i = 0; i < size; ++i) {
        printf("%.2x ", ((unsigned char *)obj)[i]);
    }
    printf("\n");
}

int main(void) {
    union {int a; float b; char c; double d;} demo;
    printf("char: %lu\n", sizeof(char));
    printf("int: %lu\n", sizeof(int));
    printf("float: %lu\n", sizeof(float));
    printf("double: %lu\n", sizeof(double));
    printf("demo: %lu\n", sizeof(demo));

    printf("\na = 1234\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.a = 1234;
    view_byte(&demo, sizeof(demo));

    printf("\nb = 123.456\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.b = 123.456;
    view_byte(&demo, sizeof(demo));

    printf("\nc = 'a'\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.c = 'a';
    view_byte(&demo, sizeof(demo));

    printf("\nd = 123.456\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.d = 123.456;
    view_byte(&demo, sizeof(demo));
    return 0;
}
char: 1
int: 4
float: 4
double: 8
demo: 8

a = 1234
00 00 00 00 00 00 00 00 
d2 04 00 00 00 00 00 00 

b = 123.456
00 00 00 00 00 00 00 00 
79 e9 f6 42 00 00 00 00 

c = 'a'
00 00 00 00 00 00 00 00 
61 00 00 00 00 00 00 00 

d = 123.456
00 00 00 00 00 00 00 00 
77 be 9f 1a 2f dd 5e 40 
E0YL%BG$[O8W[U56QITE.png
72X1L8E}B)3G46_[@FN)$~1.png
15J7)P0MSM0{OB~D7R5Y9RH.png
NAXDTFNR1)4GH2OGMO6`6NS.png
VC0BBXE%(A)1X@8NX]2Y%DI.png
LRGAVTL8~6C3FOORP47FS%A.png
W6A7~~A_ZOJRZN~VDI}82B6.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-5-4 00:14:32 | 显示全部楼层
求各大佬看到的话救救孩子,孩子永世难忘但无以回报,就给个最佳回答把!!哈哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 00:57:10 | 显示全部楼层    本楼为最佳答案   
首先,把代码写好,该回车的地方回车,该换行的地方换行,不要把代码揉成一团


自己尝试着分析这个程序,如果那里看不懂再提问
#include <stdio.h>
#include <string.h>

void view_byte(void *obj, int size) {
    for(int i = 0; i < size; ++i) {
        printf("%.2x ", ((unsigned char *)obj)[i]);
    }
    printf("\n");
}

int main(void) {
    union {int a; float b; char c; double d;} demo;
    printf("char: %lu\n", sizeof(char));
    printf("int: %lu\n", sizeof(int));
    printf("float: %lu\n", sizeof(float));
    printf("double: %lu\n", sizeof(double));
    printf("demo: %lu\n", sizeof(demo));

    printf("\na = 1234\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.a = 1234;
    view_byte(&demo, sizeof(demo));

    printf("\nb = 123.456\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.b = 123.456;
    view_byte(&demo, sizeof(demo));

    printf("\nc = 'a'\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.c = 'a';
    view_byte(&demo, sizeof(demo));

    printf("\nd = 123.456\n");
    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.d = 123.456;
    view_byte(&demo, sizeof(demo));
    return 0;
}
char: 1
int: 4
float: 4
double: 8
demo: 8

a = 1234
00 00 00 00 00 00 00 00 
d2 04 00 00 00 00 00 00 

b = 123.456
00 00 00 00 00 00 00 00 
79 e9 f6 42 00 00 00 00 

c = 'a'
00 00 00 00 00 00 00 00 
61 00 00 00 00 00 00 00 

d = 123.456
00 00 00 00 00 00 00 00 
77 be 9f 1a 2f dd 5e 40 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-4 09:44:38 | 显示全部楼层
好的,以后我写代码也会规范一些,易读一些,谢谢指点。
你的代码我看了 memset  我初学还未掌握这块内容百度了一下 感觉阅读下来问题不大。
不过这串代码好像对我帮助有限
我有比较大一部分问题是
a赋值完 bcd的数值是多少
b赋值完 acd的数值是多少
c赋值完 abd的数值是多少
d赋值完 abc的数值是多少
本人是个学生,考试是笔试也不能直接跑程序测试,就比如这种选择题,输入完数值问我输出另一个的结果
我该怎么看呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-4 09:45:29 | 显示全部楼层
人造人 发表于 2020-5-4 00:57
首先,把代码写好,该回车的地方回车,该换行的地方换行,不要把代码揉成一团

好的,以后我写代码也会规范一些,易读一些,谢谢指点。
你的代码我看了 memset  我初学还未掌握这块内容百度了一下 感觉阅读下来问题不大。
不过这串代码好像对我帮助有限
我有比较大一部分问题是
a赋值完 bcd的数值是多少
b赋值完 acd的数值是多少
c赋值完 abd的数值是多少
d赋值完 abc的数值是多少
本人是个学生,考试是笔试也不能直接跑程序测试,就比如这种选择题,输入完数值问我输出另一个的结果
我该怎么看呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 14:26:26 | 显示全部楼层
这条语句把demo占用的内存(8个字节)初始化成 0
memset(&demo, 0, sizeof(demo));

输出当前demo变量中的内容
view_byte(&demo, sizeof(demo));

demo.a赋值为1234
demo.a = 1234;


然后再一次输出demo中的内容
d2 04 00 00 00 00 00 00 

a是int类型,看上面的输出是 4 个字节
也就是只有前面4个字节
[d2 04 00 00] 00 00 00 00 

0x000004d2就是十进制的1234


c = 'a'
00 00 00 00 00 00 00 00 
61 00 00 00 00 00 00 00 

demo.c就一个字节,0x61就是字符 'a'


d = 123.456
00 00 00 00 00 00 00 00 
77 be 9f 1a 2f dd 5e 40 

b = 123.456
00 00 00 00 00 00 00 00 
79 e9 f6 42 00 00 00 00 

这两个浮点数比较麻烦,需要你先理解浮点数的存储格式
https://www.cnblogs.com/wuyuan2011woaini/p/4105765.html

下面再说一说你提的的那个问题
对一个赋值,然后读取另一个

#include <stdio.h>
#include <string.h>

void view_byte(void *obj, int size) {
    for(int i = 0; i < size; ++i) {
        printf("%.2x ", ((unsigned char *)obj)[i]);
    }
    printf("\n");
}

int main(void) {
    union {int a; float b; char c; double d;} demo;
    printf("char: %lu\n", sizeof(char));
    printf("int: %lu\n", sizeof(int));
    printf("float: %lu\n", sizeof(float));
    printf("double: %lu\n", sizeof(double));
    printf("demo: %lu\n", sizeof(demo));

    memset(&demo, 0, sizeof(demo));
    view_byte(&demo, sizeof(demo));
    demo.a = 1234;
    view_byte(&demo, sizeof(demo));
    printf("%c\n", demo.c);

    return 0;
}


也就是最后一个printf输出的内容
对于这类问题,把十进制转换成十六进制
a = 1234
00 00 00 00 00 00 00 00 
d2 04 00 00 00 00 00 00 

demo.a = 1234;
转换成
demo.a = 0x000004d2;

访问demo.c就是访问第0个字节
[d2] 04 00 00 00 00 00 00 

是0xd2,也就是
printf("%c\n", demo.c);
就是
printf("%c\n", 0xd2);


对于考试也一样,把这些值看成十六进制

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 14:29:33 | 显示全部楼层
如果你理解了上面的内容,试着分析下面的程序,看看能不能理解,如果那里不理解再提问
#include <stdio.h>
#include <string.h>

void view_byte(void *obj, int size) {
    for(int i = 0; i < size; ++i) {
        printf("%.2x ", ((unsigned char *)obj)[i]);
    }
    printf("\n");
}

int main(void) {
    union {int a; float b; char c; double d;} demo;
    printf("char: %lu\n", sizeof(char));
    printf("int: %lu\n", sizeof(int));
    printf("float: %lu\n", sizeof(float));
    printf("double: %lu\n", sizeof(double));
    printf("demo: %lu\n", sizeof(demo));

    //view_byte(&demo, sizeof(demo));
    demo.c = 'a';
    //view_byte(&demo, sizeof(demo));
    printf("%d\n", demo.a);

    return 0;
}

2.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-4 16:07:55 | 显示全部楼层
本帖最后由 KrisWang 于 2020-5-4 16:10 编辑
人造人 发表于 2020-5-4 14:29
如果你理解了上面的内容,试着分析下面的程序,看看能不能理解,如果那里不理解再提问


大哥教了我很多,我就先暂且称您老师了
老师你的代码和注释我都看完了
有两个问题
1 我学习中遇到的%u是无符号整形 所以%lu 应该是无符号长整形,他们的输出格式不应该是十进制吗 ,为什么转成16进制了呢?(由于您写的注释和代码我又看懂了,所以就更迷茫因为程序的输出结果还真是都转成了16进制)
2 基于第一个问题之上,题目中赋值demo .d1  =99 那么我测试下来demo中的 int成员a 和char成员c 的值都是99 我学习中了解到 10进制是一个字节 所以我可否理解为 char类型就取第一个字节的数值 也就是99
这边的主要问题是 也是保存自身数值 没有转换成16进制哎
3  老师 最后的代码 各个类型对应的字节我清楚了 谢谢!问题是 为什么赋值字符‘a’后 输出整形是一串不知道什么的东西呢 个人理解 首先字符a只保证第一个字节的数值为a 而int类型是4个字节 所以其输出的内容是不可控的 因为后面三个字节不知道存着什么东西
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-4 16:09:44 | 显示全部楼层
C:\Users\75525\Desktop\桌面存图\1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 16:25:16 | 显示全部楼层
KrisWang 发表于 2020-5-4 16:07
大哥教了我很多,我就先暂且称您老师了
老师你的代码和注释我都看完了
有两个问题

第3个问题你理解的没错,a是4个字节,但是只有第0个字节赋值为了 'a'
后面3个字节的内容不知道是什么,有一些编译器把后面3个字节初始化成了0,有一些是初始化成了 0xcc
还有的编译器就不初始化,里面的内容就真的是随机的


vs初始化成了 0xcc
gcc就没有初始化,里面的内容乱七八糟的,^_^

1.png
2.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 16:29:56 | 显示全部楼层
0xcccccc61 就是32位的有符号十进制数 -858993567
0xe7562961 就是32位的有符号十进制数 -413783711

1.png
2.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 16:36:04 | 显示全部楼层
问题1,没有转换成十六进制呀
#include <stdio.h>
#include <string.h>

void view_byte(void *obj, int size) {
    for(int i = 0; i < size; ++i) {
        printf("%.2x ", ((unsigned char *)obj)[i]);
    }
    printf("\n");
}

int main(void) {
    union {int a; float b; char c; double d;} demo;
    printf("char: %lu\n", sizeof(char));
    printf("int: %lu\n", sizeof(int));
    printf("float: %lu\n", sizeof(float));
    printf("double: %lu\n", sizeof(double));
    printf("demo: %lu\n", sizeof(demo));

    demo.a = 99;
    printf("d:%d\n", demo.a);
    printf("u:%u\n", demo.a);
    printf("lu:%lu\n", demo.a);
    printf("x:%x\n", demo.a);

    return 0;
}

1.png


有一个警告,是 %lu造成的,但是这个程序输出没有出现问题
十进制是 99
十六进制是 63
没有转换
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 16:38:43 | 显示全部楼层
第2个问题有点看不懂,你理解了问题1和问题3后,重新组织一下问题2
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-4 17:37:41 | 显示全部楼层
人造人 发表于 2020-5-4 16:38
第2个问题有点看不懂,你理解了问题1和问题3后,重新组织一下问题2

谢谢老师!!!
我都搞明白了 你讲的超清楚
感谢感谢!!!
(#^.^#)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 17:41:35 | 显示全部楼层
KrisWang 发表于 2020-5-4 17:37
谢谢老师!!!
我都搞明白了 你讲的超清楚
感谢感谢!!!

^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-4 18:19:41 | 显示全部楼层
111
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-11 18:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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