在C语言中,我正在努力学习指针

cidc1ykv  于 2022-12-11  发布在  其他
关注(0)|答案(2)|浏览(148)

我有这段代码,我正在用它来做其他的事情,但是,我想,把它归结为根本问题。如果我在运行scanf变量时输入5,printf输出是0,16。我不明白为什么 *pScores给我16?

#include <stdio.h>

int main(void) {
  int a=0;
  int sum=0;
  scanf("%d",&a);
  int scores[a];
  int *pScores = &scores[0];
  printf("%d, %d\n",scores[0],*pScores);
}
vmdwslir

vmdwslir1#

您正在声明数组

int scores[a];

然后以两种不同的方式输出scores[0]的值。但是,您没有将任何内容存储到scores数组的任何元素中,因此那里的值是 * 不确定的 *。
是否使用未初始化(因此是不确定的)价值以这种方式实际上上升到了“未定义的行为”的水平,这是一个令人惊讶的深刻的、实际上有点争议的问题。(请参见针对另一个答案的评论帖子)不过,打印这样一个未初始化的值并没有什么特别的用处。我相信您会发现scores[0]*pScores将打印相同的值。
现在,您可能希望未初始化的值(无论它是什么)至少是一致的,无论您如何打印它(我可能同意你的观点),但是当涉及到像这样的灰色区域时,尤其是当现代编译器开始利用规则的每一个细微差别来执行积极的优化时,最终结果可能会相当令人惊讶。我得到了相同的数字打印了两次(也就是说,我最初无法重现您的结果),但正如Barmar在评论中所建议的,当我打开优化(使用-O3)时,我也开始看到相互冲突的结果。

0kjbasz6

0kjbasz62#

您有未定义的行为,这是由于阅读了一个具有自动存储持续时间的变量,而该变量的值是不确定的。
6.2.4对象的存储持续时间中,可以找到以下规则
对于具有可变长度数组类型的对象,其生存期从对象的声明开始,直到程序的执行离开声明的作用域为止。如果以递归方式进入作用域,则每次都会创建对象的一个新示例。对象的初始值是不确定的。
然后在J.2未定义的行为中:
在以下情况下,该行为未定义
...

  • 当具有自动存储持续时间的对象的值不确定时,将使用该值。

...
在处理不确定值时,一个可以允许的非常奇怪的结果是,每次你读它们时,它们都有不同的值,薛定谔波函数不会坍缩!

相关问题