houqing1999 发表于 2023-6-9 20:29:17

s1e39课上程序测试题六

本帖最后由 houqing1999 于 2023-6-9 20:42 编辑

如下标黄的四个疑惑,谢谢。
我测了一下Visual Studio是小端字节序,详情见https://fishc.com.cn/thread-75394-1-1.html,但运行之后提示如图其一请问这个是什么意思
#include <stdio.h>

int main(void)
{
      char a = 0, b = 0;
      int *p = (int *)&b;//其二,此外此代码的含义是我理解的把b的地址赋给指针p并强制装换成整形吗,由于局部变量a,b地址连续(其三,只要连续定义两个局部变量地址就一定连续吗)并且b在前,所以这导致b强制转换后污染了a的地址。

      *p = 258;

      printf("%d %d\n", a, b);

      return 0;
}

运行后a,b的结果也不像理想的用VirtualBox虚拟机Linux运行的结果如图而是
是什么原因,其四。

isdkz 发表于 2023-6-9 20:29:45

{:10_277:}

houqing1999 发表于 2023-6-9 20:32:24

isdkz 发表于 2023-6-9 20:29


期待您的解答{:10_289:}

isdkz 发表于 2023-6-9 20:33:01

houqing1999 发表于 2023-6-9 20:32
期待您的解答

此程序设计来测试你的机器是否是小端方式(Little-endian)还是大端方式(Big-endian)。这两种方式是处理器存储和读取多字节数据(比如int类型、float类型等)的方式。

其一:这个提示可能是因为你的代码产生了未定义行为。你试图将一个char变量的地址强制转化为一个int指针,这在C标准中是不被允许的,会导致未定义行为。而"未定义行为"是指,该行为在C标准中没有明确规定,不同的编译器可能会有不同的处理方式。

其二:你的理解是正确的。你的代码确实是把变量b的地址赋给指针p,并强制转换为int*类型。然而,如我在其一中所述,这是一种未定义行为。

其三:局部变量在栈上连续分配的这个行为也是没有明确规定的。C标准没有明确规定局部变量在内存中的布局,虽然许多编译器都会按顺序在栈上分配它们,但这并非一定。因此,不能肯定的说两个连续定义的局部变量的地址就一定连续。

最后的问题:结果与预期不符是因为你在使用一个int指针修改一个char变量,而这两个类型的大小是不一致的。在大多数现代处理器上,char是8位,而int是32位。你试图用一个32位的int来修改一个8位的char,这导致了溢出,你实际上修改了两个char变量a和b的值。

总结,你在此程序中试图做一些未在C标准中明确定义的事情,这导致了不可预测的结果。如果你想探索处理器的字节顺序,我建议你使用更安全、更明确的方式,比如使用联合体(union)。

houqing1999 发表于 2023-6-9 20:45:33

本帖最后由 houqing1999 于 2023-6-9 20:49 编辑

isdkz 发表于 2023-6-9 20:33
此程序设计来测试你的机器是否是小端方式(Little-endian)还是大端方式(Big-endian)。这两种方式是处 ...

原题是这样的

houqing1999 发表于 2023-6-9 20:54:17

isdkz 发表于 2023-6-9 20:33
此程序设计来测试你的机器是否是小端方式(Little-endian)还是大端方式(Big-endian)。这两种方式是处 ...

您最好了,那么我接受您的建议,请问怎样用联合体探索处理器的字节顺序

isdkz 发表于 2023-6-9 20:57:09

houqing1999 发表于 2023-6-9 20:54
您最好了,那么我接受您的建议,请问怎样用联合体探索处理器的字节顺序

在C语言中,联合体(union)可以让我们在同一段内存空间上存储不同类型的变量,因此我们可以利用这个特性来探索机器的字节顺序。具体的方法是,我们先用一个int型的变量存储一个值,然后用一个char型的变量去读取这个int型变量的第一个字节,从而确定机器的字节顺序。

这是一个例子:

#include <stdio.h>

union ByteOrder {
    int value;
    char firstByte;
};

int main() {
    union ByteOrder test;
    test.value = 1;
   
    if (test.firstByte == 1) {
      printf("Little endian\n");
    } else {
      printf("Big endian\n");
    }
   
    return 0;
}


在这个例子中,我们首先创建了一个名为ByteOrder的联合体,这个联合体有两个成员:一个是int型的value,另一个是char型的firstByte。在main函数中,我们创建了一个ByteOrder型的变量test,并将它的value设置为1。由于value和firstByte共享内存空间,因此当我们读取firstByte的时候,我们实际上是在读取value的第一个字节。在小端方式中,最低有效位(即1所在的位置)存储在最小的地址中,因此firstByte的值会是1;在大端方式中,最低有效位存储在最大的地址中,因此firstByte的值会是0。
页: [1]
查看完整版本: s1e39课上程序测试题六