C语言、数组、指针

发布于 2024-09-25 11:27:14 字数 643 浏览 7 评论 0原文

int main()
{
    int j=97;
    char arr[4]="Abc";
    printf(arr,j);
    getch();
    return 0;
}

这段代码给了我一个堆栈溢出错误,为什么? 但是,如果我们使用 printf(arr) 而不是 printf(arr,j),那么它会打印 Abc。 请告诉我 printf 是如何工作的,意味着第一个参数是 const char* 类型,那么 arr 是如何的 由编译器处理。 对不起!上面的代码是正确的,它没有给出任何错误,我错误地写了这个。但下面的代码给出了堆栈溢出错误。

#include <stdio.h>
int main()
    {
       int i, a[i];
       getch();
       return 0;
    }

由于变量我采用任何垃圾值,因此这将是数组的大小 那么为什么当我使用 DEV C++ 并且使用 TURBO C++ 3.0 时此代码会出现此错误 错误:显示所需的常量表达式。如果数组的大小不能可变,那么当 我们通过用户输入获取数组的大小。不会显示错误。但为什么在这种情况下。

int main()
{
    int j=97;
    char arr[4]="Abc";
    printf(arr,j);
    getch();
    return 0;
}

this code gives me a stack overflow error why?
But if instead of printf(arr,j) we use printf(arr) then it prints Abc.
please tell me how printf works , means 1st argument is const char* type so how arr is
treated by compiler.
sorry! above code is right it doesn't give any error,I write this by mistake. but below code give stack overflow error.

#include <stdio.h>
int main()
    {
       int i, a[i];
       getch();
       return 0;
    }

since variable i take any garbage value so that will be the size of the array
so why this code give this error when i use DEV C++ and if I use TURBO C++ 3.0 then
error:constant expression required displayed. if size of array can't be variable then when
we take size of array through user input.no error is displayed. but why in this case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

空心↖ 2024-10-02 11:27:14

请告诉我 printf 是如何工作的

首先,仅将非用户提供或验证的字符串传递给 printf() 的第一个参数!

printf() 在必需的 const char* 参数之后接受可变数量的参数(因为 printf() 就是所谓的可变参数函数)。第一个 const char* 参数是传递 格式字符串 以便 printf() 知道如何显示其余参数。

如果 arr 字符数组包含用户输入的值,那么如果字符串恰好包含这些格式化占位符,则可能会导致段错误,因此格式字符串应始终是硬编码常量(或经过验证)细绳。您的代码示例非常简单,可以看出它确实是一个常量,但是习惯于 printf("%s", arr) 显示字符串而不是直接将它们传递给第一个仍然是很好的做法争论(当然除非你绝对必须这样做)。

也就是说,您可以使用格式化占位符(以 % 开头的占位符)来格式化输出。如果你想显示:

ABC 97

那么你对 printf() 的调用应该是:

printf("%s %d", arr, j);

%s 告诉 printf() 第二个参数应该被解释为指针到一个以 null 结尾的字符串。 %d 告诉 printf() 第三个参数应被解释为带符号的十进制。

这段代码给我一个堆栈溢出错误,为什么?

查看 AndreyT 的回答。

please tell me how printf works

First of all, pass only non-user supplied or validated strings to the first argument of printf()!

printf() accepts a variable number of arguments after the required const char* argument (because printf() is what's called a variadic function). The first const char* argument is where you pass a format string so that printf() knows how to display the rest of your arguments.

If the arr character array contains user-inputted values, then it may cause a segfault if the string happens to contain those formatting placeholders, so the format string should always be a hard-coded constant (or validated) string. Your code sample is simple enough to see that it's really a constant, but it's still good practice to get used to printf("%s", arr) to display strings instead of passing them directly to the first argument (unless you absolutely have to of course).

That being said, you use the formatting placeholders (those that start with %) to format the output. If you want to display:

Abc 97

Then your call to printf() should be:

printf("%s %d", arr, j);

The %s tells printf() that the second argument should be interpreted as a pointer to a null-terminated string. The %d tells printf() that the third argument should be interpreted as a signed decimal.

this code gives me a stack overflow error why?

See AndreyT's answer.

樱桃奶球 2024-10-02 11:27:14

我看到现在OP将行为的描述更改为完全不同的东西,所以我的解释不再适用于他的代码。尽管如此,我关于可变参数函数的观点仍然成立。

此代码会导致堆栈无效(或类似的情况),因为您未能声明函数printf。 printf 是一个所谓的可变函数,它接受可变数量的参数。在 C 语言中,[几乎]总是强制在调用可变参数函数之前声明它们。此要求的实际原因是可变参数函数可能(并且通常会)需要某种特殊的方法来传递参数。它通常被称为调用约定。如果在调用可变参数函数之前忘记声明它,C99 之前的编译器将假定它是普通的非可变参数函数,并将其作为普通函数调用。即它将使用错误的调用约定,进而导致堆栈失效。这一切都取决于实现:有些甚至可能看起来“工作”正常,有些会崩溃。但无论如何,您绝对必须在调用可变参数函数之前声明它们。

在这种情况下,您应该在调用 printf 之前包含 。头文件是一个标准头文件,其中包含printf的声明。你忘了做;因此出现错误(最有可能)。没有办法 100% 确定,因为这取决于实现。

否则,您的代码是有效的。代码很奇怪,因为您将 j 传递给 printf 而不为其提供格式说明符,但这不是一个错误 - printf 只是忽略额外的可变参数。无论如何,您的代码都应该打印 Abc。在代码开头添加 #include ,它应该可以正常工作,假设它执行了您希望它执行的操作。

同样,这段代码

#include <stdio.h>

int main()
{
    int j=97;
    char arr[4]="Abc";
    printf(arr,j);
    return 0;
}

是一个奇怪但完全有效的 C 程序,具有完美定义的输出(不过在输出末尾添加 \n 是个好主意)。

I see that now the OP changed the description of the behavior to something totally different, so my explanation no longer applies to his code. Nevertheless, the points I made about variadic functions still stand.

This code results in stack invalidation (or something similar) because you failed to declare function printf. printf is a so called variadic function, it takes variable number of arguments. In C language it has [almost] always been mandatory to declare variadic functions before calling them. The practical reason for this requirement is that variadic functions might (and often will) require some special approach for argument passing. It is often called a calling convention. If you forget to declare a variadic function before calling it, a pre-C99 compiler will assume that it is an ordinary non-variadic function and call it as an ordinary function. I.e. it will use a wrong calling convention, which in turn will lead to stack invalidation. This all depends on the implementation: some might even appear to "work" fine, some will crash. But in any case you absolutely have to declare variadic functions before calling them.

In this case you should include <stdio.h> before calling printf. Header file <stdio.h> is a standard header that contains the declaration of printf. You forgot to do it; hence the error (most likely). There's no way to be 100% sure, since it depends on the implementation.

Otherwise, your code is valid. The code is weird, since you are passing j to printf without supplying a format specifier for it, but it is not an error - printf simply ignores extra variadic arguments. Your code should print Abc in any case. Add #include <stdio.h> at the beginning of your code, and it should work fine, assuming it does what you wanted it to do.

Again, this code

#include <stdio.h>

int main()
{
    int j=97;
    char arr[4]="Abc";
    printf(arr,j);
    return 0;
}

is a strange, but perfectly valid C program with a perfectly defined output (adding \n at the end of the output would be a good idea though).

猥琐帝 2024-10-02 11:27:14

在错误代码的更正示例中的 int i, a[i]; 行中,ai 元素的可变长度数组,但 i 未初始化。因此你的程序有未定义的行为。

In your line int i, a[i]; in the corrected sample of broken code, a is a variable-length array of i elements, but i is uninitialized. Thus your program has undefined behavior.

暖伴 2024-10-02 11:27:14

你可以看到C语言中的字符串被视为char*,而printf函数可以直接打印字符串。要使用此函数打印字符串,您应该使用以下代码:

printf("%s", arr);

%s 告诉函数第一个变量将是 char*

如果您想同时打印 arr 和 j,您应该首先定义格式:

printf("%s%d", arr, j);

%d 告诉函数第二个变量将是 int

You see strings in C language are treated as char* and printf function can print a string directly. For printing strings using this function you should use such code:

printf("%s", arr);

%s tells the function that the first variable will be char*.

If you want to print both arr and j you should define the format first:

printf("%s%d", arr, j);

%d tells the function that the second variable will be int

拍不死你 2024-10-02 11:27:14

我怀疑 printf() 问题是一个转移注意力的问题,因为以 null 结尾的 "Abc" 将忽略其他参数。

你的程序调试好了吗?如果不是,你能确定故障不在 getch() 中吗?
我无法重复您的问题,但为了简单起见,我注释掉了 getch()

顺便说一句,为什么你不使用 fgetc()getchar() ?您打算在更大的程序中使用curses吗?

===== 编辑后添加=====

好吧,这不是转移注意力,只是OP的一个错误。

C++ 确实允许分配由变量指定大小的数组;正如您推断的那样,您基本上是使用随机(垃圾)大小完成此操作并溢出堆栈。当您使用 C++ 进行编译时,您通常不再编译 C 并且规则会发生变化(取决于特定的编译器)。

也就是说,我不明白你的问题 - 你需要更清楚地了解“当我们通过用户输入获取数组大小”......

I suspect the printf() issue is a red herring, since with a null-terminated "Abc" will ignore other arguments.

Have you debugged your program? If not can you be sure the fault isn't in getch()?
I cannot duplicate your issue but then I commented out the getch() for simplicity.

BTW, why did you not use fgetc() or getchar()? Are you intending to use curses in a larger program?

===== Added after your edit =====

Okay, not a red herring, just a mistake by the OP.

C++ does allow allocating an array with the size specified by a variable; you've essentially done this with random (garbage) size and overflowed the stack, as you deduced. When you compile with C++ you are typically no longer compiling C and the rules change (depending on the particular compiler).

That said, I don't understand your question - you need to be a lot more clear with "when we take size of array through user input" ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文