C语言中两种数组传递方式的区别:传数组名vs传数组地址
两种C语言数组传递方式的差异解析
先明确两种传递方式的核心区别,以及你对void**的误解:
1. 传递的指针类型与含义完全不同
第一种方式:func(arr, N)
在C语言的绝大多数语境下,数组名会隐式转换为指向数组首元素的指针。这里传递的是arr[0]的地址,原类型为char*,随后被隐式转换为函数参数要求的void*。
第二种方式:func(&arr, N)
&arr取的是整个数组的地址,它的原类型是char(*)[N](指向长度为N的char数组的指针),同样被隐式转换为void*传递给函数。
2. 地址数值相同,但类型决定指针运算逻辑
虽然在绝大多数系统中,数组首元素的地址和数组本身的地址数值完全一致,但二者的类型差异会直接影响指针运算:
- 若将第一种传递的指针转回
char*,执行+1操作会移动1个字节(指向arr[1]); - 若将第二种传递的指针转回
char(*)[N],执行+1操作会直接跳过整个N字节的数组,指向原数组之后的内存位置。
3. 关于void**的误解纠正
你认为第二种方式是传递void**是错误的:void**是指向void*类型的指针,而&arr的类型是指向数组的指针,二者属于完全不同的指针类别。之所以能传递给void*参数,是因为C语言允许任何对象指针隐式转换为void*,但这并不代表它的本质是void**。
函数内的使用差异
如果函数func需要还原指针类型操作数组:
- 第一种传递方式,需将
void*转回char*,直接通过buf[i]访问元素; - 第二种传递方式,需先转回
char(*)[N],再通过(*buf)[i]访问元素,或者进一步转换为char*(比如*(char(*)[N])buf也能得到首元素地址)。
内容的提问来源于stack exchange,提问作者k1r1t0
相关产品推荐
相关产品推荐

