为什么数组类型变量的地址在局部变量和函数参数时不同?

问题描述 投票:0回答:1

我们从小就被教导,数组类型变量的名称会产生它的第零个元素的地址,并且获取该名称的地址会产生相同的地址,但具有不同的指针类型(整个变量的类型)数组而不是单个元素的类型)。但是,如果数组类型变量是函数参数,则情况并非如此。在这种情况下,当存储传入数组的地址时,“&”生成堆栈上的地址,就好像参数被声明为“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

谢谢你。

arrays c function arguments
1个回答
0
投票

简单来说,数组不能作为函数的参数。

任何定义为采用数组作为参数的函数实际上都采用指针。 C 标准的第 6.7.6.3p7 节规定了以下有关函数参数的内容:

将参数声明为“类型数组”应调整为 “指向类型的限定指针”,其中类型限定符(如果有)是 在数组类型派生的

[
]
中指定的那些。如果 关键字
static
也出现在数组类型的
[
]
中 推导,然后对于每次调用该函数, 相应的实际参数应提供对第一个参数的访问 数组的元素至少具有指定的元素数 尺寸表达

这意味着你的函数声明如下:

void myfunc(int arg_ia[3]) {

完全等同于:

void myfunc(int *arg_ia) {

所以当你像这样调用函数时:

myfunc(mai_ia);

它收到了数组第一个元素的地址。

事实上,您可以更改函数以获取数组的地址:

void myfunc(int (arg_ia*)[3]) {

可以这样调用:

myfunc(&mai_ia);

在这种情况下,函数中

arg_ia
的值将是main中数组
mai_ia
的地址(与其第一个元素的地址相同)。

© www.soinside.com 2019 - 2024. All rights reserved.