好的,这是相关代码:
int main(int argc, char *argv[]) {
int *v1, *v2, *v3;
printf("Enter three integers: ");
scanf("%d %d %d", v1, v2, v3);
printf("We made it this far?\n");
/* Other stuff after */
return 0;
}
当使用任意三个整数的输入时,它将成功地将这些值分配给
*v1
,*v2
,但是当尝试将第三个整数分配给v3
时,程序将超时。当我给出三个以上的整数时也会发生这种情况。我对程序进行了分段,并逐一扫描整数,在这个过程中:K */
int main(int argc, char *argv[]) {
int *v1;
int *v2;
int *v3;
printf("Enter three integers: ");
scanf("%d ", v1);
printf("%d\n", *v1);
scanf("%d ", v2);
printf("%d\n", *v2);
scanf("%d\n", v3);
printf("%d\n", *v3);
printf("We made it this far?\n");
return 0;
}
我真的看不出问题是什么。格式说明符看起来很好,问题在于无论变量名称、输入或其他任何内容。我在 VSCode 上运行,我们一次也没有进入调试打印“我们已经做到这一步了吗?”任何帮助将不胜感激!
您的代码具有未定义的行为:在
scanf("%d %d %d", v1, v2, v3);
中,您传递了3个未初始化的指针作为转换后的整数的目标。 scanf()
将读取标准输入并将数字转换为整数(以 10 为基数)并存储转换后的值,就像通过 *v1 = value
一样。仅当已使用有效 *v1
变量的地址初始化 v1
时,写入 int
才有意义。
您的代码仅因第三个变量而崩溃的原因纯粹是偶然:似乎
v1
和 v2
的初始值恰好是有效地址,并且 scanf
将从 stdin
读取的值存储到这些地址而不会崩溃存在分段错误。然而,“有效地址”并没有说明这些指针指向什么,它可以位于可写内存中的任何位置,包括保存有价值信息的位置,这些信息的修改将在以后导致可怕的后果,即使在程序完成之后也是如此。未定义的行为可能不会立即产生明显的后果,这使得调试更加困难。
C 程序员应该使用一切可用的帮助来尝试避免未定义的行为。在这种情况下,当您将未初始化变量的值传递给 scanf()
时,使用高级警告进行编译(例如:gcc -Wall -Wextra -Werror)会发现问题。
这是修改后的版本:#include <stdio.h>
int main(int argc, char *argv[]) {
int i1, i2, i3;
int *v1 = &i1, *v2 = &i2, *v3 = &i3;
printf("Enter three integers: ");
int n = scanf("%d %d %d", v1, v2, v3);
if (n == 3) {
printf("We made it this far?\n");
/* Other stuff after */
printf("%d %d %d\n", i1, i2, i3);
} else {
printf("scanf returned %d\n", n);
}
return 0;
}
请注意,惯用做法是直接将目标变量的地址传递给
scanf()
,而不是使用指针变量。您可以删除
v1
、v2and
v3` 的定义并编写: int n = scanf("%d %d %d", &i1, &i2, &i3);
始终检查
scanf()
的返回值以检测无效或丢失的输入也很重要。如果
scanf()
无法根据格式字符串转换值,它会停止读取输入流,并将有问题的字节保留在流缓冲区中,保留尚未转换的目标变量未修改(在本例中仍未初始化),并返回执行和存储的成功转换的数量,或者如果根本没有可用的输入,则返回 EOF
。在具有自动存储功能的函数的本地范围内定义的未初始化变量(与 static
存储相反),当函数进入其定义范围时,具有堆栈内存或寄存器具有的任何初始值。这些字节可能在一次运行到另一次运行、一次调用到另一台计算机、一台机器到另一台机器上有所不同......如果它们形成有效的地址,这纯粹是偶然(并且缺乏运气)。
#include <stdio.h>
int main (int argc, char *argv[]) {
int v1;
int v2;
int v3;
int *p1 = &v1;
int *p2 = &v2;
int *p3 = &v3;
printf ("Enter three integers: ");
scanf ("%d", &v1);
printf ("%d\n", *p1);
scanf ("%d", &v2);
printf ("%d\n", *p2);
scanf ("%d", &v3);
printf ("%d\n", *p3);
printf ("We made it this far?\n");
return 0;
}