gpt4 book ai didi

c - ` c = (int *) ((char *) c + 1)` 的作用是什么?

转载 作者:行者123 更新时间:2023-12-05 03:17:33 27 4
gpt4 key购买 nike

我在操作系统类(class)中遇到了这个问题。 Here是6.828(操作系统)在线类(class)的代码。意思是让学习者练习C语言编程中的指针。

#include <stdio.h>
#include <stdlib.h>

void
f(void)
{
int a[4];
int *b = malloc(16);
int *c;
int i;

printf("1: a = %p, b = %p, c = %p\n", a, b, c);

c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);

c[1] = 300;
*(c + 2) = 301;
3[c] = 302;
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);

c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);

c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);

b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}

int
main(int ac, char **av)
{
f();
return 0;
}

我将它复制到一个文件并使用 gcc 编译它,然后我得到了这个输出:

$ ./pointer 
1: a = 0x7ffd3cd02c90, b = 0x55b745ec72a0, c = 0x7ffd3cd03079
2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
6: a = 0x7ffd3cd02c90, b = 0x7ffd3cd02c94, c = 0x7ffd3cd02c91

我很容易理解1,2,3,4的输出。但是我很难理解 5 的输出。特别是为什么 a[1] = 128144 和 a[2] = 256?
看起来这个输出是

的结果
c = (int *) ((char *) c + 1);
*c = 500;

我无法理解代码c = (int *) ((char *) c + 1) 的功能。cint *c 定义的指针。而在第5行输出之前,c通过c = ac = c + 1指向数组a的第二个地址。现在 (char *) c((char *) c + 1) 是什么意思,然后是 (int *) ((char *) c + 1)?

最佳答案

虽然根据标准这是未定义的行为,但它在“古老的 C”中有明确的含义,并且在您使用的机器/编译器上显然以这种方式工作。

首先,它将c 转换为(char *),这意味着指针运算将以sizeof(char) 为单位进行运算(即一个字节)而不是 sizeof(int)。然后它添加一个字节。然后它将结果转换回 (int *)。结果是一个 int 指针,它现在指向比以前高一个字节的地址。由于 c 事先指向 a[1],之后 *c = 500 将写入 a[ 的最后三个字节1]a[2] 的第一个字节。

在许多机器上(但不是 x86),这是完全非法的事情。像这样的未对齐访问只会使您的程序崩溃。 C 标准更进一步说该代码可以做任何:当编译器看到它时,它可以生成崩溃的代码,什么都不做,写入完全不相关的内存位,或者导致一个小侏儒从你的显示器侧面弹出并用木槌敲打你。然而,有时在 UB 情况下最容易做的事情也是显而易见的事情,这就是其中一种情况。

您的类(class) Material 试图向您展示一些有关数字如何存储在内存中的信息,以及如何根据您告诉 CPU 的内容以不同方式解释相同的字节。您应该本着这种精神接受它,不要将其作为编写像样的 C 语言的指南。

关于c - ` c = (int *) ((char *) c + 1)` 的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74119489/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com