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);
Related
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
#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.
void noOfClients(struct noOfClients *q );
I understand that a pointer's name holds the memory address of a variable.
But, when * comes with a pointer, it represents the content of that location.
In the above line of code, when passing a by reference, we'd say:
void noOfClients( &q);
But why?
Thank you.
* has different meaning when it is used in a variable/argument declaration and when it is used as a pointer dereference operator.
In a variable/argument declaration, it declares the variable/argument to be of a pointer type.
struct noOfClients *q
declares q to be a pointer to a struct noOfClients.
When used in an expression,
*q
dereferences where q points to.
PS
void noOfClients( &q);
is not the right way to call the function. Just use:
noOfClients(&q);
That will work if q is declared as an object.
struct noOfClients q;
noOfClients(&q);
void func(foo *a);
This is a function prototype of a function taking a pointer to a foo. Some people like to write this as
void func(foo* a);
There's no difference, but you might say that the function takes a "foo-pointer", rather than a "pointer to a foo".
a is a foo*
*a is a foo
There is no difference.
because & indicates the address of a particular variable and when you deal with functions so when you pass a variable to the function so you do some changes in that variable, sometimes the reflection of value are not done in that variable but if you pass a variable with its address then reflection will be done properly just try and understand following two codes it will sure help you
without &
#include <stdio.h>
void swap(int, int);
int main()
{
int x, y;
printf("Enter the value of x and y\n");
scanf("%d%d",&x,&y);
printf("Before Swapping\nx = %d\ny = %d\n", x, y);
swap(&x, &y);
printf("After Swapping\nx = %d\ny = %d\n", x, y);
return 0;
}
void swap(int a, int b)
{
int temp;
temp = b;
b = a;
a = temp;
}
with &
#include <stdio.h>
void swap(int*, int*);
int main()
{
int x, y;
printf("Enter the value of x and y\n");
scanf("%d%d",&x,&y);
printf("Before Swapping\nx = %d\ny = %d\n", x, y);
swap(&x, &y);
printf("After Swapping\nx = %d\ny = %d\n", x, y);
return 0;
}
void swap(int *a, int *b)
{
int temp;
temp = *b;
*b = *a;
*a = temp;
}
I am new to pointers.
For the below program , I get an answer of 255 and not 20. Please suggest how to correct.
Here is the code :
int sum(int *a , int *b);
int main()
{
int *p;
int *q;
*p =10;
*q =10;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
There is data, then there are pointers. For simplicity, once you have data, then you can point to it. This is accomplished by using the & operator. To go back to the data from a pointer, use the * operator as you have
Something more like
int sum(int *a , int *b);
int main()
{
int p_data=10;
int q_data=10;
int *p =&p_data;
int *q =&q_data;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
EDIT: Also note that pointers can be used to access memory allocated from malloc, or mmap'd, or other means
You need to alloc memory for pointers. This code should work:
#include <stdio.h>
#include <stdlib.h>
int sum(int *a , int *b);
int main()
{
int *p = (int*) malloc(sizeof(int));
int *q = (int*) malloc(sizeof(int));
if (p != NULL && q != NULL)
{
*p =10;
*q =10;
int c = sum(p,q);
printf("%d", c);
free(p);
free(q);
}
else
{
printf("Could not allocate enough memory");
return 1;
}
return 0;
}
int sum(int *a , int *b)
{
return (*a) + (*b);
}
Hope this helps!
A pointer is a variable that holds the address of another variable, and this seems clear to you. But what seems not still very clear is that when you create a pointer the compiler doesn't automagically create also a variable to point to...
In code:
int *p;
int *q;
*p =10;
*q =10;
You are defining p and q as pointers to int, but to which variables of type int they point? They have a garbage inside and can point anywhere, so when assigning 10 to what they point to, in reality, you are spamming somewhere in memory.
Under these conditions when you call sum I would expect more a memory fault than a strange value (255), but everything can happen with bad pointers, even to access an existing memory.
The correct code is:
int sum(int *a , int *b);
int main()
{
int i1, i2; //Allocate 2 int variables
int *p = &i1; //Create pointers and assign them
int *q = &i2; //the address of int vars i1 and i2
*p =10; //Initialize variables pointed by pointers with 10
*q =10;
int c = sum(p,q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
A pointer needs to be assign the address of some valid memory to point to before it may be dereferenced of the *-operator and gets written some data to where it points to.
You miss those very assignments.
Dereferencing a pointer implies reading out its value. If no value ever had been assigned to a pointer variable, already reading out its value might invoke the infamous Undefined Behaviour, anything can happen after this.
So your result could also have been just the famous 42.
Lesson learned: Never apply any operator to a variable which had not been properly been initialised.
Another approach. I think it may be useless for return function but it can help you about pointers It is passing pointer to the sum function
#include <stdio.h>
int sum(int *a , int *b);
int main()
{
int p = 10;
int q = 10;
int c = sum(&p,&q);
printf("%d",c);
}
int sum(int *a , int *b)
{
return((*a)+ (*b));
}
You're getting 255 is because of random luck. I get 20 when I compile it, but that's also random luck. The technical term is "undefined behavior", and this is undefined because you never initialized your int *p and int *q pointers.
What's inside your pointer variables? You don't know, I don't know, nobody does. Since you never initialized them, their contents are whatever bits were there before initialization. It's like moving into a house and getting whatever junk the previous tenants left for you.
If the contents of the pointers are addresses in memory (and they don't overlap), then the value returned should be 20 (by random luck). But if one of them contains a null address, who knows what you'll get!
If you want to get 20 reliably, you need to allocate memory:
In C++:
int * p = new int;
int * q = new int;
In C:
int * p = (int*)malloc(sizeof(int))
int * q = (int*)malloc(sizeof(int))
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.