gpt4 book ai didi

c - 'printf("%n %d", &a, a)' 定义明确吗?

转载 作者:行者123 更新时间:2023-12-03 23:26:54 25 4
gpt4 key购买 nike

#include <stdio.h>

int main(void) {
int i = 0;
printf("abc %n %d", &i, i);
printf("\n%d\n", i);
}
当我执行该操作时,我得到了以下结果。
abc  0
4
我认为这个结果是有意的。
但是当我执行下一个时,我得到了不同的结果。
int main(void) {
int i; // not initialize
printf("abc %n %d", &i, i);
printf("\n%d\n", i);
}
这产生了:
abc  1
4
我不知道为什么 i 的结果在第一个 printf()1 .
甚至,我发现了更多奇怪的行为:
int main(void) {
int sdf;
printf("abc %n %d", &sdf, sdf);
printf("\n%d\n", sdf);
int i;
printf("abc %n %d", &i, i);
printf("\n%d\n", i);
}
使用此输出:
abc  1
4
abc Random_Value
4
第一个总是显示 1但其他人显示随机值(我认为这是垃圾值)。
我认为垃圾值是有意的,但我不明白为什么第一个有不同的结果。

最佳答案

存储类 auto 的未初始化局部整数变量的值,即存储在堆栈区域中,为 undefined .出于这个原因,打印它,一个随机值是绝对期望的。
这就是为什么,在你的输出

abc  1
4
abc Random_Value
4
1也是垃圾。
事实上,它是堆栈中的第一个位置,它的值可能会随着系统和/或编译器的不同而改变。我的 猜测 是它的值是1,因为它代表一个“ghost argc”,它是一个非常特殊的函数,即使该函数没有参数定义也存在,它的值为1。
由于 argc表示用于从命令行调用您的程序的参数数量(至少 1:可执行文件名称)有一种方法可以验证这种假设:以这种方式调用您的程序
executableName foo
这将使 argc 变为 2,因此第一个 printf 显示的值应该变成 2也是。
出于好奇,我通过在我的机器上编译您的第二个示例(在 W10 64 位操作系统下使用 gcc 编译器的 DevC++)来测试这个假设。我确认了两个说法:
  • 当发生未定义的行为时,改变环境会导致输出发生变化
  • argc存在于堆栈中并影响未初始化的局部变量的初始值

  • 执行 uninitVars.exe后的输出
    abc
    0
    abc
    1
    执行 uninitVars.exe dog后的输出
    abc
    0
    abc
    2
    执行 uninitVars.exe dog cat后的输出
    abc
    0
    abc
    3
    所以似乎我的堆栈的前四个字节总是设置为 0(它们是返回值的位置吗?),而第二个字节 实际上是 argc ,即使它没有在 main() 中明确定义原型(prototype)。

    相反,第二个打印显示不同的值,因为它是在两个 printf 之后定义的。调用,并且它们的执行在堆栈中写入几个字节(其中一些是地址,这解释了为什么值总是不同的,因为进程的地址是虚拟的并且总是不同的)。

    关于c - 'printf("%n %d", &a, a)' 定义明确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62623109/

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