Let's see the first code:
The following code displays the value of n=10:
#include<iostream>
int main()
{
int n=10;
int*p=&n;
*p++;
std::cout<<n;
return 0;
}
The following code displays the value of n=11:
#include<iostream>
int main()
{
int n=10;
n++;
std::cout<<n
return 0;
}
p++ increments the pointer. You would need (*p)++ to increment the value.
Operator precedence.
The first case is parsed as *(p++); - first increment the address and then dereference. This does not modify any values.
The second case merely increments the value itself.
Related
So, I was told to...
"Write a function Adder() that receives a pointer to an integer array as input, and uses this
pointer to return the sum of elements of the array."
And I was pretty successful. My code is
#include <bits/stdc++.h>
using namespace std;
int Adder (int *ptr)
{
int sum=0;
for (int i=0; i<5; i++)
{
sum=*(ptr+i)+sum;
}
return sum;
}
int main(){
int array[5]={1,1,1,1,1};
int sum;
int *ptr=array;
Adder(ptr);
sum=Adder(ptr);
cout<<sum;
}
The thing I can't understand is where I
Adder(ptr)
and then
int Adder (int *ptr)
"ptr" holds the address, right? While, " *ptr " holds the actual value. I can't understand how this worked. Can someone please explain?
The reason why this works is because adding 1 to an int pointer (in your case ptr) will actually add the size of an int (which can vary depending on the machine).
See the answers to this question for a more detailed explanation: Why a pointer + 1 add 4 actually
The line
int Adder (int *ptr)
defines a function that takes a pointer to an int as its argument. In this context, *ptr does not refer to the value ptr is pointing to.
The line
Adder(ptr);
invokes that function, passing the local pointer named ptr.
I made a recursive exponential function and originally called the recursive function as return num * power(num, exp--), however I had to change it to exp-1 because the first method broke the program. Why do I have to use exp-1?
#include <iostream>
using namespace std;
int power(int num, int exp);
int main()
{
cout << power(5, 3) << endl;
return 0;
}
int power(int num, int exp)
{
if (exp == 0)
return 1;
else
return num * power(num, exp-1);
}
That's because, exp-- firstly uses your value for invoking power() function and then gets decremented. In that case, the value passed to the function remains 3. Therefore, it goes into the infinite loop.
You should use either --exp or exp-1.
Why do I have to use exp-1?
You could also pre-increment --exp which gives you the incremented value.
Post-increment exp-- takes current value and decrements afterwards.
In your case that never changes the value.
You take current the value of exp and you're passing it by value to function.
You need --exp, not exp--. exp-- is post-decrement, meaning that it will only be executed after the function call. So, exp-- is not equivalent to exp-1 in your code, but --exp is: the value will be decremented first, and then the function will be called with the decremented value.
Is int &y=x same as int y=&x?
Are s++ and *s++ the same?
Also in the below code, why is *s++ giving me some wrong results?
I was expecting *s value to be 12
#include <iostream>
using namespace std;
int main()
{
int p=10;
int &q=p; //q is a reference variable to p
//int r=&p; //error: invalid conversion from 'int*' to 'int'
int *s=&p; //valid
q++;
*s++; //here even s++ works, and cout<<*s does not give 12 but some lengthy number
//and cout<<s gives some hexadecimal, I'm guessing thats the address
cout<<p<<endl<<q<<endl<<*s;
}
Output I'm getting:
11
11
6422280
int &y=x same as int y=&x.
In first y is an integer reference which is initialized to x . OTOH, in second you are trying to assign int a value of int * which results in a compilation error .
why is *s++ giving me some wrong results? I was expecting *s value to be 12
This is because ++ has precedence over * , therefore ,first s is incremented first (thus pointing to uninitialized memory location), and then dereferenced .
Which is leading to dereference of uninitialized memory location resulting in undefined behaviour.
If you want to expected value , you can do this -
(*s)++; //dereference first and then increment
Is int &y=x same as int y=&x?
No. They are very different.
int x;
int& y = x; // y is a reference to x.
On the other hand,
int x;
int y = &x; // Should be compiler error.
// Initializing y with a pointer.
The line:
*s++;
is equivalent to:
int* temp = s;
s++;
*temp;
You are evaluating *temp but the side effect is that you are incrementing s. After that s points to the next element. That is not a valid address though. The next time you access *s, the program exhibits undefined behavior. The output of the line:
cout<<p<<endl<<q<<endl<<*s;
can be anything.
Is int &y=x same as int int y=&x?
Not nearly. The first binds the x to the int-reference y, the second initializes the int y with the address of x.
Both can be made to compile cleanly, but the second only with severe contortions abusing operator overloading:
{
int y;
int& x = y;
}
{
// Only for demonstration, never do something this crazy for real
struct { int operator&() { return 0; }; } x;
int y = &x;
}
Are s++ and *s++ the same?
Certainly not, though they have the same effect in your example, as you discard the result:
The first increments s and returns its pre-increment value.
The second does the same, but then dereferences that.
In both cases, s thereafter points behind an object, and may not be dereferenced on pain of Undefined Behavior (UB).
Which explains the curious number you got, but might also have resulted in your program just printing 42 and then beginning to reformat your harddrive (legal but unlikely).
The questions I'm asking are very basic, but I'm trying to understand the behaviour of pointers in C++ by doing exercises in the compiler. So, for example, I start by declaring an int pointer *p and trying to ascribe it some values and print it:
#include <iostream>
using namespace std;
int *p, i;
int main(){
i=5;
p=&i;
cout<<*p<<endl;
return 0;
}
This is very clear and easy, right? But while I'm wondering why the C++ syntax works this way, I test another way of assigning a value to a pointer:
#include <iostream>
using namespace std;
int *p, i;
int main(){
i=5;
p=&i;
*p=3;
cout<<*p<<endl;
return 0;
}
Obviously, the result is different now. The question is, why this wouldn't work:
#include <iostream>
using namespace std;
int *p, i;
int main(){
*p=3;
i=5;
p=&i;
cout<<*p<<endl;
return 0;
}
Why do I have to dereference the pointer first before assigning it a value, but direct assignment would not work without dereferencing?
Also, if in the second example I wrote I added another assignment:
int main(){
i=5;
p=&i;
*p=3;
*p=6;
cout<<*p<<endl;
return 0;
}
This would not change the value stored at *p (it would still be 3). I don't simply want to learn by memorising this pointer behaviour, I'm interested in understanding why it works this way. Thanks.
#include <iostream>
using namespace std;
int *p, i;
int main(){
*p=3;
i=5;
p=&i;
cout<<*p<<endl;
return 0;
}
This doesn't work because you are trying to assign a value to the integer that p points to. That's what this line does:
*p = 3;
That means, "store the value 3 at the location which p points at". But p doesn't point at anything, because you didn't assign it to point to anything until two lines later.
p = &i;
That means, "assign the address of i to be the value of p". Or, in other words, "store the address of i in p". p needs to point to something, before you can assign to the thing p points to. Otherwise you have undefined behavior.
On the last section:
int main(){
i=5;
p=&i;
*p=3;
*p=6;
cout<<*p<<endl;
return 0;
}
You say this: "This would not change the value stored at *p (it would still be 3)." -- I'm not sure why you say that. Yes, it would change the value stored at *p (which is the value of i). It changes it to 6.
The question is, why this wouldn't work:
int *p, i;
int main(){
*p=3;
here you attempt to dereference p and write something, but since p is uninitialized here (it can be 0, for example), you are trying to write to memory that you didn't allocate, thus this is a segmentation fault.
Also, if in the second example I wrote I added another assignment: [...] This would not change the value stored at *p (it would still be 3).
Actually, it would. Why would you think otherwise?
I'm interested in understanding why it works this way.
You're on the right track, just continue reading (e.g. this thread) and experimenting!
int main()
{
int a[]={2,3,4,5,6};
int j;
for(j=0;j<5;j++)
{
printf("%d\n",*a);
a++;
}
return;
}
gives "Lvalue required" error but
int main()
{
int a[]={2,3,4,5,6};
int *p,j;
p=a;
for(j=0;j<5;j++)
{
printf("%d\n",*p);
p++;
}
return;
}
doesn't. why????
Though closely related, arrays are not pointers. The name of the array is just a label to identify some allocated memory (hence, the Lvalue error when you try to modify it).
An array is not a pointer. In most expressions, an array is converted to a pointer automatically. The result of this conversion is no longer the array; it is just a pointer value.
The ++ operator cannot operate on a mere value. It must have an object to act on.
For example, consider int x = 3; (x+5)++;. The result of x+5 is 8. It is not x. The result is just a value, not an object, so there is no object containing 8 that ++ can operate on. This is an error.
Similarly, if a is an array of int, then a++ is equivalent to ((int *) a)++. The ++ is not trying to act on the a; it is trying to act on the result of converting a to a pointer.
An array expression is always converted to a pointer to the first element except when the array expression is the operand of sizeof, &, or _Alignof or is a string literal used to initialize an array.
This will display all the array data.
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace std;
int main()
{
int a[]={2,3,4,5,6};
int *p,j;
p=a;
for(j=0;j<5;j++)
{
printf("%d\n",p[j]);
}
return 0;
}