简体   繁体   中英

C passing by value or reference with pointers

Which function calls are passed by value and which are passed by reference?

int *a;

int b;

int **c;

f(a);

g(&b);

h(*c);

Just simple examples, I am just confused with pointers and how you tell how they are passed.

The pedantic answer is that all of them are passed by value, but sometimes that value is an address.

More usefully, assuming there's no errors in what you have here, all of these functions are pass-by-address which is as close as C gets to pass-by-reference. They take in a pointer as an argument and they may dereference that pointer to write data to wherever it points. Only the call to g() is safe with just these lines because the other pointers are undefined.

This is the standard in C APIs for in/out parameters which don't need to be reallocated.

Functions that need to return a new variable-sized buffer usually take in a pointer to a pointer, so they may dereference the argument to get an address in the caller to which they write a pointer to a buffer they allocate, or which is a static variable of the function.

As mentioned in the comments it's possible to just return a pointer from a function. Memory allocation wouldn't work in C without it. But it's still pretty common to see functions that have size_t ** parameters or similar for returning pointers. That might be mostly a Unix pattern where almost every function returns a success/error code so the actual function output gets shifted to the arguments.

Formally, C doesn't have pass by reference. It only has pass by value.

You can simulate pass by reference in two ways:

  • You can declare a function parameter as a pointer, and explicitly use & to pass a pointer to an object in the caller.
  • You can declare a function parameter as a pointer, and pass an array, since when you try to pass an array, what actually happens is that the array's value "decays" into a pointer to its first element. (And you can also declare the function parameter as an array, to make it look even more like there's an array being passed, but you're actually declaring a pointer in any case.)

So it's more a question of which parameters you think of as being passed by reference.

You'll often hear it said that "arrays are passed by reference in C", and this isn't false, but arguably it isn't strictly true, either, because (as mentioned) what's actually happening is that a pointer to the array's first element is being passed, by value.

The easiest way to tell is in the size of the arithmetic, but this is not so for the char type. For address arithmetic, the sizeof operator is invoked which is not the case for ordinary arithmetic as in the type of unsigned int .

#include <iostream>
using namespace std;

int main() {
    unsigned int ui, *uiPtr;

    ui = 11;
    cout << ui << endl;
    ui += 1; //increases value by 1
    cout << ui << endl;
    uiPtr = &ui;
    cout << uiPtr << endl;
    uiPtr += 1; //increases value by sizeof
    cout << uiPtr << endl;

    return 0;
}

To make your question more clear let's initialize the variables

int b;

int *a = &b;

int **c = &a;

Then this call

f(a);

passes the object b by reference through the pointer a . The pointer itself is passed by value that is the function deals with a copy of the value of the pointer a .

This call

g(&b);

in fact is equivalent to the previous call relative to the accepted value. The variable b is passed by reference.

And this call also equivalent to the previous call

h(*c);

the variable b is passed by reference through the pointer *c value of which is equal to the value of the pointer a .

So all three functions accept the variable b by reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM