#include<stdio.h>
void swap(int *a,int *b){
int p=*b;
*b=*a;
*a=p;
/*int *p=b;
b=a;
a=p;
*/
}
int main(){
int a,b;
scanf("%d %d",&a,&b);
swap(&a,&b);
printf("%d %d",a,b);
}
Above is the code.
If I put 3 5 as an input, then it should swap its values, and 5 3 should come out as an output.
I got my answer by trying int p=*b thing
However I also tried commented part, but it didn't work.
So, I checked their address in swap and in main.
In swap int *a and int *b their address changed
However, when I came back to main, a and b 's addresses were not changed...
So first I thought: is it not changed in main because parameter int *a,int *b is local variable?
But I also learned that when pointers and arguments are used as arguments their value can change unlike other variables...
I really wonder why the second method(commented part) is not swapping the values...
If you want to change in a function original objects you have to pass them to the function by reference.
In C passing objects by reference means passing them indirectly through pointers that point to the original object.
Otherwise if you will pass the original objects themselves to the function the function will deal with copies of the objects. It is evident that changing copies does not influence on the original objects.
It is exactly what happens in this function
void swap(int *a,int *b){
int *p=b;
b=a;
a=p;
}
The function deals with copies of pointers passed to the function as argument in this call
swap(&a,&b);
That is the function indeed swapped values of the two pointers that are declared as its parameters. But they are not the original pointers passed to the function. They are copies of the pointers. So the values of the original pointers were not changed
The function swap in general can look the following way
void swap( T *a, T *b )
{
T tmp = *a;
*a = *b;
*b = tmp;
}
where T is same type specifier.
So if you want to swap objects of the type int then in the above function T will be int and the function will look like
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
If you want to swap values of pointers of the type int * then T will be int * and the function will look like
void swap( int **a, int **b )
{
int *tmp = *a;
*a = *b;
*b = tmp;
}
Here is a demonstrative program.
#include <stdio.h>
void swap1( int *pa, int *pb )
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void swap2( int **ppa, int **ppb )
{
int *tmp = *ppa;
*ppa = *ppb;
*ppb = tmp;
}
int main(void)
{
int a = 3, b = 5;
swap1( &a, &b );
printf( "a = %d b = %d\n", a, b );
// reset again the values of the variables
a = 3; b = 5;
int *pa = &a, *pb = &b;
swap2( &pa, &pb );
printf( "*pa = %d *pb = %d\n", *pa, *pb );
return 0;
}
Its output is
a = 5 b = 3
*pa = 5 *pb = 3
That is at first in the program two objects of the type int are swapped, So the imagined type specifier T is int.
Then two pointers that point to the objects a and b are swapped. So the imagined type specifier T int *.
After swapping the pointers the pointer pa now points to the object b and the pointer pb now points to the object a.
In the second method, you use the local variable that is limited in the scope of the function swap. So, the variable a or b in main function is different with variable a or b that is defined as the argument in the swap function.
When you use the pointer, the swap function will change the value that is pointed by the pointer (it means that the function change the value at the address of a and b that are declared in the main function).
Assuming you meant
void swap(int *a,int *b){
int *p=b;
b=a;
a=p;
}
That code just swaps the value of the pointers in the swap() function. That won't swap the addresses around in main() because, as you said, "parameter int *a,int *b is local variable".
When you call the function swap() like this
swap(&a,&b);
the addresses of a and b are passed and become local variables in the swap() function. You can't change the address of a or b - they have a location in memory.
In the code that works
void swap(int *a,int *b){
int p=*b;
*b=*a;
*a=p;
}
you don't change the value of the pointers, you change the values in the memory the pointers point to, which is why that works.
While C is pass-by-value, if you pass the address of something as the value a function can modify something outside its scope because you told the function where that variable is.
In C, all variables declared in a function are local to that specific function.
So, you wrote something in function swap
int *p=b;
What above code will do is, it will copy the value of b into p. So, when the function swap return, it's local variables p, b and a will vanished.
Related
I would like to swap two variables containing 2D arrays. I believe this can be simply done by swapping their pointers. I tried this code, but it does not work and I have no idea why, perhaps I am not understanding pointers correctly.
#include <stdio.h>
void swap(int ***a, int ***b) {
int ** temp = *a;
*a = *b;
*b = temp;
}
int main(void) {
int a[10][10];
int b[10][10];
a[1][5] = 4;
b[1][5] = 2;
printf("%d, %d\n", a[1][5], b[1][5]);
swap(&b, &a);
printf("%d, %d\n", a[1][5], b[1][5]);
return 0;
}
This outputs
4, 2
4, 2
I would expect it to output
4, 2
2, 4
So, what am I doing wrong?
a and b in main function are not pointers but arrays.
If you want to use pointers, use pointers.
#include <stdio.h>
#define N 10
void swap(int (**a)[N][N], int (**b)[N][N]) {
int (*temp)[N][N] = *a;
*a = *b;
*b = temp;
}
int main(void) {
int a[N][N];
int b[N][N];
int (*pa)[N][N] = &a;
int (*pb)[N][N] = &b;
(*pa)[1][5] = 4;
(*pb)[1][5] = 2;
printf("%d, %d\n", (*pa)[1][5], (*pb)[1][5]);
swap(&pb, &pa);
printf("%d, %d\n", (*pa)[1][5], (*pb)[1][5]);
return 0;
}
This would not work because what you are swapping is actually what the variables in the swap() function are pointing to, and not what they are pointing at. Its like if a was pointing at 5 and b was pointing at 6 in the swap() function, then it will make a point at 6 and b point at 5, without changing the contents of the memory. This would mean the in the main() function they would be residing at the same place and would be getting pointed by the same variable a and b (different from the variable in swap())
To swap you need to swap the contents of that memory in the swap() function, so that it is reflected in the main() function.
Recall that while doing swapping using pointers, one sends the address and actually swaps the content by dereferencing (*p and *q).
I am trying to better understand pointers and referencing in C, and my course provided the following program as an example.
#include <stdio.h>
void swap(int* a, int* b);
int main(void)
{
int x = 1;
int y = 2;
swap(&x, &y);
printf("x is %i\n", x);
printf("y is %i\n", y);
}
void swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
I shambled together the following to see if it would help me understand better what's happening, mainly in regards to the need to use & versus *(dereference). Basically, the syntax of declaring a pointer to int type (int* a) versus using an asterisk to "dereference" (*a = *b) is quite confusing to me, and I was hoping someone could enlighten me. Here's another version of the above that I thought would help clarify, but really doesn't:
#include <stdio.h>
void swap(int* a, int* b);
int main(void)
{
int x = 1;
int y = 2;
int *a = &x;
int *b = &y;
swap(a, b);
printf("x is %i\n", x);
printf("y is %i\n", y);
}
void swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
In short, my question is, is there a functional difference between what these two programs are doing? What is the difference between a dereference (*a = *b) versus using the & operator (*a = &x)".
You're confusing declaration and assignment.
*a = *bis called assignment. Notice it does not include a type name.
int *a = &x on the other hand is called declaration. Notice that you initialize the pointer with the address of x. You are not dereferencing the pointer, but are declaring it as a pointer to int.
Look at this:
int main() {
int a = 5;
int b = 2;
int *c = &a; // c when dereferenced equals 5; **Declaration**
int *d = &b; // d when dereferenced equals 2; **Declaration**
int tmp = *c; // tmp equals 5
*c = *d; // c when dereferenced now equals 2 **Assignment**
*d = tmp; // d when dereferenced now equals 5 **Assignment**
return 0;
}
Finally, when you declare and initialize a pointer in the same statement, you assign the pointer the address of what you want to have point at it. When you want to change the value the object points to, you dereference it using *. On the other hand, if you want to change what it points to, you do not dereference it.
&xreturns the address of x. x is of type integer and a is of type pointer to integer. In this case, (*a = &x), you are assigning the address of x to a variable of type "pointer to integer", which is a. (*a = *b) is a assign operation between two variables of the same type which is integer. I said integer because even though a and b are "pointers to integers", in that operation they are dereferenced and therefore the integer value to which these are pointed to is read.
The confusion I think you have is because (*a = &x) only makes sense during a pointer initialization.
If you set *a = *b since a and b are pointer variables, the * operator will retrieve the value of a cell in memory that b points to it and puts it to the cell that a points to it.
For *a = &x, the & operator finds the address of the cell that allocated to the x variable, and puts it in the cell that a points to it.
In short, my question is, is there a functional difference between
what these two programs are doing?
No, the functional effect is exactly the same. In
int *a = &x;
int *b = &y;
swap(a, b);
// swap(&a, &b)
The type of a is the same of &a, namely int* (pointer to int). The only difference is that you're using other variables to store that, which is not really needed logically but it is absolutely fine to have it, especially if it could help you understand the syntax.
What is the difference between a dereference (*a = *b) versus using &
(*a = &x).
*a = *b assigns the value pointed to by b (obtained with *b) in the ones pointed to by a. To see it more clearly,
int tmp = *b;
*a = tmp;
&(*a = &x) is not a valid expression because you can't store an address into an int (actually you can, but that's beyond the point).
In Dennis M Richies book "C programming language" it talks about pointers, and one of the examples is swapping two pointers:
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp
}
What's confusing me slightly is *a = *b. If b is already a pointer being passed in, why does it need to be dereferenced before assigning it to *a? Why wouldn't a = b work as their both pointers already?
a = b means you are assigning address of b to a which not the right way.
for swapping two numbers means you need to get value at that address and that value you have to swap.
so right way is to do *a = *b; i.e value at the address of b assigned to value at the address of a.
On doing a = b, both a and b will point to location pointed by b, this will defeat the purpose of passing a and b as reference; as the swap() will not be reflected after the function returns.
*ptr is dereferencing of the pointer.
*a = *b; means you are putting in the value contained at location b into the location where a points to. And this is what is required in the swap function.
a = b; means you are assigning value of pointer b to pointer a. This is not what you need in swap logic.
The reason for the confusing is that the function actually does not swap pointers.
Let's at first assume that the function has to swap pointers and its implementation has to be look as you think
void swap(int *a, int *b)
{
int *temp;
temp = a;
a = b;
b = temp
}
The function can be called the following way
int x = 10;
int y = 20;
int *px = &x;
int *py = &y;
swap( px, py );
Parameters of a function are its local variables that are initialized by arguments. So the function call can look the following way
void swap(/*int *a, int *b*/)
{
int *a = px;
int *b = py;
int *temp;
temp = a;
a = b;
b = temp
}
Within the function these local variables were swapped but the original arguments were not changed. Local variables a and b got copies of values stored in px and py. Thus after exiting the function these local variables will be destroyed and at the same time px and py will not be changed.
To change the pointers the function should look the following way
void swap(int **a, int **b)
{
int *temp;
temp = *a;
*a = *b;
*b = temp
}
In this case the function swaps values pointed to by pointers int **a and int **b and these values are values stored in px and py. Of course the function must be called like
swap( &px, &py );
Now let's return to the original function
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp
}
It is similar to the function that swaps pointers. However in this case it swaps objects pointed to by int *a and int *b.
I just started learning C and I was confused about why do I have to use pointers to implement a swap function?
Version where swap does not work:
#include <stdio.h>
void swap(int i, int j) {
int t = i;
i = j;
j = t;
}
int main() {
int a = 23, b = 47;
printf("Before. a: %d, b: %d\n", a, b);
swap(a,b);
printf("After. a: %d, b: %d\n", a, b);
return 0;
}
Version where swap works:
#include <stdio.h>
void swap(int *i, int *j) {
int t = *i;
*i = *j;
*j = t;
}
void main() {
int a = 23, b = 47;
printf("Before. a: %d, b: %d\n", a, b);
swap(&a, &b);
printf("After . a: %d, b: %d\n", a, b);
}
By default function arguments are passed by value in C and C++. This basically means a copy of the passed argument is received in the function. This copy is distinct from the passed variable and any change on this copy is not reflected back to the passed argument.
So your first snippet actually swaps copies of the passed arguments and not the arguments themselves.
For the swapping to be reflected back to the arguments being passed, You need to pass by reference, In C this is acheived by using pointers. Where the address of the arguments is passed to function and the function actually operates on the memory address passed to it, i.e: the original variable who's value is being passed.
swap(a,b);
void swap(int i, int j) {
int t = i;
i = j;
j = t;
}
The above code fails because, the variables i and j are local to the function swap , which means the variables have their scope limited to the function swap , and their life is lost once the function terminates.
One workaround is to use pass by address as shown in the code below...
swap(&a,&b);
void swap(int* i, int* j) {
int t = *i;
i* = *j;
j* = t;
}
Now the variables i and j, are pointers to original variables a and b , which means they are acting on behalf of a and b, and hence even if the pointers have limited scope within the function, they are able to indirectly modify variables a and b.
Why have you presented two programs back to back?Those are two separate programs.The first one ,despite all its fallacies about void main() and stuff, intends to(but doesn't,as it deals with local variables) swap values by using a function that is passed copies of the integer variables a and b.This is pass-by-value.In fact, C only has pass-by-value, despite what your book by Yeshwant Kanetkar says.Anyways, to make the first program work,use the printf() to display the swapped values inside swap() function itself,as being local variables the change in values won't show in main().
void swap(int i, int j) {
int t = i;
i = j;
j = t;
printf("After. a:%d,b:%d",i,j);
}
The second program, which he may claim uses pass-by-reference, is essentially pass-by-value where copies of the addresses of the variables are passed,not the actual addresses themselves.And again, despite it's non-portable eccentricities like void main(), it does swap the values of a and b.
void swap(int *i, int *j) {
int t = *i;
*i = *j;
*j = t;
}
Output Before. a:23 b:47
After. a:47 b:23
I ran it on CodeBlocks.But then your author Mr.Void Main must have suggested you to use 16-bit Turbo C eh?
You can not do swap this way:
void swap(int i, int j) {
int t = i;
i = j;
j = t;
}
because i and j are passed by value. That means that it is the same as local variable tmp. Thus, modifying of the i and j does not actually modify variables that you passed, as local copies of the i and j do not exist outside the function swap().
Because of it, if you need to modify i and j from main(), you have to pass to swap() addresses of i and j of the main().
That's why the following version is actually works.
void swap(int *i, int *j) {
int t = *i;
*i = *j;
*j = t;
}
EDIT: In order to understand these things better, I would like to recommend you Stanford Lectures Programming Paradigms, that are available at YouTube.
I want to write a method which takes two pointers to ints and changes the values they point to. Something like:
int main() {
int a = 3;
int b = 1;
change(&a, &b);
return 0;
}
void change(int *a, int *b) {
int t = a;
*a = *b;
*b = *t;
}
I have a problem understanding how to save a copy of a and point to it from b later.
You do it like this:
int temp = *a; // remember actual value "a" points to
*a = *b; // copy value "b" points to onto value "a" points to (will overwrite that value, but we have a copy in "temp")
*b = temp; // now copy value "a" originally pointed to onto value "b" points to
The code for change should be:
void change(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
Note that for accessing the value, you always have to use *X, so first t holds the value pointed to by a, and so on.
The * dereferences a pointer, this is like returning the variable that is pointed to. So storing a value into the dereferenced pointer will cause that value to be stored into the memory that is pointed to. So simply dereference both pointers and deal exclusively with the numbers, there is no need to go changing the pointers themselves.
void change(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
Indeed because you have used call-by-value for the arguments to the function swapping the memory addresses in the pointers within "change" will have no effect on the variables inside main at all.
In
void change(int *a, int *b) {
int t = a;
*a = *b;
*b = *t;
}
haven't you notice that a's type is int * while t's type is int, so you can't just assign a to t.