I wrote the following code:
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
char c;
int i;
short int j;
long int k;
float f;
double d;
long double e;
cout << "The size of char is: " << sizeof c << endl;
cout << "The size of int is: " << sizeof i << endl;
cout << "The size of short int is: " << sizeof j << endl;
cout << "The size of long int is: " << sizeof k << endl;
cout << "The size of float is: " << sizeof f << endl;
cout << "The size of double is: " << sizeof d << endl;
cout << "The size of long double is: " << sizeof e << endl;
system("pause");
return 0;
}
The purpose of this program is to print out the size of the fundamental data types, which I think I have accomplished. The other purpose of this program is to print the size of the pointer to each of these data types. I'm having a hard time figuring out how to do this. I understand that a pointer is a variable which stores the address of another variable and that pointers involve the deference operator (*). Can anyone please provide a suggestion? I'm not looking for the answer, just a nudge in the right direction.
int *p; // p is a pointer to an int
So sizeof the pointer would be: sizeof p, which you could print as:
cout << "The size of int pointer is: " << sizeof p << endl;
This is what you need to do print other pointers' sizes.
Dereferencing is only done when you want to access what a pointer is pointing to.
E.g.
int i = 5;
int *p = &i;
*p = 6;
*p = *p + 1;
//etc
Here, you just want to get the size of the pointers. So no dereferencing is needed.
Related
i have a code:
#include <iostream>
using namespace std;
int main()
{
int *a, y = 6 , *yPtr = &y;
cout << "y:" << y << "| &y:" << &y << "| yptr:" << yPtr << "| *yptr:" << *yPtr << " | &yptr:" << &yPtr << " |a:" << a << endl;
*a = y;
cout<< "a:"<<a<<endl;
return 0;
}
when i assign *a to y *a = y then *a value not printed for me
This is because you never initialize a itself. *a points to who-knows-where, some random location. So you set some random location to 6.
As it's probably pointed outside of legal space, your program is probably quitting before it gets to the cout statement.
I've been given a set of different Pointer to Pointer exercises. Each dereferencing an array of pointers. It's definitely challenging and confusing when analyzing them without a compiler. Does anyone have any systematic tricks to solve them?
int main(void)
{
const char* s[] = { "AB", "XY", "EZ"};
const char** z = s;
z += 1;
cout << "The value of **z is: " << **z << endl;
cout << "The value of *z is: " << *z << endl;
cout << "The value of **(z-1) is: " << **(z-1)<< endl;
cout << "The value of *(z-1) is: " << *(z-1)<< endl;
cout << "The value of z[1][1] is: " << z[1][1]<< endl;
cout << "The value of *(*(z+1)+1) is: " << *(*(z+1)+1)<< endl;
return 0;
}
I have another puzzle here, which is definitely a little bit shorter.
int foo[] = {1, 4, 9};
int bar[] = {16, 26, 36, 49};
int main(void){
int *x[2];
x[0] = bar;
x[1] = foo;
*x[1] = (*x)[1];
//What changes?
}
I was able to get the correct results after a while, but I cannot consistently get the correct answers.
I'm looking for a trick similar to reading a function containing "const" right to left. I.e.
const char **x;
"x is a pointer to a char pointer that is constant."
ANSWERS BELOW:
-
-
-
The answers are:
**z is X, *z is XY, **(z-1) is A, *(z-1) is AB, z[1][1] is Z, * ( *(z+1)+1) is Z.
There are no tricks, it's just a matter of understanding the mechanics of each piece of the puzzle. Let's break it down.
z += 1;
z starts at s[0], so now it's s[1].
cout << "The value of **z is: " << **z << endl;
**z is the same as *s[1], which is the same as s[1][0]. Which is 'X'.
cout << "The value of *z is: " << *z << endl;
*z is the same as s[1], which is a char* pointer pointing to XY.
cout << "The value of **(z-1) is: " << **(z-1)<< endl;
**(z-1) is the same as *s[0]. Which is 'A'.
cout << "The value of *(z-1) is: " << *(z-1)<< endl;
By now the pattern should be obvious, this is s[0] which is a pointer to "AB".
cout << "The value of z[1][1] is: " << z[1][1]<< endl;
z[1] is the same as *(z+1); since z is already s+1, that means the expression is the same as *(s+2) or s[2]. Taking an additional subscript from that is indexing into the pointer at s[2], so s[2][1] is the second character of the string or 'Z'.
cout << "The value of *(*(z+1)+1) is: " << *(*(z+1)+1)<< endl;
Working our way from the inside parenthesis out, *(z+1) we've already determined is s[2]. Adding 1 to that pointer gets to the second character just as in the previous example, and dereferencing that pointer with * results in the character 'Z'.
So I don't know if this is the most efficient way of doing it, but the way I understand it is that [] and * are almost interchangeable for pointer to pointers. It's almost like a 2D array. It's just that [] has a higher precedence than *.
Therefore, looking at **z, we can analyze it as z[0][0]. For a more challenging example, we can analyze **(z-1) as z[-1][0]. Finally, the most challenging, *(*(z+1)+1) can be analyzed as z[+1][+1].
So while studying for my exams I was trying to do a practice problem for pointers.
In the following code I'm trying to display the number of elements before the first occurrence of 0.
There is only one part that i didn't understand please see the 6th last line.
#include <iostream>
using namespace std;
int main()
{
int A[10];
for (int i = 0; i < 10; i++){
cout << "Please enter number " << i + 1 << " in the array: ";
cin >> A[i];
}
int *Aptr = A;
while(*Aptr !=0){
cout << *Aptr << "";
Aptr++;
}
cout << "\nThere are " << (Aptr - A) //Here is what i don't understand.
<< " numbers before the first occurrence of 0." << endl;
system("pause");
return 0;
}
So why exactly is (Aptr - A) giving me the number of elements instead of a memory location, and why is this even doable since Aptr is a pointer and A is an array?
Can someone explain to me in detail?
When used in an expression, like Aptr - A, the name of an array A will be implicitly converted to a pointer (equal to &A[0]).
Then the compiler is faced with subtracting two pointers of the same type (both of type int * in your case). That is specified as giving a value of type std::ptrdiff_t, which is, in turn "a signed integral type able to represent the result of subtracting two pointers".
Pointer arithmetic, when subtracting two pointers of type int (i.e. two int *s) gives the number of ints between the two pointers (assuming they are in the same object, which is true in this case, since Aptr points at an element of the array A).
Practically, if Aptr is equal to &A[i], the subtraction Aptr - &A[0] gives a std::ptrdiff_t equal to i.
Note: there is another problem in your code, as since the first (for) loop reads 10 values, while the second while loop keeps incrementing Aptr until it points at an int with value 0. If the user enters any zero values, the second loop will stop when it finds the first (even if the user enters non-zero elements after that). If the user enters no values equal to 0, then the while loop has undefined behaviour, since Aptr will keep walking through memory past the end of A until it happens to find memory that compares (as an int) equal to 0.
First of all, name of array A is associated to address of (pointer at) the first item in the array.
So why exactly is (Aptr - A) giving me the number of elements?
Because according to rules address arithmetic subtraction operation (also +, and similar) is performed based on the data type.
I mean, that compiler operating with int* makes ++, --, addition, subtraction an integer, etc. adds addresses needed for shifting to next/previous item.
If you really want to see how many bytes are located between addresses, just convert addresses to int before making subtraction:
cout << endl << "Address difference is " << int(Aptr) - int(A) << endl;
You can try that with different data types as follows:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int A[5];
short B[5];
unsigned char C[5];
cout << "Array (data type) | Syze of array | Size of item | Item distanse | Bytes distance" << endl;
cout << "A (int) :" << setw(10)
<< sizeof(A) << setw(15)
<< sizeof(A[0]) << setw(15)
<< &A[4] - A << setw(15)
<< int(&A[4]) - int(A) << endl;
cout << "B (short) :" << setw(10)
<< sizeof(B) << setw(15)
<< sizeof(B[0]) << setw(15)
<< &B[4] - B << setw(15)
<< int(&B[4]) - int(B) << endl;
cout << "C (un.char) :" << setw(10)
<< sizeof(C) << setw(15)
<< sizeof(C[0]) << setw(15)
<< &C[4] - C << setw(15)
<< int(&C[4]) - int(C) << endl;
system("pause");
return 0;
}
UPDATE
To be better prepared for your exam, consider the following example with pointers:
#include <iostream>
using namespace std;
int main()
{
int A[5] = {0}; // all items now are 0
int * P = A + 2; // the same as P = &A[2];
*P = 33; // writing to item A[2];
cout << A[2] << endl; // just to check in usual way
cout << *(A + 2) << endl; // using A as a pointer
cout << *(2 + A) << endl; // almost the same to previous
cout << 2[A] << endl; // quite strange, but it works
cout << 0[P] << endl; // and this is the same
return 0;
}
You must understand that 0[P] means for compiler *(0 + P), as well as 2[A] means - *(2 + A), but you should not write in your program in such style (exceptions are only cases when you want to confuse a reader).
And one more important thing - difference between array and pointer - are shown in the following example:
int A[] = {1, 2, 3, 4, 5};
int *P = A;
cout << "A = " << A << endl;
cout << "P = " << P << endl;
cout << "size of A = " << sizeof(A) << endl;
cout << "size of P = " << sizeof(P) << endl;
even if the addresses (vaules A and P) are equal, compiler works with array (A) in a different way than with pointer: sizeof(A) means memory allocated for whole array (5 items of sizeof(int) each), but sizeof(P) means memory allocated for data type int * (pointer to int). So, sizeof(P) depends only on compiler and OS platform (e.g. pointer can be 32-bit or 64-bit), but sizeof(A) depends on size of item (int may be not 32 bits) and NUMBER OF ITEMS in the array.
And you can "go to the next item" with pointer:
P++;
cout << *P << endl;
but you are not able to do:
A++;
because A is not variable of pointer type (it is just similar in sense of "address of the first item"), and compiler will say you something like:
error : '++' needs l-value
I'm just learning about function pointers in C++. The following examples do all compile and return the expected result, but I was taught that example 3 was the way to go. Why do the other examples still work?
There is another thing that seemed strange are the examples f,g,h,i which in contrast to the the examples above do not all work. Why don't they work, comparing to the examples 1-8?
int executeOperator1(int a, int b, int f(int,int)){
return f(a,b);
}
int executeOperator2(int a, int b, int f(int,int)){
return (*f)(a,b);
}
int executeOperator3(int a, int b, int (*f)(int,int)){
return f(a,b);
}
int executeOperator4(int a, int b, int (*f)(int,int)){
return (*f)(a,b);
}
int op(int x, int y){
return x+y;
}
int main(int argc, char *argv[])
{
int a = 2, b=3;
//the following 8 examples compile nicely:
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,op) <<endl; //1
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,op) <<endl; //2
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,op) <<endl; //3
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,op) <<endl; //4
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,&op) <<endl; //5
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,&op) <<endl; //6
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,&op) <<endl; //7
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,&op) <<endl; //8
//int f(int,int) = op; //does not compile
int (*g)(int,int) = op; //does compile
//int h(int,int) = &op; //does not compile
int (*i)(int,int) = &op;//does compile
return 0;
}
All your examples work because of wonderful so-called pointer decay rule. A function name decays to a pointer to function in almost all contexts. (Decay here means that original type information is lost, and all what is left is the pointer. Arrays do decay to pointers too in certain contexts).
So all your examples are semantically the same thing, and I would not call any of them preferred.
And just for the fun of it, this would compile too:
int executeOperator_insane(int a, int b, int f(int,int)){
return (***************f)(a,b);
}
Function, like arrays when passed as an argument to a function, decays into a pointer. For eg: A function taking two int parameters and returning an int would have a type of int (*) (int, int). But you can pass the function as reference as well, in which case you would have a type of int (&) (int, int).
To declare a value of type of above function pointer you would simply write :
typedef int (*FuncType) (int, int);
FuncType myFunc = op;
// OR
FuncType myFunc = &op;
The second way is usually preffered as it is more clear, but most of the compilers let the user do away with the first style.
Would recommend to go through below link:
http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions
When you use:
int f(int,int);
in main (or any place that is not an argument to a function), it declares f to be a function, not a pointer to a function. Hence, you cannot use
int f(int,int) = op;
On the other hand,
int (*g)(int,int) = op;
declares g to be a pointer to a function. Hence, it works.
When int f(int,int) is used as an argument to a function, it is equivalent to sing int (*f)(int, int).
I want to pass an array to a function, then point that array variable to a new address altogether within said function.
I realize that arrays behave as pointers to the adress of their first element when passed to a function, so why the heck won't the address change for my array variable in main?
#include <iostream>
using namespace std;
void passArrayByReference(int * array) { //passing array as. pointer should let us modify it's address, correct?
cout << "Address of array in function is: " << array << endl;
int * localArray = new int [2];
//put some dummy values in our localArray
localArray[0] = 9;
localArray[1] = 9;
array = localArray;
cout << "Address of array in function is now: " << array << endl;
}
int main()
{
int * array = new int [2];
int totalElements = 2;
//put some initial values into our dynamic 1D array
array[0] = 0;
array[1] = 1;
//print our initial values
for(int i = 0; i < totalElements; i++)
cout << array[i] << endl;
cout << "Address of array in main: " << array << endl;
passArrayByReference(array);
cout << "Address of array in main: " << array << endl;
return 0;
}
You are on the right track, but you just need to include the '&' symbol in your function header. The '&' symbol is used to pass an argument by reference, as opposed to by value.
In this case you are passing the address to the first element of your array by reference, meaning that you can modify that address in the function, and the changes will be reflected in your main function.
#include <iostream>
using namespace std;
void passArrayByReference(int * &array) {
cout << "Address of array in function is: " << array << endl;
int * localArray = new int [2];
//put some dummy values in our localArray
localArray[0] = 9;
localArray[1] = 9;
array = localArray;
cout << "Address of array in function is now: " << array << endl;
}
int main()
{
int * array = new int [2];
int totalElements = 2;
//put some initial values into our dynamic 1D array
array[0] = 0;
array[1] = 1;
//print our initial values
for(int i = 0; i < totalElements; i++)
cout << array[i] << endl;
cout << "Address of array in main is: " << array << endl;
passArrayByReference(array);
cout << "Address of array in main is now: " << array << endl;
//now print the values of our 'new' array
cout << "The values of array are now:" << endl;
for(int i = 0; i < totalElements; i++)
cout << array[i] << endl;
return 0;
}
First, you have to pass pointer by pointer or reference to make persistent change to it - that is change original pointer and not only copy of it in function body:
void passArrayByReference(int *&array) {
//...
array = new_address;
std::cout << "Address of array in function is now: " << array << std::endl;
}
// and here it is the same
And second you should assign valid address new_address and take care of memory that array referenced just before it entered the function, to avoid memory leak.
Pointers are variables as well.
That's why you need to pass array as a reference to passArrayByReference so you don't just modify the copy of it.
void passArrayByReference(int *&array)