I am learning C programming and currently on Pointers.
#include <stdio.h>
void update(int *a,int *b) {
*a = *a + *b;
//*b = *a - *b;
printf("%d", *a - *b);
}
int main() {
int a = 4, b = 5;
int *pa = &a, *pb = &b;
scanf("%d %d", &a, &b);
update(pa, pb);
return 0;
}
I have no idea why it prints 4 instead of -1. I want to assign their difference in pointer *b. Any tip is appreciated.
In your case,
*a = *a + *b;
cout << *a - *b;
adds the value of *b to *a, and then subtract *b, so it's essentially the same as
cout << *a + *b -*b;
or
cout << *a;
which is 4 (assuming you entered the same value with which you initialized the variables in the code).
I have no idea why it prints 4 instead of -1.
Well, strictly speaking the code can't be said to print 4. Nor -1.
The code will print the first (integer) value that you type in the console (due to the scanf statement).
Your function alters a by adding b. But when you call printf you again subtract b so you print the original value of a which is the first input for the scanf.
I want to assign their difference in pointer *b
Well, then replace:
*a = *a + *b;
//*b = *a - *b;
with
//*a = *a + *b;
*b = *a - *b;
Now b contains the difference between the values read by scanf. To print it simply do:
printf("difference between scan'ed values: %d", *b);
BTW: For good coding style do this change:
scanf("%d %d", &a, &b); --> if(scanf("%d %d", &a, &b) != 2) exit(1);
also notice that functionally this is the same as:
if(scanf("%d %d", pa, pb) != 2) exit(1);
you could use conversion syntax:
int value;
value = (int)(*a) - (int)(*b);
printf(value);
this should do the trick. but if you'd like to get absolute value, then you'll need an IF-ELSE statements, like so:
int value;
if(*a > *b)
value = (int)(*a) - (int)(*b);
else
value = (int)(*b) - (int)(*a);
printf(value);
If your trying to Simulate by Reference your invoking the function wrong in update(pa, pb);
By calling update you are running that function you just need to re-assign the "updated" values back to the original value location like this: update(&a, &b);
Once you have updated the values print value a and you'll have -1
Related
I want to calculate the sum and absolute difference of the two variable in this program.
#include <stdio.h>
#include <stdlib.h>
void update(int *a,int *b) {
// Complete this function
*a= *a+*b;
*b= abs(a-b);
}
int main() {
int a, b;
int *pa = &a, *pb = &b;
scanf("%d %d", &a, &b);
update(pa, pb);
printf("%d\n%d", a, b);
return 0;
}
But for some inputs this doesn't produce correct outputs for the absolute difference.eg.(4,5) produce correct outputs; (2,6) doesn't. I am unable to figure out the mistake. What is the reason?
As pointed out in other answer subtracting two pointers is UB.
To answer other part of problem,
Try to understand what is happening to the pointer values at each point of arithmetic operation,
void update(int *a,int *b) {
// Complete this function
*a= *a+*b; //<< here *a has sum of *a and *b
*b= abs(*a-*b);
//here *a itself is *a +*b
//so entire operation is abs(*a + *b -*b) and hence *b will have value of abs(*a)
}
Try to have local variables to keep intermediate values and assign it at the end,
void update(int *a,int *b) {
int sum = *a + *b;
int diff = abs (*a -*b);
*a= sum;
*b= diff;
}
*b= abs(a-b);
You are subtracting the pointers, which is undefined behavior because they don't point into the same array. You want to be subtracting the numbers they point to. Make this
*b= abs(*a-*b);
`void f(int *a, int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}`
this code has no local variables and two int parameters
The code is used to swap two numbers. See the code :
#include<stdio.h>
void f(int *a, int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
int main()
{
int a = 9, b = 4;
f(&a,&b);
printf("Value of a is %d \n", a);
printf("Value of b is %d",b);
}
The output is :
Value of a is 4
Value of b is 9
It swaps the values of a and b. This is exploiting the properties of XOR that:
a ^ a == 0
a ^ 0 == a
So, in your code, first you replace a with a^b on line 1.
Then, on line 2 you do: (a ^ b) ^ b == a ^ (b ^ b) == a ^ 0 == a, and assign that to b. So, at this point b has the old value of a.
On line 3 you do the same thing as above, except this time the as get cancelled out, and you're left with the old value of b, which is then assigned to a
How do you save space using XOR in C?
Write code that does not fail with select values.
Write clear code that the compiler can readily optimize and then enable those optimizations. Possible use inline. With inline and your compiler does not optimize this well, get a better compiler.
/* inline */ void f(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
What does the code below do?
OP's code fails with f(&a, &b); when a,b point to the same place as it zeros out data.
Do not use.
Faulty tricks like the exclusive OR swap belong to an earlier era of weak compilers.
See How does XOR variable swapping work?.
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).
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.
Complete C newb here. Trying to learn/understand pointers by messing with simple code fragments.
#include <stdio.h>
void swap(int *px, int *py)
{
int tmp;
tmp = *px;
*px = *py;
*py = tmp;
}
main()
{
int *a, *b;
*a = 1;
*b = 2;
swap(&a,&b);
printf("%d %d\n", *a, *b);
}
Why is this not valid? The code works when I remove the dereferencing operator * from main.
Conceptually, this seems like it should work. I initialize a and b as pointers which point to int 1 and int 2, respectively. I then send their addresses to swap(), which should switch what they point to.
There are a couple of problems. First, the pointers a and b are not pointing to valid memory. So the assignment of the integer values is undefined (possible crash). Secondly, the call to swap (assuming a and b are pointing to valid memory) should not include the address (it is currently sending the address of the pointer variable).
The following changes would make it work:
int a, b;
a = 1;
b = 2;
swap(&a,&b);
printf("%d %d\n", a, b);
The swap() function is OK but inside main you are taking the addresses of pointers, so you're passing int** arguments to int* parameters.
int *a, *b;
swap(&a,&b);
To fix it, replace the code in main() with :
int a = 1, b = 2;
swap(&a,&b);
printf("%d %d\n", a, b);
Pointers point to data. A pointer itself doesn't comprise memory for storage, it just points to existing memory. So when you declare int *a; , you just have a garbage pointer with no useable value, and you mustn't dereference it.
The only sensible way to use pointers is to assign them the address-of something (or the result of some allocation function):
int i;
int *a = &i; // now a points to i
Therefore, the right way to use your swap function is to pass it addresses of integers:
int i = 10;
int j = -2;
swap(&i, &j);
a and b are uninitialized pointers, dereferencing them induces undefined behavior. You want:
int main() {
int a, b;
a = 1;
b = 2;
swap(&a,&b);
printf("%d %d\n", a, b);
return 0;
}
Your method signature is wrong. You ask for two pointers to int, yet you pass in two pointers to pointers to int.
When you say, " I then send their addresses to swap(), which should switch what they point to." Are you trying to change the address values within the pointer variables in main, to switch which bit of memory they are pointing to? In that case you will need another step of redirection:
#include <stdio.h>
void swap(int **px, int **py) {
int *tmp;
tmp = *px;
*px = *py;
*py = tmp;
}
int main (void) {
int x, y; /* storage to point to */
int *a, *b;
a = &x;
b = &y;
*a = 1;
*b = 2;
printf("(*a, *b, x, y) == (%d, %d, %d, %d)\n", *a, *b, x, y);
swap(&a, &b);
printf("(*a, *b, x, y) == (%d, %d, %d, %d)\n", *a, *b, x, y);
}
$ ./a.out
(*a, *b, x, y) == (1, 2, 1, 2)
(*a, *b, x, y) == (2, 1, 1, 2)
The x & y values have not changed, but a was pointing to x and now points to y and vice versa for b.