C always uses 'pass by value' to pass arguments to functions (another term is 'call by value', which means the same thing), which means the code within a function cannot alter the arguments used to call the function, even if the values are changed inside the function.
Every other time you pass data to a function (besides scanf), the data outside the function is not modified - it's like a local variable inside the function - that is because C creates a copy of the data that the function uses. An example of a 'swap' function to demonstrate the difference between pass by value and pass by reference is a simple function that swaps the values of two variables:
void swap(int fistVariable, int secondVariable) // create a temporary variable to hold one of the values to perform the swap int tempVariable; tempVariable = firstVariable; /* temporarily save the value of the first variable */ firstVariable = secondVariable; /* swap the vale of the first variable with the value of the second variable */ secondVariable = tempVariable; /* put the value of the first variable into the second variable */ return; > int main(void) int a = 100; int b = 200; printf("before swap: value of a: %d \n", a); printf("before swap: value of b: %d \n", b); // call function to swap values swap(a, b); // check values outside the function after swap function is run printf("after swap: value of a: %d \n", a); printf("after swap: value of b: %d \n", b); return 0; >
Enter fullscreen mode
Exit fullscreen mode
If the code above is run, the values remain the same after the swap function is run. This is because, under the hood, C is passing in copies of the variables ( a and b in this case), and they are modified within the function, but the originals remain unaffected.
Even though C always uses 'pass by value', it is possible simulate passing by reference by using dereferenced pointers as arguments in the function definition, and passing in the 'address of' operator & on the variables when calling the function.
What is passed in is a copy of the pointer, but what it points to is still the same address in memory as the original pointer, so this allows the function to change the value outside the function.
The arguments passed in and worked with inside the function are dereferenced pointers, which, from the programmer's perspective, is essentially the same thing as working with the values themselves. Using the same structure as the swap function above, using pointers, the values outside the function will be swapped:
void swap(int *pFirstVariable, int *pSecondVariable) int temp; // using dereferenced pointers means the function is working with the values at the addresses that are passed in temp = *pFirstVariable; *pFirstVariable = *pSecondVariable; *pSecondVariable = temp; return; > int main(void) int a = 100; int b = 200; printf("before swap: value of a: %d \n", a); printf("before swap: value of b: %d \n", b); // call the function to swap values, using the 'address of' operator to pass in the address of each variable swap(&a, &b); // check values outside the function after swap function is run printf("after swap: value of a: %d \n", a); printf("after swap: value of b: %d \n", b); return 0; >
Enter fullscreen mode
Exit fullscreen mode
If the example above is run, the values will be swapped (outside the function) after swap() has been called.
Returning a pointer from a function is a particularly powerful. It allows you to return not just a single value, but a whole set of values (e.g. structures, covered later). There is a special syntax for declaring a function that returns a pointer:
int * myFunction() //your code >
Enter fullscreen mode
Exit fullscreen mode