update actual values using pass by value - c

I want to know if there is any way to update original values by using pass by value.
Also i want to know if I can return updated address back to main
Here I dont want to use pass by reference to swap original values in main.
#include<stdio.h>
int a = 100;
int f =200;
int *p, * q;
swap(int, int);
main()
{
printf("%d %d\n", a,f);
swap(a, f);
printf("%d %d\n",a ,f); //values remain same here how to change them
}
swap(int a, int f)
{
int t;
p=&a;
q=&f;
t=*p;
*p=*q;
*q= t;
printf("%d %d\n",a ,f);
}

I want to know if there is any way to update original values by using pass by value.
Yes there is, you need to pass a pointer:
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
And call it like this:
swap(&a, &f);
Note that there's no pass-by-reference in C, that's a C++ feature. In C everything, including pointers, are passed by value.
And pass-by-value means copy in C, so it's impossible to modify what was passed.
Also i want to know if I can return updated address back to main
Yes you can. Just change the function return type to a pointer type and add a return statement with the address of the variable of your choice.

Related

Why would a double pointer be needed? In which example of a situation?

I have 2 pieces of codes shown below:
The first one is:
void input(int * a) {
(*a) = 10;
}
int main()
{
int * a = (int *) malloc(sizeof(int));
input(a);
printf("%d", *a);
free(a);
return 0;
}
And the second is:
void input(int ** a) {
*(*a) = 10;
}
int main()
{
int * a = (int *) malloc(sizeof(int));
input(&a);
printf("%d", *a);
free(a);
return 0;
}
I ran those two codes, and they showed the same output (which is 10). I wonder if they had the same meaning? Can you help me to point out the difference (if any)?
You demonstrated that you understand the need for a pointer to int,
i.e. in cases where the result/effect of a function is expected to be a modification of the int pointed to.
The need for a double pointer arises when the expected effect is a modification of a pointer.
The most popular need for having a pointer modified (or potentially modified) is the insertion, sorting or deletion operation of linked lists. The need to be able to modifiy the pointer which refers to the list (or the first element in the list).
For example StackOverflow has many questions along the lines of "Why does my linked-list deletion only work after the first element?".
About half of the answers propose to return the new head pointer and update it outside of the function. The other half recommends to use a double pointer to allow modifying it (the pointer-to head pointer) inside the function. Both works, it is a matter of taste/habit/opinion which approach to use.
You're ultimately setting it to an int value (10), so obviously an int** is not really needed in your example.
However, if you needed to set it to an int* value, then an int** would be needed.
For example:
void input(int** a) {
*a = (int*)malloc(sizeof(int));
}
int main()
{
int* a;
input(&a);
printf("%p", a);
free(a);
return 0;
}

Why the value stored in 'z' is 35? Shouldn't it be 20 since in the function 'c=*b' (c is equal to the value pointed by *b)?

In the following code:
#include <stdio.h>
void shuffle(int* a, int* b, int c) {
int temp = *a;
*a = *b + c;
c = *b;
*b = temp;
}
int main() {
int x = 10;
int y = 20;
int z = 35;
shuffle(&x,&y,z);
printf("x: %i\n", x);
printf("y: %i\n", y);
printf("z: %i\n", z);
return 0;
}
The value of 'z' remains 35. Why is that so? Shouldn't the value be 20? Since:
c = *b;
When you pass a, b and c as parameters you can notice something, that int c is not passed as a pointer. In C the parameters can be passed two ways.
The first is reference-passed parameter, the parameter is passed as the address of the variable, any change done to the content of that address will persist even out of the function.
The second way is to pass it as a by-value parameter, in that case, you only create a copy of the content of the "passed" variable to another.
Now, int* a is passed as a reference (because it is a pointer), lets say a=0x12341234(address of a) and its value is 10, and one more time, int c (not a pointer) has 0x10101010 as an address with a value of 35.
Then, when our function is called with a as a pointer and c as a normal integer, we can realize that inside the function the address of a stills 0x12341234, however, address of c is now 0x20202020(for example). We have created a copy of c in another place of the memory. Modifying a copied variable does not modify the original variable. This is like:
int original = 20;
int copy = original;//we see that copy is a COPY of original
copy = 321;//Original still being 20

C pointer referencing another pointer in functions

I discovered that if you assign a pointer address to another pointer's address in a FUNCTION it won't change the in value in the main,
however by doing the same thing in main, it will change. So what is the reason of this?
void func(int *a, int *b){
b = a;
}
int main(){
int i= 5, k =6, *a=&i, *b=&k;
printf("%d %d\n",*a,*b); //output 5 6
b = a;
printf("%d %d\n",*a,*b); //output 5 5
a=&i;
b=&k;
func(a,b);
printf("%d %d\n",*a,*b); //output 5 6
printf("%d %d\n",*a,*b); //output 5 6
}
In this function
void func(int *a, int *b){
b = a;
}
parameters a and b are local variables of the function. After exiting the function they will be destroyed. The function deals with copies of arguments. If you want that the function would change the original arguments themselves you have to pass pointers to them. For example
void swap(int **a, int **b){
int *tmp = *a;
*a = *b;
*b = tmp;
}
Your function:
void func(int *a, int *b){
b = a;
}
doesn't do anything, it just takes two values representing memory addresses as parameters and assigns one to the other without any external effect whatsoever. It just writes the value of the one to the other (probably not even that, because the compiler will likely detect this is pointless and eliminate it altogether), it doesn't do anything with the information stored at those addresses. You will need to deference the pointer to read or write to the memory address it holds the value of, but in the present form, the function will not assign the pointer to the other, but the value of i to k.
If you want a function to change a parameter outside of it, you should pass by reference, which in C is just pass by pointer, so you need to pass a pointer to the pointer, not the pointer - which will pass a copy of that pointer - the same value, while passing as pointer to pointer will pass the address of the pointer in memory, not the value it holds.
So it should be:
void func(int **a, int **b){
*b = *a;
}
and func(&a,&b) and you will reproduce what you do in main via b = a.

pointers and functions

how to return more than one value from a function?
A function can only have a single return value. You could either pack multiple values into a compound data type (e.g. a struct), or you could return values via function parameters. Of course, such parameters would have to be passed using pointers to memory declared by the caller.
1
Declare method like this foo (char *msg, int *num, int *out1, int *out2);
and call it like this
int i=10;
char c='s';
int out1;
int out2;
foo(&c,&i,&out1,&out2);
Now what ever values u assign to out1 and out2 in function will be available after the function returns.
2
Return a structure having more than one members.
In C, one would generally do it using pointers:
int foo(int x, int y, int z, int* out);
Here, the function returns one value, and uses out to "return" another value. When calling this function, one must provide the out parameter with a pointer pointing to allocated memory. The function itself would probably look something like this:
int foo(int x, int y, int z, int* out) {
/* Do some work */
*out = some_value;
return another_value;
}
And calling it:
int out1, out2;
out1 = foo(a, b, c, &out2);
You cannot return more than 1 value from a function. But there is a way. Since you are using C, you can use pointers.
Example:
// calling function:
foo(&a, &b);
printf("%d %d", a, b);
// a is now 5 and b is now 10.
// called function:
void foo(int* a, int* b) {
*a = 5;
*b = 10;
}
Functions can return arrays or lists

Why do these swap functions behave differently?

#include <stdio.h>
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void swap2(int *a, int *b)
{
int *temp = a;
a = b;
b = temp;
}
void swap3(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
main()
{
int a = 9, b = 4;
printf("%d , %d\n", a, b);
swap1(a, b);
printf("%d , %d\n", a, b);
swap2(&a, &b);
printf("%d , %d\n", a, b);
swap3(&a, &b);
printf("%d , %d\n", a, b);
}
C has value semantics for function parameters. This means the a and b for all your three swap variants are local variables of the respective functions. They are copies of the values you pass as arguments. In other words:
swap1 exchanges values of two local integer variables - no visible effect outside the function
swap2 exchanges values of two local variables, which are pointers in this case, - same, no visible effect
swap3 finally gets it right and exchanges the values pointed to by local pointer variables.
You're swap2 function has no effect.
You are passing in two pointers. Inside the function, the (parameter) variables a and b are local to the function. The swap2 function just swaps the values of these local variables around - having no effect outside the function itself.
As Anon pointed out, swap1 has the same problem - you're just modifying local variables.
swap1 will not work because the function just copied the arguments, not affecting the variables in main.
swap2 will not work either.
swap1() and swap2() have an effect limited to the scope of the function itself: the variables they swap are parameters passed by copy, and any change applied to them does not impact the source variable of your main() that were copied during the function call.
swap3 works as it acts on the values pointed by the parameters, instead of acting on the parameters themselves. It is the only of the three that chage the value located at the memory adress in which your main()'s a and b variables are stored.
Just for fun, exchange values without the use of a temporary variable
x = x ^ y
y = x ^ y
x = x ^ y

Resources