C语言中数组做函数参数退化问题刨析
一、综述
C语言中数组作为函数参数运行的时候, 函数在执行的过程中,数组参数是否像其他类型的参数(例如:int类型)不发生改变的执行呢?
我们首先看一个示例,然后观看他的打印结果,然后分析原因
二、代码示例和运行结果
/*
C语言中 数组作为函数参数退化为指针
我们以打印数组的为例, 数组作为打印函数的参数
*/
#include "stdafx.h"
#include<stdio.h>
/*
数组打印函数大小默认100
*/
void printarray_1(int arr[100]){
printf("--------------void printarray_1(int arr[100])---------------\n");
//PS:我们再次打印一下得到的数组长度是多少?
int len = sizeof(arr)/sizeof(int);
printf("len = %d\n", len);
for(int i=0; i<len;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
}
/*
数组打印函数传入数组参数,但是不限定大小
*/
void printarray_2(int arr[]){
printf("--------------void printarray_2(int arr[])---------------\n");
int len = sizeof(arr)/sizeof(int);
printf("len = %d\n", len);
for(int i=0; i<len;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
}
/*
数组打印函数传入数组参数,并且在传入一个int类型的长度参数
*/
void printarray_3(int arr[] ,int len){
printf("--------------void printarray_3(int arr[] ,int len)---------------\n");
for(int i=0; i<len;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
}
/*
数组打印函数传入指针参数,并且在传入数组长度参数
*/
void printarray_4(int *p ,int len){
printf("--------------void printarray_4(int *p ,int len)---------------\n");
for(int i=0; i<len;i++){
printf("arr[%d] = %d\n",i,*(p+i));
}
}
int main(){
int arr[5] = {1,2,3,4,5};
printarray_1(arr);
printarray_2(arr);
printarray_3(arr,5);
printarray_4(arr,5);
return 0;
}
运行结果如下:
--------------void printarray_1(int arr[100])---------------
len = 1
arr[0] = 1
--------------void printarray_2(int arr[])---------------
len = 1
arr[0] = 1
--------------void printarray_3(int arr[] ,int len)---------------
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 4
arr[4] = 5
--------------void printarray_4(int *p ,int len)---------------
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 4
arr[4] = 5
请按任意键继续. . .
三、原因分析
我们通过打印结果可以发现.
问题1,函数void printarray_1(int arr[100])和void printarray_2(int arr[])通过int len = sizeof(arr)/sizeof(int);语句求得数组长度是1,与我们编写代码时认为的5不一致.
问题2,函数void printarray_3(int arr[] ,int len)和函数void printarray_4(int *p ,int len)得到了我们期望的结果
我们从上面可知,当数组作为函数的参数进行传递的时候,编译器根本就没有认为他是一个数组, 如果编译器认为他是一个数组的话,那么前两个函数的打印结果不可能是1, 应该是5. 所以我们可知当数组作为函数的参数的时候, 数组退化为了一个指针. 那么我们 可以解释问题1中前两个函数求得数组长度为1的问题了, sizeof(arr)是一个指针变量的长度 ,是4, sizeof(int)结果是4,故结果是1
那么我们有一个疑问,如果数组作为函数的参数将退化为一个指针的话, 那么第三个函数void printarray_3(int arr[] ,int len)参数中也有arr[] 并且得到了正确的结果,并且代码中也出现了arr[i]通过索引来访问数组元素的操作. 这是在c开发中, 为了减少我们的编程难度和初学者的成本, 编译器兼容了这种写法 ,实际的arr[i]通过索引访问数组元素是 (arr+i)的操作. 编译器这样人性化的对我们这么好, 但是也无形中给了我们一个误解就是数组可以做函数的参数
四、结论
通过以上的代码示例和代码分析我们可知:
1,在C语言中,数组作为函数的参数,将会退化一个指针
2,在C语言中,数组作为函数的参数,并且在函数内通过索引访问数组元素,编译器对我们编程习惯的额兼容,实际他的内部是通过*(arr+i)访问的
3,在C语言中,数组作为函数的参数, 编译器在编译的时候, 不检查数组参数的大小,仅仅把他当做了一个指针
4,在C语言中,数组作为函数的参数,规范的写法是 指针+数组长度