如何解释以下代码的输出? (与 C 中的类型转换有关)

How to explain the following code's output? (related to typecasting in C)

我从一个要求它的输出和解释的博客中看到这段代码片段。

#include<stdio.h>

int main()
{
    int *const volatile p = 5;
    printf("%d\n",5/2+p);
    return 0;
}

这是我目前的理解:

1.The const 和 volatile 关键字在输出上下文中没有作用

2.This 代码是一个糟糕的代码,因为它在没有正确转换的情况下在 int* 和 int 之间执行算术运算。

3.I 最初假设输出应该是未定义的。博客说答案是 13(这是我实验发现的)。

Q.What 我不明白 13 是怎么得到的,是编译器未定义行为的结果吗?

4.I 使用 gdb 并确定症结在于操作 p+2 ,其中 p 是指针(保持值 5),2 是整数除法 (5/2) 的结果.

此代码不正确:

int *const volatile p = 5;

不能将整数赋值给(或初始化,规则相同)指针,零值常量表达式的特殊情况除外。编译器必须给出诊断并可以拒绝该程序。如果它确实生成了一个可执行文件,语言规则将不再适用,因为代码违反了合同。

This code is a bad one as it performs arithmetic operation between an int* and an int without a proper cast.

您可以添加一个整数和一个指针而不用强制转换。事实上这是正常的做法。这意味着您将指针向前移动它指向的元素数。

尽管如此,指针运算必须保持在数组对象的范围内,或者指向最后一个。 (为此目的,非数组可以被视为大小为 1 的数组)。因此 5/2 + p,即 p + 2 的有效性将取决于 p 是否已经指向一个数组,并且至少在它之后有另一个数组元素。在您的确切程序中它没有实际意义,因为该程序无效。

同样,printf 的问题也没有实际意义,因为我们已经 运行 关闭了 rails。但是 %d 的 ope运行d 必须具有 int 类型(它不能是指针)。

这确实是未定义的行为,但不是由于算法。由于错误的转换说明符打印指针 - %d 而不是 %p 并将参数转换为 void * - 并用非零 int 值初始化指针.

算术本身:

如果 int 的大小是 4/ sizeof(int) == 4(因为它似乎在您的平台上)结果是 13 因为您增加了指针值乘以 2.

你递增 2 因为在 5/2 处正在进行整数运算并且 2.5 的小数部分将被丢弃。

5 开始时,它会增加 2 4 步。

sizeof(int) == 4
5 + (sizeof(int) * 2) == 13

5 + 8 = 13.

但如上所述,由于错误的转换说明符和用非零 int 值分配指针,这是未定义的行为。


对于指针的整数初始化:

对于错误的转换说明符:

根据sizeof(int) == 4,则命令

int *const volatile p = 5;

分配给指针,作为初始地址,(类似于)0x0005 5 不是一个值,而是地址,因为您还没有为它分配一些内存。然后,在printf()的结果上,结果是2+p,也就是指针运算。指针是 int 类型的,因此,您将其地址添加 2 个位置。因此,2 sizeof(int) 进一步是 2 * 4 = 8。最终,指针指向的地址是 5+8 = 13。 例如,您可以删除关键字 volatile 和 const 以了解它们不会影响结果。此外,您打印出指针引用的地址,但不是它的主题(或取消引用该地址的结果)