数组作为参数传递时会发生什么?

时间:2014-01-26 20:04:16

标签: c arrays pointers

我最近痛苦地了解到,如果将数组传递给函数,它会“衰减”到指针。

我的问题是,在创建它的范围内处理的数组是什么,sizeof如何区分?我认为所有数组都是指针,方括号将指针向前移动并一次取消引用。请注意以下代码:

[name@localhost lab03]$ cat arraysAsArguments.c
#include <stdio.h>

void function(int array[]) //Treated as pointer
{
  printf("%x", array);
  int size = sizeof array;
  int firstElement = sizeof array[0];
  printf("size: %d\n", size);
  printf("firstElement: %d\n", firstElement);
}

int main()
{
  int array[] = {0,1,2,3,4,5}; // expected size = 6*4 = 24 bytes
  printf("%x", array);
  int size = sizeof array;
  int firstElement = sizeof array[0];
  printf("size: %d\n", size);
  printf("firstElement: %d\n", firstElement);
  function(array);
}

[name@localhost lab03]$ clang arraysAsArguments.c
arraysAsArguments.c:5:12: warning: conversion specifies type 'unsigned int' but the argument has type 'int *' [-Wformat]
  printf("%x", array);
          ~^   ~~~~~
arraysAsArguments.c:15:12: warning: conversion specifies type 'unsigned int' but the argument has type 'int *' [-Wformat]
  printf("%x", array);
          ~^   ~~~~~
2 warnings generated.
[name@localhost lab03]$ ./a.out
57c84940size: 24
firstElement: 4
57c84940size: 8
firstElement: 4

在main和function中,array的类型为int *。发生了什么事?!

3 个答案:

答案 0 :(得分:4)

当作为函数传递时,数组衰减到指向其第一个元素的指针。这就是为什么sizeof内的function调用不符合您的预期,因为它在指针上调用sizeof。在function这一行内

int size = sizeof array;

array已经衰减为指针,并且您在int*变量中存储了size的大小。

您仍然可以通过参数访问数组中的元素,但作为符号

array[1];

相同
*(array + 1);

如果您已声明函数直接接受int*作为参数而不是数组,则这与访问数组元素的方式相同。所有发生的事情都是衰减到指针 - int array[]中的main仍然是一个数组。

答案 1 :(得分:1)

Cc-faq: 6.4

  

由于数组会立即衰减为指针,因此数组实际上永远不会传递给函数。您可以假装函数接收数组作为参数,并通过将相应的参数声明为数组来说明它:

void f(char a[])
{ ... }
     

从字面上解释,这个声明没有用,所以编译器转过身来假装你写了一个指针声明,因为这就是函数实际上会收到的内容:

void f(char *a)
{ ... }  

c-faq: Why doesn't sizeof properly report the size of an array when the array is a parameter to a function?

  

编译器假装数组参数被声明为指针(即,在示例中,为char *a;),sizeof报告指针的大小。

我建议你阅读c-faq: 6. Arrays and Pointers的整个部分。

答案 2 :(得分:0)

根据你的语句将数组传递给函数Arrays衰减到指针是正确的。

我们可以说数组只是指针而已,唯一的区别是“数组是常量指针”

int arr[3] = {1,2,3};

所以,这里我们可以通过使用指针取消引用来获取数组元素%d,*(arr + 0);

printf("%d %d \n",*(arr+0),arr[0]);

此外,char str =“string”;     的printf( “%C \ n” 个,(STR + 0));

所以,根据我的理解,数组和指针是相同的,只有差异是 ARRAYS是常数指针。 即我们不能做arr ++;到数组。

int arr[3];
char *str;

如果我们将数组传递给函数,我们在arr中做出的任何更改都会反映在调用函数数组中为arr,&amp; arr和&amp; arr [0]是相同的。 指针中的位置:str和&amp; str是不同的。