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

Ori*_*ski 4 c c++ printf pointers matrix

我们有以下代码片段:

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

我不明白为什么我们在通话中没有收到错误/警告printf.我收到警告但没有错误,程序运行正常.它打印' 12'.
printf期待一个类型的参数char *,即指向char.所以,如果我声明char arr[3],那么arr是一个包含a的内存单元的地址char,所以如果我printf用它调用它会衰减指向char,即char *.
类似地,tab是包含3个字符的类型数组的存储器单元的地址,而存储器单元的地址包含char,因此tab将衰减char **,并且它应该是一个问题,因为printf期望a char *.

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

附录:

我得到的警告是:
a.c:6: warning: char format, different type arg (arg 2)

Dav*_*vis 6

示例来源

#include <stdio.h>

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

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译警告

$ 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到参数printf指示它将被接收的指针(为字符串)的功能.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;
}
Run Code Online (Sandbox Code Playgroud)

不要害怕尝试.看看你是否可以根据你现在所知道的答案得出答案.你tab现在如何(根据实验)提到摆脱警告并仍然显示12