关于 printf 参数的问题。 C/C++
我们有以下代码片段:
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 I DO get a warning but not an error, and the program runs fine. It prints 'printf
.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
示例源代码
编译警告
指针就是指针
printf
的%s
参数表示该函数将接收一个指针(指向一个字符串)。 在 C 语言中,字符串仅仅是一系列以 ASCII-Z 结尾的字节。tab[2][3]
变量是一个指针。 有些编译器会发出有关指针不匹配的警告。 但是,代码仍应打印出12
,因为printf
的代码从给定的指针开始遍历内存(按顺序打印字符),直到找到零字节。 1、2 和 \0 在内存中连续设置,从tab
变量表示的地址开始。实验
作为一个实验,当您编译并运行以下代码时会发生什么:
不要害怕实验。 看看你是否能根据你现在所知道的得出答案。 现在(根据实验)您将如何引用
tab
来消除警告并仍然显示12
?Example Source
Compile Warning
Pointers are Pointers
The
%s
argument toprintf
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. Thetab[2][3]
variable is a pointer. Some compilers will issue a warning about the pointer mismatch. However, the code should still print out12
becauseprintf
'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 thetab
variable.Experiment
As an experiment, what happens when you compile and run the following code:
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 display12
?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.
您关于
tab
将衰减为char **
的假设是错误的:tab
的类型为char [2][3]
,即它将衰减为char (*) [3]
。 重要的是要理解,尽管数组和指针的行为通常很相似,但它们并不是同一件事。printf()
需要一个char *
,因此它采用char (*) [3]
的位并相应地解释它们。 尽管它适用于您的平台,但 C 标准并不保证这一点:两个指针都引用相同的内存位置,但它们的表示形式不必相同。检查我对此相关问题了解详细信息。
Your assumption that
tab
will decay tochar **
is wrong:tab
has typechar [2][3]
, ie it will decay tochar (*) [3]
. It's important to understand that although arrays and pointers often behave alike, they are not the same thing.printf()
expects achar *
, so it takes the bits of thechar (*) [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.
你自己好像已经解释过了,我不知道还有什么可说的。
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 twochar *
's. Each element oftab
is a string thatprintf
can accept, buttab
itself is not acceptable, since it is a pointer to a pointer to a char.