欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言中数组做函数参数退化问题刨析

程序员文章站 2023-12-31 13:58:40
...

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语言中,数组作为函数的参数,规范的写法是 指针+数组长度

上一篇:

下一篇: