Understanding pointers with a swap program in C
Asked Answered
H

4

7

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

Hiatus answered 11/8, 2015 at 18:27 Comment(0)
H
6

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.

Hoary answered 11/8, 2015 at 18:32 Comment(2)
Ah, click! Thank you!Hiatus
If it helps to understand, write int* x instead of int *xMccafferty
L
5

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

Liva answered 11/8, 2015 at 18:44 Comment(0)
S
1

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.

Subclinical answered 11/8, 2015 at 18:44 Comment(2)
You cannot *a = &x without an explicit cast.Altitude
It will be. If you don't get any, file a bug to your compiler.Altitude
A
-1

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

Altitude answered 11/8, 2015 at 18:50 Comment(4)
What's the reason for downvoting?Altitude
You misread the last part of his question. He meant & (*a = &x). Norice how I separated the & from the parenthesisHoary
@Hoary I did cover that. The expression is not valid and cannot compile.Altitude
Apologies for the confusion, I do appreciate your help though.Hiatus

© 2022 - 2024 — McMap. All rights reserved.