数组是c真正引用类型的参数吗?

时间:2016-06-08 21:21:08

标签: c arrays pointers malloc

#include <stdio.h>
#include <stdlib.h>

void fun(int *arr)
{
    arr=(int *)malloc(2*sizeof(int));
    arr[0]=5;
    arr[1]=4;
    printf("in fun {%d, %d}",arr[0],arr[1]);
}

void anotherFunction(int *arr) 
{
    arr[0]=4;
    arr[1]=5;
    printf("in fun {%d, %d}",arr[0],arr[1]);
}

int main(void) 
{
    int *arr,*emptyInMain;
    int arr2[]={99,99};
    arr=(int *)malloc(2*sizeof(int));
    arr[0]=99;
    arr[1]=99;

    printf("arr ");
    fun(arr);
    printf("\narr in main {%d, %d}\n",arr[0],arr[1]);

    printf("emptyInMain");
    fun(emptyInMain);
    //printf("\narr in main {%d, %d}\n",emptyInMain[0],emptyInMain[1]);    // WILL GIVE RUNTIME ERROR
    printf("\n\--commented the line in the code because emptyInMain[0],emptyInMain[1] will give RUNTIME ERROR--");

    printf("\narr2");
    fun(arr2);
    printf("\narr2 in main {%d, %d}\n",arr2[0],arr2[1]);

    printf("\nfollowing output shows expected behaviour\n");

    printf("\narr2");
    anotherFunction(arr2);
    printf("\narr2 in main {%d, %d}\n",arr2[0],arr2[1]);
    return 0;
}

我们都知道将数组作为参数传递是一个引用调用。好像我将一个数组arr = {99,99}发送到一个使arr [0] = 4和arr [1] = 5的函数,调用函数中的值也变为4和5。如果我发送变量的地址并且某些操作在其他函数中完成,则应该适用。

以上代码的以下输出让我感到困惑。如果我的想法是正确的,我想要放心。

arr in fun {5, 4}
arr in main {99, 99}
emptyInMainin fun {5, 4}
--commented the line in the code because emptyInMain[0],emptyInMain[1] will give RUNTIME ERROR--
arr2in fun {5, 4}
arr2 in main {99, 99}

following output shows expected behaviour

arr2in fun {4, 5}
arr2 in main {4, 5}

只有最后一个输出显示更改。

为什么我认为arr在前三种情况下没有改变,我们发送的是arr的地址,它存储在fun()的局部变量中。该局部变量在语句后开始指向其他地址:

arr=(int *)malloc(2*sizeof(int));

anotherFunction()是唯一不会改变其自身局部变量分配并操纵存储在其(局部变量的)地址中的值的函数。

如果我的假设错误,请告诉我。另外,请让我知道在所有情况下,我可以做出哪些最佳更改以使数组中的值发生变化。我怎样才能通过调用函数内的malloc使变量指向位置(我猜双指针但不确定)。

2 个答案:

答案 0 :(得分:3)

要回答标题中的问题,C参数始终按值传递,绝不会通过引用传递。使数组不同的是,当您将数组作为参数传递时,它会自动转换为指向数组第一个元素的指针,这就是传递的值。通过制作值的副本来传递所有其他类型的参数。

在任何一种情况下,在函数中分配参数变量都不会影响调用者的变量。当参数是指针时,您可以间接通过它来访问调用者的数据。如果它是指向数组元素的指针,您可以将其编入索引以访问调用者的数组。这就是anotherfunction()函数中发生的事情。

如果你想在函数中分配数组并影响调用者,有两种方法可以做到。

首先让函数返回指针:

int *fun() {
    int *localarr = malloc(2 * sizeof(int));
    localarr[0] = 4;
    localarr[1] = 5;
    return localarr;
}

然后调用者会这样做:

arr = fun();

第二种方法是将指针传递给指针。

void fun(int **arrparam) {
    int *localarr = malloc(2 * sizeof(int));
    localarr[0] = 4;
    localarr[1] = 5;
    *arrparam = localarr;
}

然后来电者做:

fun(&arr);

答案 1 :(得分:1)

  

如何通过调用函数内的malloc使变量指向位置,以便main中的变量也开始指向新位置(我猜双指针但不确定)。

为了做到这一点,你已经传递了一个指向指针的指针(这是你的双指针)。

foo(int** ptr)
{
   *ptr = malloc(sizeof(int)*2);
   (*ptr)[0] = 10;
   (*ptr)[1] = 20;
}

int main()
{
   int* ptr;
   foo(&ptr);  // Use the & operator to pass a pointer to the pointer.

   // Check to make sure that the values are as expected.
   assert(ptr[0] == 10);
   assert(ptr[1] == 20);

   // deallocate the memory
   free(ptr);
}