cpointersdereferenceaddress-operator

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


Solution

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