关于 printf 参数的问题。 C/C++

发布于 2024-07-25 21:10:48 字数 797 浏览 4 评论 0原文

我们有以下代码片段:

char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
printf("%s\n", tab);

我不明白为什么我们在调用 printf 时没有收到错误/警告。 我确实收到了警告,但没有收到出现错误,程序运行正常。 它打印“12”。
printf 需要一个char * 类型的参数,即指向char 的指针。 因此,如果我声明了 char arr[3],那么 arr 就是包含 char 的内存单元的地址,所以如果我调用 < code>printf 加上它,它会衰减为 指向 char 的指针,即 char *
类似地,tab是包含3个字符的数组类型的内存单元的地址,反过来,内存单元的地址包含char,因此 tab 将衰减为 char **,这应该是一个问题,因为 printf 需要一个 char *< /代码>。

有人可以解释这个问题吗?

附录:

我收到的警告是:
ac:6: 警告:字符格式,不同类型 arg (arg 2)

We have the following code fragment:

char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
printf("%s\n", tab);

And I don't understand why we don't get an error / warning in the call to printf. I DO get a warning but not an error, and the program runs fine. It prints '12'.
printf is expecting an argument of type char *, i.e. a pointer to char. So if I declared char arr[3], then arr is an address of a memory unit which contains a char, so if I called printf with it, it would decay to pointer to char, i.e. char *.
Analogously, tab is an address of a memory unit that contains the type array of 3 char's which is in turn, an address of memory unit contains char, so tab will decay to char **, and it should be a problem, since printf is expecting a char *.

Can someone explain this issue?

Addendum:

The warning I get is:
a.c:6: warning: char format, different type arg (arg 2)

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

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

发布评论

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

评论(4

终陌 2024-08-01 21:10:48

示例源代码

#include <stdio.h>

int main( void ) {
  char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
  printf("%s\n", tab);

  return 0;
}

编译警告

$ gcc test.c
test.c: In function ‘main’:
test.c:5: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[3]’

指针就是指针

printf%s 参数表示该函数将接收一个指针(指向一个字符串)。 在 C 语言中,字符串仅仅是一系列以 ASCII-Z 结尾的字节。 tab[2][3] 变量是一个指针。 有些编译器会发出有关指针不匹配的警告。 但是,代码仍应打印出 12,因为 printf 的代码从给定的指针开始遍历内存(按顺序打印字符),直到找到零字节。 1、2 和 \0 在内存中连续设置,从 tab 变量表示的地址开始。

实验

作为一个实验,当您编译并运行以下代码时会发生什么:

#include <stdio.h>

int main( void ) {
  char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
  printf("%s\n", tab[1]);

  return 0;
}

不要害怕实验。 看看你是否能根据你现在所知道的得出答案。 现在(根据实验)您将如何引用 tab 来消除警告并仍然显示 12

Example Source

#include <stdio.h>

int main( void ) {
  char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
  printf("%s\n", tab);

  return 0;
}

Compile Warning

$ gcc test.c
test.c: In function ‘main’:
test.c:5: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[3]’

Pointers are Pointers

The %s argument to printf indicates to the function that it will be receiving a pointer (to a string). A string, in C, is merely a series of bytes terminated by an ASCII-Z. The tab[2][3] variable is a pointer. Some compilers will issue a warning about the pointer mismatch. However, the code should still print out 12 because printf's code traverses memory starting at the pointer it was given (printing characters as it goes) until it finds a zero byte. The 1, 2, and \0 are contiguously set in memory, starting at the address represented by the tab variable.

Experiment

As an experiment, what happens when you compile and run the following code:

#include <stdio.h>

int main( void ) {
  char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
  printf("%s\n", tab[1]);

  return 0;
}

Don't be afraid of experimenting. See if you can come up with the answer based on what you now know. How would you reference tab now (in light of the experiment) to get rid of the warning and still display 12?

暮色兮凉城 2024-08-01 21:10:48

tab 参数与 printf() 调用中的省略号匹配。 C 和 C++ 编译器没有义务检查此类参数。

The tab parameter matches the elipsis in the printf() call. C and C++ compilers are undfer no obligation to check such parameters.

骷髅 2024-08-01 21:10:48

您关于 tab 将衰减为 char ** 的假设是错误的:tab 的类型为 char [2][3],即它将衰减为 char (*) [3]。 重要的是要理解,尽管数组和指针的行为通常很相似,但它们并不是同一件事。 printf() 需要一个 char *,因此它采用 char (*) [3] 的位并相应地解释它们。 尽管它适用于您的平台,但 C 标准并不保证这一点:两个指针都引用相同的内存位置,但它们的表示形式不必相同。

检查我对此相关问题了解详细信息。

Your assumption that tab will decay to char ** is wrong: tab has type char [2][3], ie it will decay to char (*) [3]. It's important to understand that although arrays and pointers often behave alike, they are not the same thing. printf() expects a char *, so it takes the bits of the char (*) [3] and interprets them accordingly. Although it works on your platform, the C standard doesn't guarantee this: both pointers reference the same memory location, but their representation need not be identical.

Check my answer to this related question for details.

往日情怀 2024-08-01 21:10:48

你自己好像已经解释过了,我不知道还有什么可说的。

tab 是两个 char * 的数组。 tab 的每个元素都是 printf 可以接受的字符串,但 tab 本身是不可接受的,因为它是一个指向字符。

You seem to have explained it yourself, I don't see what's left to say.

tab is an array of two char *'s. Each element of tab is a string that printf can accept, but tab itself is not acceptable, since it is a pointer to a pointer to a char.

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