我最近痛苦地了解到,如果将数组传递给函数,它会“衰减”到指针。
我的问题是,在创建它的范围内处理的数组是什么,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 *。发生了什么事?!
答案 0 :(得分:4)
当作为函数传递时,数组衰减到指向其第一个元素的指针。这就是为什么sizeof
内的function
调用不符合您的预期,因为它在指针上调用sizeof
。在function
这一行内
int size = sizeof array;
array
已经衰减为指针,并且您在int*
变量中存储了size
的大小。
您仍然可以通过参数访问数组中的元素,但作为符号
array[1];
与
相同*(array + 1);
如果您已声明函数直接接受int*
作为参数而不是数组,则这与访问数组元素的方式相同。所有发生的事情都是衰减到指针 - int array[]
中的main
仍然是一个数组。
答案 1 :(得分:1)
由于数组会立即衰减为指针,因此数组实际上永远不会传递给函数。您可以假装函数接收数组作为参数,并通过将相应的参数声明为数组来说明它:
void f(char a[]) { ... }
从字面上解释,这个声明没有用,所以编译器转过身来假装你写了一个指针声明,因为这就是函数实际上会收到的内容:
void f(char *a) { ... }
编译器假装数组参数被声明为指针(即,在示例中,为
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是不同的。