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

数组类型变量作为局部变量与函数参数时,取地址结果为何不同?

数组作为函数参数时取地址的疑问

我们知道,数组类型的变量名会指向其首元素的地址,对该变量名取地址会得到相同的内存地址,但类型是数组指针。但当数组作为函数参数时,对参数里的数组变量使用&运算符得到的却是存储传入数组地址的栈地址,就像参数声明成X* x而非X x[]一样。既然数组传参本质是传递首元素地址,那为什么对函数参数中的数组变量用&运算符的行为没有被忽略?

测试程序

#include <stdio.h>

void myfunc(int arg_ia[3])
{
    int loc_ia[3] = { 1, 2, 3 };

    printf("loc_ia = %p, &loc_ia[0] = %p, &loc_ia = %p, loc_ia==&loc_ia[0] = %d, loc_ia==&loc_ia = %d\n",
           loc_ia, &loc_ia[0], &loc_ia, (void*)loc_ia == (void*)&loc_ia[0],  (void*)loc_ia == (void*)&loc_ia);

    printf("arg_ia = %p, &arg_ia[0] = %p, &arg_ia = %p, arg_ia==&arg_ia[0] = %d, arg_ia==&arg_ia = %d\n",
           arg_ia, &arg_ia[0], &arg_ia, (void*)arg_ia == (void*)&arg_ia[0], (void*)arg_ia == (void*)&arg_ia);    
}

int main(void)
{
    int mai_ia[3] = { 4, 5, 6 };

    printf("mai_ia = %p, &mai_ia[0] = %p, &mai_ia = %p, mai_ia==&mai_ia[0] = %d, mai_ia==&mai_ia = %d\n",
           mai_ia, &mai_ia[0], &mai_ia, (void*)mai_ia == (void*)&mai_ia[0], (void*)mai_ia == (void*)&mai_ia);    

    myfunc(mai_ia);
}

程序输出

mai_ia = 0x7ff7b45195bc, &mai_ia[0] = 0x7ff7b45195bc, &mai_ia = 0x7ff7b45195bc, mai_ia==&mai_ia[0] = 1, mai_ia==&mai_ia = 1
loc_ia = 0x7ff7b451958c, &loc_ia[0] = 0x7ff7b451958c, &loc_ia = 0x7ff7b451958c, loc_ia==&loc_ia[0] = 1, loc_ia==&loc_ia = 1
arg_ia = 0x7ff7b45195bc, &arg_ia[0] = 0x7ff7b45195bc, &arg_ia = 0x7ff7b4519580, arg_ia==&arg_ia[0] = 1, arg_ia==&arg_ia = 0

问题解析

核心原因是函数参数里的数组声明会被编译器自动转换成指针类型。也就是说,你写的void myfunc(int arg_ia[3])和void myfunc(int* arg_ia)完全等价,编译器会直接把前者当成后者处理。

  • 对于普通数组(比如main里的mai_ia、函数内的局部数组loc_ia),它们是真正的数组类型变量。对数组名取地址&mai_ia,得到的是指向整个数组的指针(类型为int (*)[3]),虽然它的内存地址和首元素地址&mai_ia[0]完全相同,但二者的类型不同——不过当你转换成void*比较时,地址值是相等的,所以输出里的比较结果都是1。

  • 而函数参数arg_ia本质上是一个指针变量,它存储了传入的数组首元素地址。此时对arg_ia取地址&arg_ia,得到的是这个指针变量本身在栈上的存储地址,和它指向的数组首元素地址自然不是一回事,所以输出里arg_ia==&arg_ia的结果是0。

C语言设计成这样的原因是数组无法直接作为参数传递(数组属于不可复制的类型),自动转成指针后只需要传递一个地址值,效率更高。这就导致函数参数里的“数组名”其实已经不是真正的数组了,而是一个普通的指针变量,所以对它取地址的行为和对普通指针变量取地址完全一样,不会像真正的数组那样得到和首元素相同的地址。

内容的提问来源于stack exchange,提问作者kbro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:07:42