gpt4 book ai didi

c - 变量声明的行为如何?

转载 作者:行者123 更新时间:2023-11-30 14:26:48 25 4
gpt4 key购买 nike

#include<stdio.h>
#include<conio.h>

int main(){

char i;
int c;

scanf("%i",&c);
scanf("%c",&i);// catch the new line or character introduced before x number
printf("%i",i);// value of that character

getch();
return(0);
}

程序将以与下一个变量声明(而不是上面的变量声明)相同的方式运行:

这个:

int c;
int *x;
int i;

或者这个:

int *x;
int c;
int i;

只有这样:c变量和i变量之前的x指针。我知道最后的声明没有意义,用 int i 而不是 char i,并且添加了一个甚至不需要的指针。但这是偶然发生的,我想知道这是否只是巧合。

最佳答案

假设代码的其余部分没有任何问题,声明变量的顺序应该没有任何区别。声明的顺序不需要与它们在内存中的布局方式有任何关系。即使确实如此,您也可以通过名称来引用变量;只要您的代码正确,对 i 的引用就是对 i 的引用,编译器将生成正确访问该变量所需的任何代码。

现在如果你这样做:

int i;
scanf("%c", &i);

那么你做错了什么。具有 "%i" 格式的 scanf 需要一个 char* 参数,该参数指向要写入的 char 对象该值将被存储。您给它的是 int* 而不是 char*。因此,你的程序的行为是未定义的;语言标准没有说明它的行为方式。

那么为什么它看起来工作正常呢?可能发生的情况是 scanfint 对象 i 的地址视为指向 char 的指针>。它可能会指向i表示的第一个字节;例如,i 可能是 32 位,指针将指向这些位的前 8 位。 (它们可能是高位或低位,具体取决于系统。)

现在,当您打印 i 的值时:

printf("%d\n", i);

i 的内容例如是 1 个字节,由您刚刚读入的任何字符组成,以及 3 个字节的垃圾。这 3 个垃圾字节很可能全部为零,但它们可以是任何东西。如果垃圾字节恰好为 0,并且第一个字节恰好是高位字节(即,您在 big-endian 机器上),那么您可能会得到“正确”的输出。

但不要这样做。由于行为未定义,因此它可以“正确”工作多年,然后在最糟糕的时刻彻底失败。

这里的教训是,C 倾向于假设你知道自己在做什么。有很多构造具有未定义的行为,这意味着它们无效,但编译器和运行时系统都不需要告诉您存在问题。与大多数其他语言相比,C 语言更需要程序员将事情做好。编译器(和其他工具)会告诉您一些错误,但不是全部。

在存在未定义行为的情况下,声明变量的顺序可能会产生影响。例如,如果您编写的代码读取或写入超过变量的末尾,那么那里存储的内容可能很重要。但是,在程序运行之前,不要试图随意更改声明。摆脱未定义的行为,因此顺序并不重要。

解决方案:首先不要犯错误。 (当然,说起来容易做起来难。)

命名约定会很有帮助。如果您将 char 变量称为 c,并将 int 变量称为 i,而不是反之亦然,那么它会更容易跟踪哪个是哪个。

但是 c 是用于保存输入字符值的 int 变量的合理名称 - 不是用于 scanf,而是用于 >getchar(),如:

int c;
while ((c = getchar()) != EOF) {
/* ... */
}

关于c - 变量声明的行为如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8526334/

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