Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding pointers with a swap program in C

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)".

like image 438
Caleb Jay Avatar asked Aug 11 '15 18:08

Caleb Jay


2 Answers

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.

like image 171
Isaiah Avatar answered Sep 21 '22 09:09

Isaiah


&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.

like image 37
Marco Ramírez Avatar answered Sep 23 '22 09:09

Marco Ramírez