在 C 中通过引用传递数组 [英] Passing an Array by reference in C

查看:38
本文介绍了在 C 中通过引用传递数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 C 新手,我有疑问.

I'm new to C and I have a doubt.

由于 C 函数会创建其参数的本地副本,我想知道为什么以下代码按预期工作:

Since C functions create local copies of it's arguments, I'm wondering why the following code works as expected:

void function(int array[]){

    array[0] = 4;
    array[1] = 5;
    array[2] = 6;   
}

int main(){

    int array[] = {1,2,3};

    function(array);

    printf("%d %d %d",array[0],array[1],array[2]);

    return 0;
}

线路输出为 4 5 6.

With the line output being 4 5 6.

为什么这有效而以下无效?

Why does this work while the following doesn't?

void function(int integer){

    integer = 2;
}

int main(){

    int integer = 1;

    function(integer);

    printf("%d",integer);

    return 0;
}

在这种情况下,输出仅为 1.

The output is just 1 in this case.

简短版本:如果函数作为数组传递,为什么函数可以修改其父变量的值?

Short version: Why can functions modify the values of their parent variables if they are passed as array?

谢谢大家!

推荐答案

这是由数组趋向于衰减为指针这一事实造成的.

This is caused by the fact that arrays tend to decay into pointers.

int a[] = { 1, 2, 3 };
int* p = a; // valid: p is now the address of a[0]
a = p;  // NOT valid.

printf("a = %p\n", a);
printf("p = %p\n", p); // prints same address as a

ap 将打印相同的值.

a and p will print the same value.

与其他人所说的相反,a 不是一个指针,它可以简单地衰减为一个.http://c-faq.com/aryptr/aryptrequiv.html

Contrary to what others have said, a is not a pointer, it can simply decay to one. http://c-faq.com/aryptr/aryptrequiv.html

在你的第一个 function() 中传递的是数组第一个元素的地址,函数体取消引用它.事实上,编译器将函数原型视为这样:

In your first function() what gets passed is the address of the array's first element, and the function body dereferences that. Infact, the compiler is treating the function prototype as this:

void function(int* array /*you wrote int array[]*/){
    array[0] = 4;
    array[1] = 5;
    array[2] = 6;   
}

function(&array[0]);

这必须发生,因为您说的是未知大小的数组"(int array[]).编译器无法保证推导出按值传递所需的堆栈量,因此它会衰减为指针.

This has to happen because you said "array of unknown size" (int array[]). The compiler could not guarantee to deduce the amount of stack required to pass by value, so it decays to a pointer.

---- 编辑----

---- Edit ----

让我们结合您的示例并使用更独特的名称使事情更清楚.

Lets combine both your examples and use more distinctive names to make things clearer.

#include <stdio.h>

void func1(int dynArray[]) {
    printf("func1: dynArray = %p, &dynArray[0] = %p, dynArray[0] = %d\n",
             dynArray, &dynArray[0], dynArray[0]);
}

void func2(int* intPtr) {
    printf("func2: intPtr = %p, &intPtr[0] = %p, intPtr[0] = %d\n",
             intPtr, &intPtr[0], intPtr[0]);
}

void func3(int intVal) {
    printf("func3: intVal = %d, &intValue = %p\n",
             intVal, &intVal);
}

int main() {
    int mainArray[3] = { 1, 2, 3 };
    int mainInt = 10;

    printf("mainArray = %p, &mainArray[0] = %p, mainArray[0] = %d\n",
             mainArray, &mainArray, mainArray[0]);
    func1(mainArray);
    func2(mainArray);

    printf("mainInt = %d, &mainInt = %p\n",
             mainInt, &mainInt);
    func3(mainInt);

    return 0;
}

ideone 现场演示:http://ideone.com/P8C1f4

Live demo at ideone: http://ideone.com/P8C1f4

mainArray = 0xbf806ad4, &mainArray[0] = 0xbf806ad4, mainArray[0] = 1
func1: dynArray = 0xbf806ad4, &dynArray[0] = 0xbf806ad4, dynArray[0] = 1
func2: intPtr = 0xbf806ad4, &intPtr[0] = 0xbf806ad4, intPtr[0] = 1

mainInt = 10, &mainInt = 0xbf806acc
func3: intVal = 10, &intValue = 0xbf806ad0

func1func2中,dynArray"和intPtr"是局部变量,但它们是指针变量,它们从main接收mainArray"的地址.

In func1 and func2 "dynArray" and "intPtr" are local variables, but they are pointer variables into which they receive the address of "mainArray" from main.

此行为特定于数组.如果你把数组放在一个结构体中,那么你就可以按值传递它.

This behavior is specific to arrays. If you were to put the array inside a struct, then you would be able to pass it by value.

这篇关于在 C 中通过引用传递数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆