为什么这种检测机器存储方法不正确?(使用C语言)
我做作业时漏掉了一道题 计算机内存中的数据存储有大端存储和小端存储两种方法,为了检测一种机器存储方法,一位学生写了以下程序:为什么这种检测机器存储方法不正确?(使用C语言),c,cpu-architecture,C,Cpu Architecture,我做作业时漏掉了一道题 计算机内存中的数据存储有大端存储和小端存储两种方法,为了检测一种机器存储方法,一位学生写了以下程序: union NUM { int a; char b; } num; int main(){ num.b = 0xff; if (num.a! = 0xff) printf ("bigend"); else printf ("smallend"); return 0; } 但他发现运行在x
union NUM {
int a;
char b;
} num;
int main(){
num.b = 0xff;
if (num.a! = 0xff)
printf ("bigend");
else
printf ("smallend");
return 0;
}
但他发现运行在x86机器上的程序,打印输出实际上是“bigend”,这显然是错误的。你知道问题出在哪里吗?
该如何修改该程序
我问过我的老师,题目是正确的。我在一些网站上找到了一些信息,但这让我更加困惑。为什么这个问题不正确?而问题实际在哪里呢?假设一个
int
(因此整个联合)是4个字节,写入num.b
只写入这4个字节中的一个,其余的未初始化。随后读取num.a
读取那些未初始化的字节,调用
联合中的字节必须设置为所有0,以便内容得到良好定义
#include <stdio.h>
#include <string.h>
union NUM {
int a;
char b;
} num;
int main(){
// set all bytes of num to 0 first
memset(&num, 0, sizeof(num));
num.b = 0xff;
if (num.a! = 0xff)
printf ("bigend");
else
printf ("smallend");
return 0;
}
#包括
#包括
工会会员{
INTA;
字符b;
}num;
int main(){
//首先将num的所有字节设置为0
memset(&num,0,sizeof(num));
num.b=0xff;
如果(num.a!=0xff)
printf(“bigend”);
其他的
printf(“smallend”);
返回0;
}
假设int
(因此整个联合)是4个字节,写入num.b
只写入这4个字节中的一个,其余的未初始化。随后读取num.a
读取那些未初始化的字节,调用
联合中的字节必须设置为所有0,以便内容得到良好定义
#include <stdio.h>
#include <string.h>
union NUM {
int a;
char b;
} num;
int main(){
// set all bytes of num to 0 first
memset(&num, 0, sizeof(num));
num.b = 0xff;
if (num.a! = 0xff)
printf ("bigend");
else
printf ("smallend");
return 0;
}
#包括
#包括
工会会员{
INTA;
字符b;
}num;
int main(){
//首先将num的所有字节设置为0
memset(&num,0,sizeof(num));
num.b=0xff;
如果(num.a!=0xff)
printf(“bigend”);
其他的
printf(“smallend”);
返回0;
}
类型双关在C中是未定义的行为。当您读取num.a
时,您违反了严格的别名规则,因此允许编译器生成可能返回任何内容的代码。确实如此
要避免这种情况,您需要使用memcpy()
:
类型双关在C中是未定义的行为。当您读取
num.a
时,您违反了严格的别名规则,因此允许编译器生成可能返回任何内容的代码。确实如此
要避免这种情况,您需要使用memcpy()
:
您应该尝试在显示“bigend”的x86计算机上使用调试器对此进行调试。如果将
0xff
替换为0x1
,则尝试是否可行。如果num是一个静态/全局变量,则它应该可行。否则,它可能会失败,因为并非a
的所有字节都已初始化。0xFF是有问题的,因为它取决于char的有符号性,尽管在这种特殊情况下,它可能不是问题。。。。或者只打印fnum.a
并查看它的实际内容。您应该尝试在显示“bigend”的x86计算机上使用调试器对此进行调试。如果将0xff
替换为0x1
,则可以尝试。如果num是静态/全局变量,则应该可以。否则,它可能会失败,因为并非a
的所有字节都已初始化。0xFF是有问题的,因为它取决于char的有符号性,尽管在这种特殊情况下,它可能不是问题。。。。或者只打印fnum.a
并查看它的实际内容。memset()
可以使它与当前编译器版本一起工作,但是读取num.a
仍然没有定义,因为这仍然违反严格的别名规则。memset()
可以使它与当前编译器版本一起工作,但是读取num.a
仍然是未定义的,因为这仍然违反了严格的别名规则。