C语言二维数组函数传参时数组衰减(array decay)的选择性现象疑问
C语言二维数组传参时的数组衰减解析
你的核心疑问在于:为什么printArray函数中sizeof(B[0])得到12字节,而不是和sizeof(B)一样的4字节?这要从C语言数组衰减的规则和二维数组的本质说起:
函数参数的数组声明会被隐式转换为指针
C语言的函数参数里,数组类型的声明永远会被调整为指向数组首元素的指针。你写的void printArray(int B[][3]),实际等价于:
void printArray(int (*B)[3])
这里的B是一个指向int[3]类型数组的指针,而非二维数组。所以sizeof(B)计算的是指针的大小(你的环境是32位,所以是4字节),这符合你看到的结果。
二维数组是“数组的数组”,传参时仅最外层衰减
int B[2][3]本质是一个包含2个元素的数组,每个元素都是int[3]类型的一维数组。当你把它传给函数时,只有最外层的数组会发生衰减:从int[2][3]衰减为指向第一个元素(即int[3]数组)的指针int (*)[3],内层的一维数组并没有被直接衰减。
B[0]在函数中的实际含义
在printArray里,B是int (*B)[3]指针。B[0]等价于*(B + 0)——对指针解引用后,得到的是int[3]类型的数组(尽管它是通过指针访问的,但类型依然是数组)。而sizeof运算符作用于数组类型时,不会触发数组衰减,它会直接计算整个数组的大小:3个int,每个4字节,总计12字节,这就是你看到的结果。
对比main函数中的情况验证
main里的B是真正的int[2][3]数组,sizeof(B)计算整个二维数组的总大小:2*3*4=24字节,这是因为sizeof作用于数组本身,不触发衰减。main里的B[0]是int[3]数组,sizeof(B[0])计算一维数组的大小:3*4=12字节,和函数里的结果一致,因为两者的操作数都是int[3]数组类型。
数组衰减的触发规则总结
数组衰减仅在表达式中使用数组名,且不属于以下例外场景时发生:
- 使用
sizeof(数组名)获取数组大小 - 使用
&数组名获取数组的地址(而非首元素地址) - 用字符串字面量初始化字符数组(如
char str[] = "hello")
对于多维数组,只有最外层数组会在传参时衰减;如果要让内层数组也衰减,需要对其进行额外操作(比如把B[0]传给另一个函数,此时它会衰减为int*)。
你的代码及运行结果回顾
代码:
#include<stdio.h> void printArray(int B[][3]) { printf("sizeof(B) is : %u\n", sizeof(B)); printf("sizeof(B[0]) is : %u\n", sizeof(B[0])); } int main(int argc, char* argv[]) { int B[2][3] = { {2,3,6},{4,5,8} }; printf("sizeof(B) is : %u\n", sizeof(B)); printf("sizeof(B[0]) is : %u\n", sizeof(B[0])); printArray(B); return 0; }
运行结果:
sizeof(B) is : 24 sizeof(B[0]) is : 12 sizeof(B) is : 4 sizeof(B[0]) is : 12
内容的提问来源于stack exchange,提问作者Sotiris
相关产品推荐
相关产品推荐

