Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这种检测机器存储方法不正确?(使用C语言)_C_Cpu Architecture - Fatal编程技术网

为什么这种检测机器存储方法不正确?(使用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的有符号性,尽管在这种特殊情况下,它可能不是问题。。。。或者只打印f
num.a
并查看它的实际内容。您应该尝试在显示“bigend”的x86计算机上使用调试器对此进行调试。如果将
0xff
替换为
0x1
,则可以尝试。如果num是静态/全局变量,则应该可以。否则,它可能会失败,因为并非
a
的所有字节都已初始化。0xFF是有问题的,因为它取决于char的有符号性,尽管在这种特殊情况下,它可能不是问题。。。。或者只打印f
num.a
并查看它的实际内容。
memset()
可以使它与当前编译器版本一起工作,但是读取
num.a
仍然没有定义,因为这仍然违反严格的别名规则。
memset()
可以使它与当前编译器版本一起工作,但是读取
num.a
仍然是未定义的,因为这仍然违反了严格的别名规则。