KrisWang 发表于 2020-5-4 00:12:19

新人求助

新人头很大
这边贴了一点图,最近学校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个字节?

KrisWang 发表于 2020-5-4 00:14:32

求各大佬看到的话救救孩子,孩子永世难忘但无以回报,就给个最佳回答把!!哈哈哈

人造人 发表于 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));
    }
    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

KrisWang 发表于 2020-5-4 09:44:38

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

KrisWang 发表于 2020-5-4 09:45:29

人造人 发表于 2020-5-4 00:57
首先,把代码写好,该回车的地方回车,该换行的地方换行,不要把代码揉成一团




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

人造人 发表于 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个字节
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));
    }
    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个字节
04 00 00 00 00 00 00

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


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

人造人 发表于 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));
    }
    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;
}


KrisWang 发表于 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个字节 所以其输出的内容是不可控的 因为后面三个字节不知道存着什么东西

KrisWang 发表于 2020-5-4 16:09:44

C:\Users\75525\Desktop\桌面存图\1.png

人造人 发表于 2020-5-4 16:25:16

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


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


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



人造人 发表于 2020-5-4 16:29:56

0xcccccc61 就是32位的有符号十进制数 -858993567
0xe7562961 就是32位的有符号十进制数 -413783711



人造人 发表于 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));
    }
    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;
}





有一个警告,是 %lu造成的,但是这个程序输出没有出现问题
十进制是 99
十六进制是 63
没有转换

人造人 发表于 2020-5-4 16:38:43

第2个问题有点看不懂,你理解了问题1和问题3后,重新组织一下问题2

KrisWang 发表于 2020-5-4 17:37:41

人造人 发表于 2020-5-4 16:38
第2个问题有点看不懂,你理解了问题1和问题3后,重新组织一下问题2

谢谢老师!!!
我都搞明白了 你讲的超清楚
感谢感谢!!!
(#^.^#)

人造人 发表于 2020-5-4 17:41:35

KrisWang 发表于 2020-5-4 17:37
谢谢老师!!!
我都搞明白了 你讲的超清楚
感谢感谢!!!


^_^

luobin2254 发表于 2020-5-4 18:19:41

111
页: [1]
查看完整版本: 新人求助