将数组地址作为函数参数传递

时间:2011-07-11 02:15:23

标签: c

最近,我正在调试我的一个程序并发现了一个我经常犯的错误,但在编译过程中没有显示为警告,所以我只是假设一切都已就绪并且没问题。我对以下代码中发生的事情感到困惑:

void foo(char b[2]);
char a[2] = {1, 2};
foo(a);   // I always assumed that this would pass the entire array to be
          // duplicate in stack, guess I was wrong all this while
          // Instead the address of the array was passed

void foo(char b[2])
{
   // Value of b[0], b[1]?
   // Does this mean :   1) b[0] == &a[0]?
   //                or  2) b[0] == &a[0+2]?
   // Compiler didn't complain, so I assume this is a valid syntax
}

6 个答案:

答案 0 :(得分:6)

当您将数组作为参数传递给函数时,它会衰减为指针,这在6.7.1中的C标准中定义:

  

在进入函数时,每个参数表达式的值应转换为类型   它的相应参数,就像通过赋值给参数一样。 数组表达式和   函数指示符作为参数在调用之前被转换为指针。宣言   “类型数组”的参数应调整为“指向类型的指针,

这实质上意味着在你的函数声明中它等同于使用

void foo(char b[2]);void foo(char b[]);void foo(char *b)

`

答案 1 :(得分:0)

这是有效的语法,是的,当传递数组时,第一个元素的内存地址被复制,但是当你取消引用地址时,你正在修改原始数组。

答案 2 :(得分:0)

这与以下内容相同:

// The array "char b[2]" "decays" to a pointer "char *b"
void foo(char *b)
{
    // b[0] == a[0]
    // also, b == a (two addresses, both the same)
}

您可以了解C中的数组和指针的行为方式非常相似(但 完全相同)。如果它们是函数参数(但不是其他任何地方),则数组会衰减为指针。这里真正的问题是在64位系统上sizeof(b) == 8sizeof(a) == 2,除非你知道数组衰减为指针,否则这有点令人惊讶。

答案 3 :(得分:0)

  1. 将数组声明为函数参数时,会将其视为指针。您的foo

    完全相同
    void foo(char *b)
    {
        ...
    }
    
  2. 数组衰减到指针。换句话说,在某些用途中(例如sizeof(a)a是一个数组,但在其他需要指针的地方,名称a 表示地址a[0]

答案 4 :(得分:0)

如果您将b[0] = &a[0]作为参数,则

foo(a)

如果您通过foo((a+1))然后b[0] = &a[1](您不应该这样做,因为b[1]未定义)等等。

答案 5 :(得分:0)

我应该做一个修正:数组的地址没有传递 - 它是数组第一个元素的地址。最简单的方法是:

在C中,数组的值是指向其第一个元素的指针。

如果使用数组数组,则需要在第一次取消引用后提供有关数组大小的信息:

// either the following or: void foo(char param[][30][20])
void foo(char (*param)[30][20])
{
    // ...
}


int main(void)
{
    // bar is an array of 10 arrays of 30 arrays of 20 chars.
    // its value's TYPE is 'pointer to an array of 30 arrays of 20 chars,
    // which is what foo above requires.
    char bar[10][30][20];

    foo(bar);

}
相关问题