首页 > 解决方案 > C 按值传递数组与按引用传递数组

问题描述

大家好,所以我一直在学习 C,我遇到了这个例子,我并没有真正找到背后的逻辑。这不是关于我正在寻找更多解释的代码的技术问题。这是代码

#include <stdio.h>

void set_array(int array[4]);
void set_int(int x);

int main(void)
{
    int a = 10;
    int b[4] = {0, 1, 2, 3};
    set_int(a);
    set_array(b);
    printf("%d %d\n", a, b[0]);
}

void set_array(int array[4])
{
    array[0] = 22;
}

void  set_int(int x)
{
    x = 22;
}

输出是10 22

基本上我的问题是为什么从 set_array 函数传递的 22 重写 b 数组上的 0 并实际打印但从 set_int 函数传递的 22 没有被传递或打印。

谢谢你们!

标签: carrayspass-by-referenceimplicit-conversionfunction-declaration

解决方案


在 C 中,通过引用传递意味着通过指向对象的指针间接传递对象。如果您将对象直接传递给函数,则该函数将处理对象值的副本。

比较这个演示程序中的两个函数调用。

#include <stdio.h>

void f( int x )
{
    x = 10;
}

void g( int *x )
{
    *x = 10;
}


int main(void) 
{
    int x = 0;

    printf( "Before call f: x = %d\n", x );

    f( x );

    printf( "After  call f: x = %d\n", x );

    putchar( '\n' );

    printf( "Before call g: x = %d\n", x );

    g( &x );

    printf( "After  call g: x = %d\n", x );

    return 0;
}

程序输出为

Before call f: x = 0
After  call f: x = 0

Before call g: x = 0
After  call g: x = 10

f那就是我们直接将对象传递给函数x。因此该函数处理对象的副本x。更改副本不会影响xmain 中声明的原始对象。

至于函数,它通过指向它的指针间接g访问对象。x所以改变指向的对象我们改变了xmain中声明的对象。

至于数组,那么当数组传递给函数时,它会隐式转换为指向其第一个元素的指针。所以这个函数实际上是通过这个指针通过引用来获取数组的元素。使用指针和指针算法,我们可以更改数组的任何元素。

这个函数声明

void set_array(int array[4]);

相当于下面的声明

void set_array(int array[]);

并且这两个声明都由编译器调整为声明

void set_array(int *array);

所以函数处理一个指针——指向数组第一个元素的指针,用作函数调用的参数。

程序中函数 set_array 的调用

set_array(b);

相当于下面的调用

set_array( &b[0] );

因为在表达式中使用的数组(例如作为函数参数表达式)被隐式转换为指向它们的第一个元素的指针。


推荐阅读