C: switch pointers to integers - c

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.

Related

Pointer Confusion: swap method in c

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

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

Confusion when Swapping Pointers

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.

C function with pointers work on one computer, and doesn't work on another

#include <stdio.h>
void swap (int *a, int *b)
{
int *tmp;
*tmp = *a;
*a = *b;
*b = *tmp;
}
int main ()
{
int x = 5;
int y = 7;
swap (&x,&y);
printf ("\n x = %d \n y = %d \n",x,y);
}
I'm using codeblocks, and this code won't work, and I don't understand why... On one computer it works perfectly but on the other it won't run at all.
Any help?
Thanks in advance.
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
What you need is a variable tmp to store the value and not a pointer *tmp.
The below code really a poor way of doing this but
int *tmp = malloc(sizeof(int));
*tmp = *a;
*a = *b;
*b = *tmp;
Once done please free the memory using
free(tmp);
Gopi already corrected your code - adding on to the previous answer - i think this is good to know information for a newbie:
Section 4.1 states:
An lvalue (3.10) of a
non-function, non-array type T can be
converted to an rvalue. If T is an
incomplete type, a program that
necessitates this conversion is
ill-formed. If the object to which the
lvalue refers is not an object of type
T and is not an object of a type
derived from T, or if the object is
uninitialized, a program that
necessitates this conversion has
undefined behavior. If T is a
non-class type, the type of the rvalue
is the cv-unqualified version of T.
Otherwise, the type of the rvalue is
T.
When you try to dereference and uninitialized pointer the behavior is undefined. Undefined means anything can happen - there is no guarantee. So you can get different behavior in different environments.
From Wiki Making pointers safer
A pointer which does not have any address assigned to it is called a wild pointer. Any attempt to use such uninitialized pointers can cause unexpected behavior, either because the initial value is not a valid address, or because using it may damage other parts of the program. The result is often a segmentation fault, storage violation or wild branch (if used as a function pointer or branch address).
What you did here:
int *tmp;
*tmp = *a;
is that you created a pointer to int which is not pointing to anything - basically it contains some junk value (could be your pincode even - who knows).
Your mistake was to use uninitialized memory. Always allocate memory to a pointer before using it. Next, don't forget to free the allocated memory after you're done with it.
Also, you should add return 0; at the end of your main() function.
If you don't mind a second opinion, check the below code.
#include <stdio.h>
#include <stdlib.h>
void swap (int *a, int *b)
{
int *tmp = malloc(sizeof(*tmp));
*tmp = *a;
*a = *b;
*b = *tmp;
free(tmp);
}
int main ()
{
int x = 5;
int y = 7;
swap (&x,&y);
printf ("\n x = %d \n y = %d \n",x,y);
return 0;
}
If you want to use pointers, although it does not make any sense at all
void swap(int *a, int *b)
{
int tmp[1];
*tmp = *a;
*a = *b;
*b = *tmp;
}
here tmp is not strictly a pointer, but you can use the * indirection operator on it.
Or
void swap(int *a, int *b)
{
int value = *a;
int *tmp = &value;
*tmp = *a;
*a = *b;
*b = *tmp;
}
Or you can use malloc as Gopi already pointed out.
If you want to use pointers, then do use pointers:
#include <stdio.h>
void swap (int ** ppx, int ** ppy)
{
int * p = *ppx;
*ppx = *ppy;
*ppy = p;
}
int main (void)
{
int x = 5;
int y = 7;
int * px = &x;
int * py = &y;
printf ("\nx = %d\ny = %d\n", *px, *py);
swap (&px, &py);
printf ("\nx = %d\ny = %d\n", *px, *py);
return 0;
}
Result:
x = 5
y = 7
x = 7
y = 5

Change value of variable with a pointer?

I am new with pointers and I am trying to create a function that changes value of variable a to variable b, and the value of variable b to variable a.
I think I have everything right except the function. In the function I am trying to make the value of pointer a (*a) and assign it to the value pointer b has, and vice verca. However my output is "a is now y and b is now y".
Is this because when I assign *a to b, b will get *a's value which just changed to an y?
#include <stdio.h>
void change(char* a, char* b)
{
*a = b;
*b = a;
}
int main(void)
{
char a = 'x';
char b = 'y';
printf("a is now %c and b is now %c\n", a, b);
change(&a, &b);
printf("a is now %c and b is now %c\n", a, b);
return 0;
}
Your change function is wrong:
void change(char* a, char* b)
{
char temp = *a;
*a = *b;
*b = temp;
}
First make a temporary variable - copy it in a temp variable, then swap the value. This line is UB:
*a = b;
*b = a;
You are trying to store a pointer's value in a char.
Yes, your first assignment overwrites the value that is needed in the second one.
The solution is to use some temporary storage to hold the one of the variable values during the swap:
void change(char *a, char *b)
{
const char old_a = *a;
*a = *b;
*b = old_a;
}
There is also a trick you can do to go around this (using bitwise XOR), but it's scary so ignore it at this point.

Resources