Pass by reference and pointers [duplicate] - c

This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed 8 years ago.
What is the difference between passing by reference the parameters in a function and passing pointer variables as a parameter in a function ?

There is no pass by reference in C, it's always pass by value.
C developers can emulate pass by reference, by passing the pointers to a variable and the accessing it using dereferencing within the function. Something like the following, which sets a variable to 42:
static void changeTo42 (int *pXyzzy) {
*pXyzzy = 42;
}
:
int x = 0;
changeTo42 (&x);
Contrast that with the C++ true pass by reference, where you don't have to muck about with pointers (and especially pointers to pointers, where even seasoned coders may still occasionally curse and gnash their teeth):
static void changeTo42 (int &xyzzy) {
xyzzy = 42;
}
:
int x = 0;
changeTo42 (x);
I would implore ISO to consider adding true references to the next C standard. Not necessarily the full capability found in C++, just something that would fix all the problems people have when calling functions.

You might be thinking of C++. I'll cover that below.
In C there is no passing by reference. To accomplish the same feat, you can send a pointer to a variable as an argument and dereference the pointer in the method, as shown in paxdiablo's comment.
In C++, you could accomplish the same thing if you tried to pass by reference C-style (as explained previously) or if you tried passing the arguments as such:
static void multiply(int& x){
x * 7;
}
void main(){
int x = 4;
multiply(x);
}
The variable x at the end of this program would equal 28.

Related

Is passing pointers to functions similar to calling a function by reference? [duplicate]

This question already has answers here:
Passing by reference in C
(19 answers)
Closed 4 years ago.
I don't really see any difference, with passing pointers to functions and calling a function by reference. Am I right
#include <stdio.h>
int multi;
int multiplication(int *a, int *b){
multi = (*a) * (*b);
return multi;
}
int main()
{
int X = 2, Y=3;
multiplication(&X, &Y);
printf("%d", multi);
return 0;
}
From the example code you show, you obviously mean pass by reference, not call by reference.
There is no pass by reference in C, it's always pass by value. Of course, you can get the effect of pass by reference by passing a pointer to something. The pointer is your reference. It's again passed by value, but you use that value to access some other object.
Languages that have pass by reference will typically use pointers to implement it.

Are pointers considered a method of calling by reference in C?

In my University's C programming class, the professor and subsequent book written by her uses the term call or pass by reference when referring to pointers in C.
An example of what is considered a 'call by reference function' by my professor:
int sum(int *a, int *b);
An example of what is considered a 'call by value function' by my professor:
int sum(int a, int b);
I've read C doesn't support call by reference. To my understanding, pointers pass by value.
Basically, is it incorrect to say pointers are C's way of passing by reference? Would it be more correct to say you cannot pass by reference in C but can use pointers as an alternative?
Update 11/11/15
From the way my question originated, I believe a debate of terminology has stemmed and in fact I'm seeing two specific distinctions.
pass-by-reference (the term used mainly today): The specific term as used in languages like C++
pass-by-reference (the term used by my professor as a paradigm to explain pointers): The general term used before languages like C++ were developed and thus before the term was rewritten
After reading #Haris' updated answer it makes sense why this isn't so black and white.
you cannot pass by reference in C but can use pointers as an alternative
Yup, thats correct.
To elaborate a little more. Whatever you pass as an argument to c functions, it is passed by values only. Whether it be a variable's value or the variable address.
What makes the difference is what you are sending.
When we pass-by-value we are passing the value of the variable to a function. When we pass-by-reference we are passing an alias of the variable to a function. C can pass a pointer into a function but that is still pass-by-value. It is copying the value of the pointer, the address, into the function.
If you are sending the value of a variable, then only the value will be received by the function, and changing that won't effect the original value.
If you are sending the address of a variable, then also only the value(the address in this case) is sent, but since you have the address of a variable it can be used to change the original value.
As an example, we can see some C++ code to understand the real difference between call-by-value and call-by-reference. Taken from this website.
// Program to sort two numbers using call by reference.
// Smallest number is output first.
#include <iostream>
using namespace std;
// Function prototype for call by reference
void swap(float &x, float &y);
int main()
{
float a, b;
cout << "Enter 2 numbers: " << endl;
cin >> a >> b;
if(a>b)
swap(a,b); // This looks just like a call-by-value, but in fact
// it's a call by reference (because of the "&" in the
// function prototype
// Variable a contains value of smallest number
cout << "Sorted numbers: ";
cout << a << " " << b << endl;
return 0;
}
// A function definition for call by reference
// The variables x and y will have their values changed.
void swap(float &x, float &y)
// Swaps x and y data of calling function
{
float temp;
temp = x;
x = y;
y = temp;
}
In this C++ example, reference variable(which is not present in C) is being used. To quote this website,
"A reference is an alias, or an alternate name to an existing variable...",
and
"The main use of references is acting as function formal parameters to support pass-by-reference..."
This is different then the use of pointers as function parameters because,
"A pointer variable (or pointer in short) is basically the same as the other variables, which can store a piece of data. Unlike normal variable which stores a value (such as an int, a double, a char), a pointer stores a memory address."
So, essentially when one is sending address and receiving through pointers, one is sending the value only, but when one is sending/receiving a reference variable, one is sending an alias, or a reference.
**UPDATE : 11 November, 2015**
There has been a long debate in the C Chatroom, and after reading comments and answers to this question, i have realized that there can be another way to look at this question, another perspective that is.
Lets look at some simple C code
int i;
int *p = &i;
*p = 123;
In this scenario, one can use the terminology that, p's value is a reference to i. So, if that is the case, then if we send the same pointer (int* p) to a function, one can argue that, since i's reference is sent to the function, and thus this can be called pass-by-reference.
So, its a matter of terminology and way of looking at the scenario.
I would not completely disagree with that argument. But for a person who completely follows the book and rules, this would be wrong.
NOTE: Update inspired by this chat.
Reference is an overloaded term here; in general, a reference is simply a way to refer to something. A pointer refers to the object pointed to, and passing (by value) a pointer to an object is the standard way to pass by reference in C.
C++ introduced reference types as a better way to express references, and introduces an ambiguity into technical English, since we may now use the term "pass by reference" to refer to using reference types to pass an object by reference.
In a C++ context, the former use is, IMO, deprecated. However, I believe the former use is common in other contexts (e.g. pure C) where there is no ambiguity.
Does C even have ``pass by reference''?
Not really.
Strictly speaking, C always uses pass by value. You can simulate pass by reference yourself, by defining functions which accept pointers and then using the & operator when calling, and the compiler will essentially simulate it for you when you pass an array to a function (by passing a pointer instead, see question 6.4 et al.).
Another way of looking at it is that if an parameter has type, say, int * then an integer is being passed by reference and a pointer to an integer is being passed by value.
Fundamentally, C has nothing truly equivalent to formal pass by reference or c++ reference parameters.
To demonstrate that pointers are passed by value, let's consider an example of number swapping using pointers.
int main(void)
{
int num1 = 5;
int num2 = 10;
int *pnum1 = &num1;
int *pnum2 = &num2;
int ptemp;
printf("Before swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
temp = pnum1;
pnum1 = pnum2;
pnum2 = ptemp;
printf("After swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Instead of swapping numbers pointers are swapped. Now make a function for the same
void swap(int *pnum1, int *pnum2)
{
int *ptemp = pnum1;
pnum1 = pnum2;
pnum2 = temp;
}
int main(void)
{
int num1 = 5;
int num2 = 10;
int *pnum1 = &num1;
int *pnum2 = &num2;
printf("Before swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
swap(pnum1, pnum2);
printf("After swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Boom! No swapping!
Some tutorials mention pointer reference as call by reference which is misleading. See the this answer for the difference between passing by reference and passing by value.
From the C99 standard (emphasis mine):
6.2.5 Types
20 Any number of derived types can be constructed from the object and function types, as
follows:
...
— A pointer type may be derived from a function type or an object type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’. The construction of a pointer type from a referenced type is called ‘‘pointer type derivation’’. A pointer type is a complete object type.
Based on the above, what your professor said makes sense and is correct.
A pointer is passed by value to functions. If the pointer points to a valid entity, its value provides a reference to an entity.
"Passing by reference" is a concept. Yes, you are passing the value of a pointer to the function, but in that instance the value of that pointer is being used to reference the variable.
Someone else used a screwdriver analogy to explain that it is wrong to refer to the passing of pointers as passing by reference, saying that you can screw a screw with a coin but that that doesn't mean you would call the coin a screw driver. I would say that is a great analogy, but they come to the wrong conclusion. In fact, while you wouldn't claim a coin was a screwdriver, you would still say that you screwed the screw in with it. i.e. even though pointers are not the same as c++ references, what you are using them to do IS passing by reference.
C passes arguments by value, period. However, pointers are a mechanism that can be used for effectively passing arguments by reference. Just like a coin can be used effectively as a screw driver if you got the right kind of screw: some screws slit are even chosen to operate well with coins. They still don't turn the coins into actual screw drivers.
C++ still passes arguments by value. C++ references are quite more limited than pointers (though having more implicit conversions) and cannot become part of data structures, and their use looks a lot more like the usual call-by-reference code would look, but their semantics, while very much catered to match the needs of call-by-reference parameters, are still more tangible than that of pure call-by-reference implementations like Fortran parameters or Pascal var parameters and you can use references perfectly well outside of function call contexts.
Your professor is right.
By value , it is copied.
By reference, it is not copied, the reference says where it is.
By value , you pass an int to a function , it is copied , changes to the copy does not affect the original.
By reference , pass same int as pointer , it is not copied , you are modifying the original.
By reference , an array is always by reference , you could have one billion items in your array , it is faster to just say where it is , you are modifying the original.
In languages which support pass-by-reference, there exists a means by which a function can be given something that can be used to identify a variable know to the caller until the called function returns, but which can only be stored in places that won't exist after that. Consequently, the caller can know that anything that will be done with a variable as a result of passing some function a reference to it will have been done by the time the function returns.
Compare the C and C# programs:
// C // C#
int x=0; int x=0;
foo(&x); foo(ref x);
x++; x++;
bar(); bar();
x++; x++;
boz(x); boz(x);
The C compiler has no way of knowing whether "bar" might change x, because
foo() received an unrestricted pointer to it. By contrast, the C# compiler
knows that bar() can't possibly change x, since foo() only receives a
temporary reference (called a "byref" in .NET terminology) to it and there
is no way for any copy of that byref to survive past the point where foo()
returns.
Passing pointers to things allows code to do the same things that can be done with pass-by-ref semantics, but pass-by-ref semantics make it possible for code to offer stronger guarantees about things it won't do.

Does C even have "pass by reference"? [duplicate]

This question already has answers here:
Passing by reference in C
(19 answers)
Closed 2 years ago.
I heard that in "c" that there are we can pass the arguments via "call by value" or "call by reference".
But in one book it's mentioned that there are we can pass the arguments via both way but there is no "pass by reference" but I actually pass the mostly arguments by "pass by reference".
So why it is mentioned "does C even have "pass by reference"?
A detailed description will be greatly appreciated.
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;
}
The concept of "reference semantics" is an abstract, theoretical one, meaning that you have a way for a function to modify existing data in place by giving that function a reference to the data.
The question is whether reference semantics can be implemented by a language. In C, you can obtain reference semantics by using pointers. That means you can obtain the desired behaviour, but you need to assemble it yourself from various bits and pieces (pointer types, address-of operators, dereference operators, passing pointers as function arguments ("by value")).
By contrast, C++ contains a native reference type and thus implements reference semantics directly in the language.
Other languages have different approaches to this, for example, in Python many things are references by default (and there's a difference, say, between a = b and a = b[:] when b is a list). Whether and how a language provides reference vs value semantics is a profound part of the language's design.

type casting integer to void* [duplicate]

This question already has answers here:
what does it mean to convert int to void* or vice versa?
(6 answers)
Closed 9 years ago.
#include <stdio.h>
void pass(void* );
int main()
{
int x;
x = 10;
pass((void*)x);
return 0;
}
void pass(void* x)
{
int y = (int)x;
printf("%d\n", y);
}
output: 10
my questions from the above code..
what happens when we typecast normal variable to void* or any pointer variable?
We have to pass address of the variable to the function because in function definition argument is pointer variable. But this code pass the normal variable ..
This format is followed in linux pthread programming... I am an entry level C programmer. I am compiling this program in linux gcc compiler..
I'm only guessing here, but I think what you are supposed to do is actually pass the address of the variable to the function. You use the address-of operator & to do that
int x = 10;
void *pointer = &x;
And in the function you get the value of the pointer by using the dereference operator *:
int y = *((int *) pointer);
Please read why glib provide macros for this kind of conversions, there's no need to repeat the text here. The main point is: a pointer has a platform dependent size.
If you are planning to use pthreads and you are planning to pass the pass function to pthread_create, you have to malloc/free the arguments you are planning to use (even if the threaded function just need a single int).
Using an integer address (like &x) is probably wrong, indeed each modification you will execute on x will affect the pass behaviour.

Passing array not pointer to a function in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to find the sizeof(a pointer pointing to an array)
I want to pass an array to a function such that if I use the sizeof operator on array inside the function body, I should get the actual size of the array and not that of a pointer. For e.g -
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,0};
printf("Array size = %d\n", sizeof(arr)/sizeof(int)); ---> O/P = 40/4 = 10
func(arr);
}
void func(int arr[])
{
printf("Array size = %d\n", sizeof(arr)/sizeof(int)); --->O/P = 4/4 = 1
}
The printf statement in the main function prints 10 while the one in func prints 1. Is it possible to do so in C language?
EDIT: I know other alternatives like wrapping the array into a struct etc. Actually, I was trying to solve a problem given on TopCoders site and the requirement of one problem is that I have to write a function(requirement given below). Now I am confused that how I am going to calculate the size of the int[] donations array inside int maxDonations(int[] donations) function.
Definition
Class: BadNeighbors
Method: maxDonations
Parameters: int[]
Returns: int
Method signature: int maxDonations(int[] donations)
(be sure your method is public)
If you want, I can post the entire question.
A cheap way would be to wrap the array into a struct and pass that (or a pointer to the struct).
However, I would recommend passing an additional size_t argument that specifies the size of the array. This would make your function more flexible.
In C you cannot pass an array as a parameter to a function directly. You can pass a structure, a pointer or some other numeric value, but not an array.
Based on the constraints in your question, this question is impossible to answer.
In C, sizeof is an operator, rather than a function: you correctly mention this in your question. However, C operators are evaluated at compile time, rather than runtime, which means that you cannot use sizeof in a function in the way you want to - at compile time the compiler cannot tell how func() is going to be called.
Looking at the problem as set, I am assuming it is this one:
http://www.cs.duke.edu/csed/algoprobs/neighbors.html
The required method signature on that page is:
public int maxDonations(int[] donations)
although for some reason, you've omitted the public keyword in your question. This keyword indicates that the language in question is not C, and this example solution looks very much as if it is written in Java, in which language this is a non-problem, arrays have a length member.
I'd suggest you clarify the requirements for the question from your teacher/website/whatever to check what is really expected.

Resources