You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 04:19:52