I was trying to understand pointers in C and wrote this code
#include <stdio.h>
int swap(int *fa,int *fb){
int temp = *fa;
*fa = *fb;
*fb = temp;
}
int main(){
int a=5,b=7;
int *pa = &a;
int *pb = &b;
swap(pa,pb);
printf("%d\n",*pa);
printf("%d\n",*pb);
printf("%d\n",a);
printf("%d",b);
}
now the output(as expected) is
7
5
7
5
I am having a bit of understanding of what is happening but I have a confusion that
fa = pa // fa points to what pa points to which means a
fb = pb // fb points to what pb points to which means b
IS THIS WHAT IS HAPPENING
Or is it that fa and fb effect pa and pb first, which in turn effect a and b.
- right after I call the swap function, this happens
fa = pa // fa points to what pa points to which means a
fb = pb // fb points to what pb points to which means b
If you mean after entering swap
then yes. That is correct. Parameters are passed as a copy, which means inside that function fa
and fb
get a copy of pa
and pb
from the caller.
- we swap values of fa and fb, which in turn swap values of a and b, since pa and pb points to a and b they also point to these new values.
No. fa
and fb
are not touched at all. They are dereferenced. This means, the address where they point to, is affected. You can use printf
to print the content of those pointer variables. They will not change. Instead the content of a
and b
are changed.
BTW: Your printf
statements don't make much sense. You should print both before and after the function call to see any effect.
For starters pay attention to that your function swap
having the return type int
returns nothing.
int swap(int *fa,int *fb){
The return type int
does not make a sense.
The function can be declared like
void swap(int *fa,int *fb);
The function swap does not swap the values of its arguments.
int swap(int *fa,int *fb){
int temp = *fa;
*fa = *fb;
*fb = temp;
}
It swaps the pointed to by the arguments objects because within the function there are used expressions that dereference the pointers like
*fa
or *fb
.
Here is a demonstrative program that shows that the values of the pointers fa
and fb
are not changed.
#include <stdio.h>
void swap(int *fa,int *fb){
printf( "fa = %p, fb = %p\n", ( void * )fa, ( void * )fb );
int temp = *fa;
*fa = *fb;
*fb = temp;
printf( "fa = %p, fb = %p\n", ( void * )fa, ( void * )fb );
}
int main(void)
{
int a=5,b=7;
int *pa = &a;
int *pb = &b;
swap(pa,pb);
return 0;
}
The program output might look like
fa = 0x7ffff85444f0, fb = 0x7ffff85444f4
fa = 0x7ffff85444f0, fb = 0x7ffff85444f4
As it is seen the pointers have the same values in the beginning and the end pf the function. It is the values of the pointed objects that are swapped.
And the pointers fa
and fb
do not affect the pointers pa
and pb
declared in main. Because the pointers fa
and fb
being local variables of the function get copies of the values stored in the pointers pa
and pb
.
When you pass the pointers to your function, you pass a variable which contains an address. When you dereference fa (or fb), you get the actual value at that address. So when you modify it, you modify the value for both pointers since they point to the same adress.
To understand pointers better you can go with actual fake addresses. Let's say that variable 'a' is stored at address 0x9000 in RAM and variable 'b' is stored at address 0x10000.
#include <stdio.h>
int swap(int *fa,int *fb){ //fa and fb are variables of type pointer which contain 0x9000 and 0x10000 respectively
int temp = *fa; //temp contains the content of address 0x9000 (a)
*fa = *fb; //address 0x9000 contains content of address 0x10000 (b)
*fb = temp; //address 0x10000 contains content of temp (a)
}
int main(){
int a=5,b=7;
int* pa = &a; //pa is a variable of type pointer which contains 0x9000
int* pb = &b; //pb is a variable of type pointer which contains 0x10000
swap(pa,pb);
}
Don't forget that int* is a variable of type pointer to an int. What it means is that the variable contains an address of a variable of type int. In reality it just points to memory. You could write something like
int* a = 0x9000;
You would have a pointer of type int which points to address 0x9000. That would be valid syntax but your OS would complain that you don't have access to that address. If you write
long* a = 0x9000;
The only difference is the amount of bytes you get when dereferencing. When you dereference a pointer you get the amount of bytes that the type contains. With the type int*, when you dereference you'll get 4 bytes (32 bits) starting at address 0x9000. With type long* you'll get 8 bytes (64 bits) starting at address 0x9000.
The size of a variable of type int* or long* is the same since this depends only on the architecture of you CPU. So with both of these you'll get a variable of type pointer which has the same size. The only difference is the amount of bytes you get when dereferencing.
we swap values of fa and fb, which in turn swap values of a and b, since pa and pb points to a and b they now point to these new values.
No - you swap the values of what fa
and fb
point to , which is a
and b
respectively. The values of fa
and fb
(along with pa
and pb
) never change.
I modified your code as follows:
#include <stdio.h>
#include <stdlib.h>
void swap(int *fa,int *fb){
printf( "Entering swap: fa = %p, fb = %p, *fa = %d, *fb = %d\n", (void *) fa, (void *) fb, *fa, *fb );
int temp = *fa;
*fa = *fb;
*fb = temp;
printf( "Leaving swap: fa = %p, fb = %p, *fa = %d, *fb = %d\n", (void *) fa, (void *) fb, *fa, *fb );
}
int main(){
int a=5,b=7;
int *pa = &a;
int *pb = &b;
printf( "Before swap: a = %d, b = %d, pa = %p, &a = %p, pb = %p, &b = %p, *pa = %d, *pb = %d\n",
a, b, (void *) pa, (void *) &a, (void *) pb, (void *) &b, *pa, *pb );
swap(pa,pb);
printf( "After swap: a = %d, b = %d, pa = %p, &a = %p, pb = %p, &b = %p, *pa = %d, *pb = %d\n",
a, b, (void *) pa, (void *) &a, (void *) pb, (void *) &b, *pa, *pb );
return EXIT_SUCCESS;
}
When run, it gives the output 1 :
Before swap: a = 5, b = 7, pa = 0x7ffee8f43a60, &a = 0x7ffee8f43a60, pb = 0x7ffee8f43a5c, &b = 0x7ffee8f43a5c, *pa = 5, *pb = 7
Entering swap: fa = 0x7ffee8f43a60, fb = 0x7ffee8f43a5c, *fa = 5, *fb = 7
Leaving swap: fa = 0x7ffee8f43a60, fb = 0x7ffee8f43a5c, *fa = 7, *fb = 5
After swap: a = 7, b = 5, pa = 0x7ffee8f43a60, &a = 0x7ffee8f43a60, pb = 0x7ffee8f43a5c, &b = 0x7ffee8f43a5c, *pa = 7, *pb = 5
So, we can see the following are all true:
fa == pa == &a
*fa == *pa == a == 5 // before swap, 7 after swap
fb == pb == &b
*fb == *pb == b == 7 // before swap, 5 after swap
fa
and pa
and &a
are all the same value.
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.