变量的声明如何表现?

时间:2011-12-15 20:43:57

标签: c variables memory variable-assignment declaration

#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 变量和 x 指针在 i 变量之前。 我知道那些最后的声明没有意义, int i 而不是 char i ,以及一个甚至不需要的添加指针。 但这是偶然发生的,我想知道这是不是巧合。

2 个答案:

答案 0 :(得分:1)

该函数需要一系列引用作为附加参数,每个参数指向由格式字符串中相应的%-tag指定的类型的对象,顺序相同。阅读scanf

这些还可以帮助您:

I don't understand why I can't get three inputs in c

scanf() leaves the new line char in buffer?

关于问题的最后部分,int的位数始终大于char,因此不会导致问题。

答案 1 :(得分:1)

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

现在,如果你这样做:

int i;
scanf("%c", &i);
那时你做错了什么。 scanf格式的"%i"需要char*参数,该参数指向将存储值的char对象。你给的是int*而不是char*。结果,你的程序的行为是不确定的;语言标准没有说明它将如何表现。

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

现在打印i的值:

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

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

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

这里的教训是,C倾向于认为你知道自己在做什么。有一个 lot 的构造具有未定义的行为,这意味着它们无效,但是编译器和运行时系统都不需要告诉您存在问题。在C语言中,比大多数其他语言更重要的是,作为一名程序员,你要把事情弄清楚。编译器(和其他工具)会告诉你一些错误,但不是所有错误。

如果存在未定义的行为,您声明变量的顺序可以有所不同。例如,如果您编写的代码读取或写入变量的末尾,那么存储在那里的情况就很重要了。但是,在程序运行之前,不要试图改变你的声明。摆脱未定义的行为,因此订单重要。

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

命名约定可能会有所帮助。如果您调用了char变量cint变量i,而不是反之亦然,那么跟踪哪个变量就更容易了。< / p>

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

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