C语言char (*)[length]指针声明与printf类型不匹配警告疑问
问题解答
核心误解点
你对第10行声明的理解错误是混淆了数组指针和指针数组的声明语法:
C语言的声明遵循优先级规则:
- 没有括号时,
[]的优先级高于*,所以char *name_ptr[11]才是你以为的「长度为11的char*数组」(即指针数组) - 第10行的声明加了括号,
*先和name_ptr结合,说明name_ptr是一个指针,再和后面的[NAME_LEN+1]结合,说明这个指针指向的是长度为11的char数组,也就是编译器警告里提到的char (*)[11]类型,这类指针也叫数组指针。
代码运行逻辑说明
逐行拆解逻辑:
- 第8行:定义长度为11的char数组
name,语法合法 - 第9行:将字符串
"Hi"拷贝到name数组中,"Hi"总长度仅为3(包含结束符\0),远小于数组长度,无溢出问题 - 第10行:声明数组指针
name_ptr,赋值为&name(即数组name的首地址),二者类型完全匹配,所以编译器不会在这一行报错 - 第12-14行的printf调用:
- 第一个
%s对应参数name:数组名在传参时会自动退化为指向首元素的char*指针,和%s的要求完全匹配,输出正常 - 第二个
%s对应参数name_ptr:name_ptr的类型是char (*)[11],和%s要求的char*不匹配,所以触发编译警告。但由于C语言中数组首元素的地址和整个数组的地址数值上完全相同,所以运行时传入的地址值刚好是"Hi"的首地址,看起来输出正常,但这属于未定义行为,实际开发中绝对不能依赖这种写法。
- 第一个
容易混淆的声明对比
char *arr[11]:指针数组,arr是数组,共11个元素,每个元素的类型是char*char (*arr)[11]:数组指针,arr是指针,指向一个包含11个char元素的数组
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

