Pass by Reference/Value in C++

Passing by reference in C

Because you're passing the value of the pointer to the method and then dereferencing it to get the integer that is pointed to.

Does C even have pass by reference? [duplicate]

C parameters are always passed by value rather than by reference. However, if you think of the address of an object as being a reference to that object then you can pass that reference by value. For example:

void foo(int *x)
{
*x = 666;
}

You ask in a comment:

So why do we need pointers in C when we can pass all the parameters by value?

Because in a language that only supports pass-by-value, lack of pointers would be limiting. It would mean that you could not write a function like this:

void swap(int *a, int *b)
{
int temp = *a;
*b = *a;
*a = temp;
}

In Java for example, it is not possible to write that function because it only has pass-by-value and has no pointers.

In C++ you would write the function using references like this:

void swap(int &a, int &b)
{
int temp = a;
b = a;
a = temp;
}

And similarly in C#:

void swap(ref int a, ref int b)
{
int temp = a;
b = a;
a = temp;
}

Meaning of pass by reference in C and C++?

In colloquial usage, "pass by reference" means that, if the callee modifies its arguments, it affects the caller, because the argument as seen by the callee refers to the value as seen by the caller.

The phrase is used independent of the actual programming language, and how it calls things (pointers, references, whatever).

In C++, call-by-reference can be done with references or pointers. In C, call-by-reference can only be achieved by passing a pointer.

"Call by value":

void foo( int x )
{
// x is a *copy* of whatever argument foo() was called with
x = 42;
}

int main()
{
int a = 0;
foo( a );
// at this point, a == 0
}

"Call by reference", C style:

void foo( int * x )
{
// x is still a *copy* of foo()'s argument, but that copy *refers* to
// the value as seen by the caller
*x = 42;
}

int main()
{
int a = 0;
foo( &a );
// at this point, a == 42
}

So, strictly speaking, there is no pass-by-reference in C. You either pass the variable by-value, or you pass a pointer to that variable by-value.

Is this call by reference or by value in C?

C passes arguments by value, always, meaning that the called function receives a local copy of whatever the caller refers to.

The called function can modify the received value, because it is a local copy, without affecting the original value. For example:

char *test(char *s) {
s++;
return s;
}

t = test("A");

it's legal and shows that the parameter s can be modified without affecting the caller (which passes a literal...).

But the strcpy() of you example does something different: it takes a pointer s, and modifies what s points to. Pointers are powerful, and they can be used to simulate "pass by reference" (a pointer is a reference).

after assignment *s = *t is held, which one is compared with '\0'? *s or *t?

The *s: in C, an assignment returns a value - and the value is the value of the assigned variable after the assignment is done. Writing:

if (i=3) ...

is the same as

i=3;
if (i) ...

If i was a pointer the syntax would be different but the mechanism is the same, the assignment would "use" the pointer and the value of the whole assignment is used as expression to be evaluated in the test.

I ask for clarification about ''not pass by reference'' in C

Or is the function asking for a pointer and when we use & it creates a pointer to that variable?

That's exactly right.

In C++, the symbol & has multiple meanings:

  • When applied as a unary operator in an expression, it means "take the address of", and produces a pointer;
  • When part of a type like int& (or, indeed, int*&), it means "reference to";
  • (And, when applied as a binary operator between two arithmetic expressions, it means "bitwise AND".)

With the choice of using & for reference types, the idea was, I think, to save creating new symbols and to try to create some symmetry between pointers and references. I don't think it worked; I think it's really confusing.

But for you, in C, it's moot, because (as you've discovered!) C does not have references. Instead your function could be written to take a pointer-to-pointer (int**). Ironically, you will probably need to use & at the call-site to present your argument to such a function!

As a further complication, you will sometimes hear the phrase "pass by reference" used in a broad sense. This is confusing in the realm of C++ because "reference" has this more specific meaning there. In fact, references were introduced in the C++ language specifically to make "pass by reference" more elegant and intuitive. But back in C, and more generally, it's just a way of saying "we're referring to a thing rather than copying it"; technically in C the way we do that is, indeed, to pass a pointer.

Is passing pointer by value or by reference the same

What is the difference between passing a pointer by reference and passing a pointer by value in C?

There is no such thing as passing a pointer by reference in C, all variables are passed by value, even pointers.

My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.

Again, the pointers are not passed by reference, a copy of the value stored in the pointer is passed, i.e. the address where it points to, you can test this by changing the value of the pointer inside the function, and check how that reflects on the original pointer, spoiler, it doesn't.

When working with pointers I noticed that if I pass a char by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.*

What you are passing is an address, a memory location where some data is stored, when you change the data stored in that memory address it will be permanent, no matter where you do it, in fact that is one of the advantages of using pointers, for you to change the contents of some variable outside the scope where it's declared.

C intro - How to pass a parameter by reference in function?

  1. It is perfectly valid. You can initialize and pass any number of pointer variables with their reference.

  2. This is also valid..when you pass the variable address, you should store it into a pointers

you have to do some changes in your code,
You can assign directly a/b and a*b pointer variables *c & *d
Then you have to read double number with %lf format argument.

#include <stdio.h>
#include <string.h>

void myFunction(double a, double b, double *c, double *d)
{
*c = a/b; //change
*d = a*b; //change
printf("%lf %lf",*c,*d);
return;
//printf statements
}



int main()
{
//first and second double hold the scanf inputs
double first;
double second;

//unsure here - to reference c and d as parameters in the function, do I simply declare unfilled double variables here?
double *c;
double *d;

printf("Enter your first number\n");
scanf("%lf", &first); //change
printf("Enter your second number\n");
scanf("%lf", &second); //change

//call the function, first and second by value, &c / &d by reference - correct?
myFunction(first, second, &c,&d);
}

What exactly is the difference between pass by reference in C and in C++?

There are questions that already deal with the difference between passing by reference and passing by value. In essence, passing an argument by value to a function means that the function will have its own copy of the argument - its value is copied. Modifying that copy will not modify the original object. However, when passing by reference, the parameter inside the function refers to the same object that was passed in - any changes inside the function will be seen outside.

Unfortunately, there are two ways in which the phrases "pass by value" and "pass by reference" are used which can cause confusion. I believe this is partly why pointers and references can be difficult for new C++ programmers to adopt, especially when they've come from a background in C.

C

In C, everything is passed by value in the technical sense. That is, whatever you give as an argument to a function, it will be copied into that function. For example, calling a function void foo(int) with foo(x) copies the value of x as the parameter of foo. This can be seen in a simple example:

void foo(int param) { param++; }

int main()
{
int x = 5;
foo(x);
printf("%d\n",x); // x == 5
}

The value of x is copied into foo and that copy is incremented. The x in main continues to have its original value.

As I'm sure you're aware, objects can be of pointer type. For example, int* p defines p as a pointer to an int. It is important to note that the following code introduces two objects:

int x = 5;
int* p = &x;

The first is of type int and has the value 5. The second is of type int* and its value is the address of the first object.

When passing a pointer to a function, you are still passing it by value. The address it contains is copied into the function. Modifying that pointer inside the function will not change the pointer outside the function - however, modifying the object it points to will change the object outside the function. But why?

As two pointers that have the same value always point at the same object (they contain the same address), the object that is being pointed to may be accessed and modified through both. This gives the semantics of having passed the pointed to object by reference, although no references ever actually existed - there simply are no references in C. Take a look at the changed example:

void foo(int* param) { (*param)++; }

int main()
{
int x = 5;
foo(&x);
printf("%d\n",x); // x == 6
}

We can say when passing the int* into a function, that the int it points to was "passed by reference" but in truth the int was never actually passed anywhere at all - only the pointer was copied into the function. This gives us the colloquial1 meaning of "pass by value" and "pass by reference".

The usage of this terminology is backed up by terms within the standard. When you have a pointer type, the type that it is pointing to is known as its referenced type. That is, the referenced type of int* is int.

A pointer type may be derived from a function type, an object type, or an incomplete
type, called the referenced type.

While the unary * operator (as in *p) is known as indirection in the standard, it is commonly also known as dereferencing a pointer. This further promotes the notion of "passing by reference" in C.

C++

C++ adopted many of its original language features from C. Among them are pointers and so this colloquial form of "passing by reference" can still be used - *p is still dereferencing p. However, using the term will be confusing, because C++ introduces a feature that C doesn't have: the ability to truly pass references.

A type followed by an ampersand is a reference type2. For example, int& is a reference to an int. when passing an argument to a function that takes reference type, the object is truly passed by reference. There are no pointers involved, no copying of objects, no nothing. The name inside the function actually refers to exactly the same object that was passed in. To contrast with the example above:

void foo(int& param) { param++; }

int main()
{
int x = 5;
foo(x);
std::cout << x << std::endl; // x == 6
}

Now the foo function has a parameter that is a reference to an int. Now when passing x, param refers to precisely the same object. Incrementing param has a visible change on the value of x and now x has the value 6.

In this example, nothing was passed by value. Nothing was copied. Unlike in C, where passing by reference was really just passing a pointer by value, in C++ we can genuinely pass by reference.

Because of this potential ambiguity in the term "pass by reference", it's best to only use it in the context of C++ when you are using a reference type. If you are passing a pointer, you are not passing by reference, you are passing a pointer by value (that is, of course, unless you are passing a reference to a pointer! e.g. int*&). You may, however, come across uses of "pass by reference" when pointers are being used, but now at least you know what is really happening.


Other languages

Other programming languages further complicate things. In some, such as Java, every variable you have is known as a reference to an object (not the same as a reference in C++, more like a pointer), but those references are passed by value. So even though you appear to be passing to a function by reference, what you're actually doing is copying a reference into the function by value. This subtle difference to passing by reference in C++ is noticed when you assign a new object to the reference passed in:

public void foo(Bar param) {
param.something();
param = new Bar();
}

If you were to call this function in Java, passing in some object of type Bar, the call to param.something() would be called on the same object you passed in. This is because you passed in a reference to your object. However, even though a new Bar is assigned to param, the object outside the function is still the same old object. The new one is never seen from the outside. That's because the reference inside foo is being reassigned to a new object. This kind of reassigning references is impossible with C++ references.


1 By "colloquial", I don't mean to suggest that the C meaning of "pass by reference" is any less truthful than the C++ meaning, just that C++ really does have reference types and so you are genuinely passing by reference. The C meaning is an abstraction over what is really passing by value.

2 Of course, these are lvalue references and we now have rvalue references too in C++11.



Related Topics



Leave a reply



Submit