int main()
{
int j=97;
char arr[4]="Abc";
printf(arr,j);
getch();
return 0;
}
这段代码给我一个堆栈溢出错误的原因?
但是如果我们使用printf(arr,j)
代替printf(arr)
,那么它会输出Abc。
请告诉我printf
如何工作,意味着第一个参数是const char*
类型,所以arr是多少
由编译器处理。
抱歉!上面的代码是对的,它没有给出任何错误,我写错了。但是下面的代码会给出堆栈溢出错误。
#include <stdio.h>
int main()
{
int i, a[i];
getch();
return 0;
}
因为变量i采用任何垃圾值,所以这将是数组的大小 那么为什么这个代码在我使用DEV C ++时会出现这个错误,如果我使用TURBO C ++ 3.0呢 错误:显示所需的常量表达式。如果数组的大小不能变化那么 我们通过用户输入获取数组大小。显示错误。但为什么在这种情况下。
答案 0 :(得分:3)
请告诉我printf的工作原理
首先,仅将非用户提供或验证的字符串传递给printf()
的第一个参数!
printf()
在所需的const char*
参数之后接受可变数量的参数(因为printf()
是所谓的可变参数函数)。第一个const char*
参数是您传递format string的位置,以便printf()
知道如何显示其余参数。
如果arr
字符数组包含用户输入的值,那么如果字符串恰好包含那些格式化占位符,则可能会导致段错误,因此格式字符串应始终为硬编码常量(或经过验证)串。你的代码示例非常简单,可以看到它确实是一个常量,但是习惯printf("%s", arr)
来显示字符串而不是直接将它们传递给第一个参数仍然是一种好习惯(除非你绝对必须这样做)。
话虽如此,您使用格式化占位符(以%
开头的那些)来格式化输出。如果要显示:
Abc 97
然后您对printf()
的致电应该是:
printf("%s %d", arr, j);
%s
告诉printf()
第二个参数应该被解释为指向以null结尾的字符串的指针。 %d
告诉printf()
第三个参数应该被解释为带符号的小数。
这段代码给我一个堆栈溢出错误原因?
答案 1 :(得分:3)
我看到OP现在将行为的描述改为完全不同的东西,所以我的解释不再适用于他的代码。尽管如此,我对可变函数的观点仍然存在。
此代码导致堆栈失效(或类似的东西),因为您未能声明函数printf
。 printf
是一个所谓的可变参数函数,它需要可变数量的参数。在C语言中,它几乎总是必须在调用它们之前声明可变参数函数。这个要求的实际原因是可变函数可能(并且经常会)需要一些特殊的方法来传递参数。它通常被称为一个调用约定。如果您在调用之前忘记声明一个可变参数函数,那么前C99编译器将假定它是一个普通的非变量函数并将其称为普通函数。即它将使用错误的调用约定,这反过来将导致堆栈失效。这一切都取决于实施:有些可能看起来“工作”很好,有些会崩溃。但无论如何你绝对 在调用它们之前声明了可变参数函数。
在这种情况下,您应在调用<stdio.h>
之前加入printf
。头文件<stdio.h>
是包含printf
声明的标准头文件。你忘了这样做;因此错误(最有可能)。没有办法百分百肯定,因为它取决于实施。
否则,您的代码有效。代码很奇怪,因为你将j
传递给printf
而没有为它提供格式说明符,但它不是错误 - printf
只是忽略了额外的可变参数。在任何情况下,您的代码都应打印Abc
。在代码的开头添加#include <stdio.h>
,它应该可以正常工作,假设它符合您的要求。
再次,这段代码
#include <stdio.h>
int main()
{
int j=97;
char arr[4]="Abc";
printf(arr,j);
return 0;
}
是一个奇怪但完全有效的C程序,具有完美定义的输出(在输出的末尾添加\n
将是一个好主意)。
答案 2 :(得分:1)
在更正后的代码示例中的int i, a[i];
行中,a
是i
元素的可变长度数组,但i
未初始化。因此,您的程序具有未定义的行为。
答案 3 :(得分:0)
我怀疑 printf()问题是一个红色的鲱鱼,因为使用以空值终止的“Abc”会忽略其他参数。
你调试了你的程序吗?如果没有,你能否确定故障不在 getch()? 我无法复制您的问题,但为了简单起见,我注释掉了 getch()。
顺便说一句,你为什么不使用 fgetc()或 getchar()?您打算在更大的程序中使用 curses 吗?=====编辑后添加=====
好吧,不是红鲱鱼,只是OP的错误。
C ++允许分配一个变量指定大小的数组;你基本上用随机(垃圾)大小完成了这个并且溢出了堆栈,正如你推断的那样。使用C ++编译时,通常不再编译C并且规则会更改(取决于特定的编译器)。
那就是说,我不明白你的问题 - 当我们通过用户输入获取数组大小时,你需要更清楚“”...
答案 4 :(得分:0)
您会看到C语言中的字符串被视为char*
,而printf
函数可以直接打印字符串。要使用此功能打印字符串,您应该使用以下代码:
printf("%s", arr);
%s告诉函数第一个变量是char*
。
如果要同时打印arr和j,则应首先定义格式:
printf("%s%d", arr, j);
%d告诉函数第二个变量是int