1.数组作为形参被调用
在C语言中,当数组名作为函数参数被调用时,它并不传递整个数组本身,而是传递数组首元素的地址。这是因为数组名在大多数情况下(除了作为sizeof操作符的操作数或作为&操作符的操作数时)会被解释为指向数组首元素的指针。
这意味着,当你在函数中接收一个数组作为参数时,你实际上接收到的是一个指向该数组第一个元素的指针。基于这一点,你可以通过这个指针在函数内部访问和修改数组的元素。
下面是一个简单的例子来说明这一点:
#include <stdio.h>
// 函数声明,参数是一个指向整数的指针
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]); // 通过指针访问数组元素
}
printf("\n");
}
int main() {
int myArray[] = {1, 2, 3, 4, 5};
int size = sizeof(myArray) / sizeof(myArray[0]); // 计算数组元素数量
// 调用函数,数组名myArray作为参数,传递的是数组首元素的地址
printArray(myArray, size);
return 0;
}
在这个例子中,printArray
函数接收一个指向整数的指针arr
和一个整数size
作为参数。虽然printArray
函数的声明看起来像是它接收了一个数组,但实际上它接收的是一个指向整数的指针。当myArray
作为参数传递给printArray
时,它传递的是myArray
首元素的地址,即&myArray[0]
。然后,printArray
函数就可以通过这个指针遍历数组了。
这种方式非常灵活和强大,因为它允许函数操作数组,而不需要知道数组的确切大小(在这个例子中,我们通过额外的size
参数来传递数组的大小)。然而,这也意味着调用者需要负责传递正确的大小,以避免越界访问等错误。
2.数组作为实参在函数中的值传递
(1)整型变量的传递
首先我们分析整型变量在函数中的传递,例如以下代码:
#include<stdio.h>
void changeData(int data)
{
data = data + 100;
printf("changeData中data的地址是:%p,data=%d\n",&data,data);
}
int main()
{
int data = 10;
changeData(data);
printf("main中data的地址是:%p,data=%d\n",&data,data);
return 0;
}
它的输出为:
changeData中data的地址是:000000000061FDF0,data=110
main中data的地址是:000000000061FE1C,data=10
我们可以看到,虽然两个函数中的变量名一样都是data,但是他们的地址不同,就代表他们是不同的变量。main函数中的data被调用到changeData函数中,传递的只是它的值,在changeData函数中data只是一个局部变量,改变的也只是changeData函数中data的值,并不影响main函数中data的值。
(2)数组变量的传递:
接着我们再看数组的情况:
#include<stdio.h>
void changeData(int array[])
{
array[0] = array[0] + 100;
printf("changeData中array的地址是:%p,array[0]=%d\n",array,array[0]);
}
int main()
{
int array[] = {10};
changeData(array);
printf("main中array的地址是:%p,array[0]=%d\n",array,array[0]);
return 0;
}
输出为:
changeData中array的地址是:000000000061FE1C,array[0]=110
main中array的地址是:000000000061FE1C,array[0]=110
我们可以看到,两个函数中数组的地址和值都是一样的,当changeData函数中的数组值被改变时,main函数中数组的值也同样发生改变。验证了我们之前提到的当数组名作为函数参数被调用时,它并不传递整个数组本身,而是传递数组首元素的地址。在同一地址上进行的操作,将会保留其变化。