C 按值传递数组与按引用传递数组
C pass array by value vs pass array by reference
大家好,我一直在学习 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 不会'既不会通过也不会打印出来。
谢谢大家!
C 函数,当接收参数时 除了 数组和指针(arryays 实际上被翻译成指针)不更新源值,因为它们创建了一个 参数传值的copy.
你的函数应该是:
void set_int(int *x)
{
x = 22;
}
那么您正在使用源变量。但是因为你没有声明一个指针,而是一个变量,你必须这样调用它:
set_int(&a);
确保您传递的是 a 的内存引用,而不是它的内容。
在 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
也就是我们直接把对象x
传给了函数f
。所以函数处理对象的副本x
。更改副本不会影响在 main.
中声明的原始对象 x
至于函数 g
然后它通过指向对象的指针间接获得了对象 x
的访问权。因此,更改指向的对象我们更改了在 main.
中声明的对象 x
对于数组,当数组传递给函数时,它会隐式转换为指向其第一个元素的指针。所以函数实际上是通过这个指针通过引用获取数组的元素。使用指针和指针算法我们可以改变数组的任何元素。
这个函数声明
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] );
因为表达式中使用的数组(例如作为函数参数表达式)被隐式转换为指向其第一个元素的指针。
大家好,我一直在学习 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 不会'既不会通过也不会打印出来。
谢谢大家!
C 函数,当接收参数时 除了 数组和指针(arryays 实际上被翻译成指针)不更新源值,因为它们创建了一个 参数传值的copy.
你的函数应该是:
void set_int(int *x)
{
x = 22;
}
那么您正在使用源变量。但是因为你没有声明一个指针,而是一个变量,你必须这样调用它:
set_int(&a);
确保您传递的是 a 的内存引用,而不是它的内容。
在 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
也就是我们直接把对象x
传给了函数f
。所以函数处理对象的副本x
。更改副本不会影响在 main.
x
至于函数 g
然后它通过指向对象的指针间接获得了对象 x
的访问权。因此,更改指向的对象我们更改了在 main.
x
对于数组,当数组传递给函数时,它会隐式转换为指向其第一个元素的指针。所以函数实际上是通过这个指针通过引用获取数组的元素。使用指针和指针算法我们可以改变数组的任何元素。
这个函数声明
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] );
因为表达式中使用的数组(例如作为函数参数表达式)被隐式转换为指向其第一个元素的指针。