Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an Array by reference in C

Tags:

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

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; } 

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; } 

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?

Thank you all!

like image 879
Costagero Avatar asked Oct 28 '13 22:10

Costagero


People also ask

Can you pass an array by reference in C?

Passing arrays to functions in C/C++ are passed by reference. Even though we do not create a reference variable, the compiler passes the pointer to the array, making the original array available for the called function's use. Thus, if the function modifies the array, it will be reflected back to the original array.

What is passing an array by reference?

If we pass the address of an array while calling a function, then this is called function call by reference. The function declaration should have a pointer as a parameter to receive the passed address, when we pass an address as an argument.

How arrays are passed to functions in C?

To pass an entire array to a function, only the name of the array is passed as an argument. result = calculateSum(num); However, notice the use of [] in the function definition. This informs the compiler that you are passing a one-dimensional array to the function.

What is array in C How can you reference it?

Arrays are used to store multiple values in a single variable, instead of declaring separate variables for each value. To create an array, define the data type (like int ) and specify the name of the array followed by square brackets [].


1 Answers

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 

a and p will print the same value.

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

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]); 

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; } 

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 

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.

like image 193
kfsone Avatar answered Sep 30 '22 21:09

kfsone