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

时间:2009-06-29 08:21:16

标签: c++ c pointers matrix printf

我们有以下代码片段:

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

我不明白为什么我们在调用printf时没有收到错误/警告。我得到警告但没有错误,程序运行精细。它会打印“12printf期望类型为char *的参数,即指向char的指针。因此,如果我声明char arr[3],则arr是包含char的内存单元的地址,因此如果我用它调用printf,它将衰减到指向char 的指针,即char * 类似地,tab是包含数组的3个字符的内存单元的地址,而该字符串依次是内存单元的地址包含char,因此{{1}将衰减到tab,这应该是一个问题,因为char **期待printf

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

附录:

我得到的警告是:
char *

4 个答案:

答案 0 :(得分:6)

示例来源

#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]’

指针是指针

%s的{​​{1}}参数向函数指示它将接收指针(到字符串)。 C中的字符串只是由ASCII-Z终止的一系列字节。 printf变量是一个指针。一些编译器会发出有关指针不匹配的警告。但是,代码仍应打印出tab[2][3],因为12的代码遍历内存,从指定的内容开始(打印字符),直到找到零字节为止。 1,2,和0在内存中连续设置,从printf变量表示的地址开始。

<强>实验

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:4)

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

检查my answerthis related question了解详情。

答案 3 :(得分:1)

你似乎已经自己解释了,我看不出还有什么要说的。

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