This question already has answers here:
Address of array VS pointer-to-pointer : Not the same?
(2 answers)
Closed 6 years ago.
Consider the below code snippet:
int x[] ={10,20,30,40,50};
int *p;
int **q;
p = x; /* Obviously p now holds base address of array. So no problem here */
q = &x; /* Error. Why? */
I am getting this error in gcc compiler.
error: cannot convert ‘int (*)[5]’ to ‘int**’ in assignment q = &x;
An array variable can be considered as constant pointer to first element of the array. Then why cant I assign the address of the constant pointer i.e) &x to pointer of pointer variable q ?
An array decays to a pointer in certain contexts, like assignment, or passing it to a function.
The address-of operator, &, does not decay the array into a pointer. It's as simple as that. Instead, you get a pointer to the array. In this case:
int (*q)[5];
q= &x; // Works just fine
Related
This question already has answers here:
Array changed in a void function, is still changed outside! why? (scope)
(4 answers)
Passing an array as a parameter in C
(3 answers)
Passing Arrays to Function in C++
(5 answers)
Passing an array as an argument to a function in C
(11 answers)
Closed 11 months ago.
I don't get it why you can alter the values inside the array, without using a reference or a pointer (&, *), I'm a freshmen student, and I don't know the reason behind, I hope someone can provide a logical answer, please refer to the code below, Thank You in Advance.
#include <iostream>
using namespace std;
void a(int x[]){
for(int i = 0; i < 5; i++){
x[i] += 2;
}
}
int main(){
int x[5] = {1,2,3,4,5};
a(x);
for(auto b : x){
cout << b << " ";
}
return 0;
}
A function parameter is never an array in C++. When you declare a function parameter as an array, it is automatically adjusted to be a pointer to element of such array. These declarations are effectively identical:
void a(int x[]); // looks like an array of int of unknown bound
void a(int* x); // declaration above is adjusted to this
void a(int x[1234]); // the size is ignored completely
An array implicitly converts to a pointer to the first element of the array (such conversion is called decay). Hence, you can call the function that doesn't accept an array parameter by passing an array argument:
int* ptr1 = x; // implicit conversion
int* ptr2 = &x[0]; // same conversion explicitly
a(x); // same conversion happens here
These two rules (function parameter adjustment and array to pointer decay) make it so that what syntactically looks like passing arrays by value, is actually done using indirection. Within the function, you modify the elements by indirecting through the pointer parameter that points to the array that exists outside of the function.
Important note: The adjustment of array to pointer in function parameter does not apply in other contexts. Arrays and pointers are distinct types with different properties.
Another note: The adjustment does not apply to parts of compound types. For example, a function parameter of type "pointer to array" will not be adjusted to be "pointer to pointer" and "reference to array" will not be adjusted to be "reference to pointer".
The parameter having the array type in this function declaration
void a(int x[]){
is adjusted by the compiler to pointer type to array elements type. That is the above declaration is equivalent to
void a(int *x){
In this call of the function
a(x);
the array designator is implicitly converted to pointer to its first element. That is the call is equivalent to
a( &x[0]);
So within the function you have a pointer to the first element of the array declared in main.
Using the pointer arithmetic you can access elements of the array. That is the elements of the array are passed to the function by reference in the C meaning indirectly through a pointer to them.
Within the function the variable x has the type int *. And this expression statement
x[i] += 2;
is equivalent to
*( x + i ) += 2;
Beacuse
void a(int x[]){
is the same as
void a(int *x){
and so you are using a pointer
Why?
Because an array like
int x[10];
'decays' to a pointer when passed to a function (and in other places). This can be very confusing but at the same time is very flexible
It mens that I can have a function like strlen that can accpet a 'real' array, or a pointer. These 'strings'
char *s1 = malloc(10);
strcpy(s1, "hello");
char s2[] = "hello";
char *s3 = "hello";
store their data in different ways but all can be handled by
size_t strlen(const char *s);
note that this is exactly the same as
size_t strlen(const char s[]);
they are 2 different ways of writing the same thing. Personal preference is for the second type if its really is an 'array' vs a pointer to maybe an array.
One issue with this 'decay' is that inside strlen (or any pointer/array accepting function) it is impossible to 'know' the length just from the parameter. The compiler knows that the size of s2 is 6 but this information is not carried forward to the function.
Regularly SO sees this
void my_func(int *arr){
int len = sizeof(arr)/sizeof(arr[0]);
....
}
int a[10];
my_func(a);
This will give len = 1 or 2 (depending on 32 or 64 bit machine), never 10
The flexibility costs a litle power
This question already has an answer here:
What's the meaning of * and & when applied to variable names?
(1 answer)
Closed 3 years ago.
What is the difference between these two operators?
My understanding is that they both point to the memory location of the variable they are used on.
Ex.
int p;
foo(*p,&p);
&p gets the pointer to the integer p -> That is, the memory address in which p is stored.
*p "dereferences" the pointer, i.e. looks at the object at the memory address provided by p and returns that object.
Your code above is invalid C, as you cannot dereference an int:
error: indirection requires pointer operand ('int' invalid)
Consider instead the following:
// Create an integer
int p = 1234;
printf("Integer: %d\n", p);
// Get the pointer to that integer, i.e. the memory address in which p is stored
int *pointer = &p;
printf("Pointer: %p\n", pointer);
// Dereference the pointer to get the value back
int q = *pointer;
printf("Dereferenced: %d\n", q);
Gives the following output:
Integer: 1234
Pointer: 0x7ffee53fd708
Dereferenced: 1234
Also notice that to print out a pointer address, we have to use a special format specifier %p instead of the %d we'd use for an int.
// declare an integer
int p = 42;
// declare a pointer type, and use it to store the address
// of the variable p.
int* ptr = &p;
// use the * to dereference the pointer, and read the integer value
// at the address.
int value = *ptr;
This question already has answers here:
When to use references vs. pointers
(17 answers)
Closed 7 years ago.
I am learning some C++, and I came across pointers and addresses. However, in none of the materials, I could find a good explanation on when to use pointer, and when to use address. As I understand it is that when I use pointer, I POINT to address in memory, where some variable is stored. So for example:
int x = 5;
int k* = &x;
Which will mean that:
k represents x
When I change k, I also change value of x.
My question is as follows: when should I use pointer, and when should I use address? When I declare a function, should I use pointer, or address as a variable?
You have a typo there. It should be:
int x = 5;
int *k = &x;
It should be read as: k points to x. Or if you insist on the "represent" word: *k represents x.
The & operator takes any variable as argument and returns its address (pointer). The * gets a pointer (address) as argument and returns the value stored there. As such they are opposite operations: &*k is the same as k and likewise *&x is just like x. You can look at these expression this way:
x //an integer
k //pointer to integer
&x //pointer to x
*k //integer pointed to by k
*&x //integer pointed to by a pointer to x, that is x
&*k //pointer to the integer pointed to by k, that is k
Note that operator & can only be used on variables, as expressions in general do not have addresses, only variables do (well, and temporaries, but that is another matter). For example, this expression is invalid:
&(x + 1) //error!
The funniest thing with these operator is how a pointer is declared:
int *k;
You might think that it would be better written as int &k, but that's not how declarators are read in C++. Instead, that declaration should be read as:
int (*k);
that is, *k is an integer, so it results that k is a pointer to an integer.
Now, the declaration with initialization is weirder:
int *k = &x;
should actually be read as:
int (*k);
k = &x;
That is, you declare *k as being an integer, thus, k is a pointer-to-integer. And then you initialize k (the pointer) with the address of x.
Actually you can create pointers of any type, even pointers to pointers, pointers to pointers to pointers... but note that this syntax is illegal:
int x;
int **p = &&x; //error, &x is not a variable
but this is valid:
int x;
int *k = &x;
int **p = &k;
If a variable stores an address of a memory location, it is considered a pointer. So an int * for example stores the address of an int-variable. By using the dereference-operator *, you can access the memory location at the address of the pointer and assign to it.
To get the address of a variable, you use the &-operator. This is what your example does. To assign to the memory-location where x is stored, you would use the derefence-operator again like this: *k = 0;
Note that the derefence-operator and the * to express a pointer type are two different things. * and & are each other's inverse (overloading aside) operators, while int * is a type.
In C++ in particular, if the & is used together with a type, the type of the variable is a reference-type, e.g. const string &s. Just like the pointer-type this is different from the address-of operator. Reference-types do not need to be derefenced using *, but will direcly modify the memory location they reference.
Pointer operator (*) is used whenever you want to point to a variable.
Address operator (&) is used whenever you point to the memory address of a variable.
This question already has answers here:
C: differences between char pointer and array [duplicate]
(14 answers)
C++ - Is an array a pointer? [duplicate]
(2 answers)
Closed 7 years ago.
char list[] = "World";
char *ptr = list + 2;
char **p = &ptr;
The question: Why is &ptr of type char**? I understand that p points to a pointer to an array but isn't the address of ptr a char*?
I have looked at Is an array name a pointer?, is it possible that the array is considered a pointer as well in this case?
Is array considered a pointer also?
No, pointers and arrays are distinct types. The confusion arises partly because in many cases pointers can decay to arrays, and in functions, array-like parameters are adjusted to pointers.
Why is &ptr of type char**?
Because ptr is of type char*. Applying the address-of operator to an object of a type gives you a pointer to that type.
I understand that p points to a pointer to an array
No, it points to a pointer, which points to an element of an array.
A pointer to an array is a different type altogether. For example, here a real pointer to an array is made to point to an array:
int a[8];
int (*arr)[8] = &a;
You have to follow things step-wise to easily understand this.
char* ptr is a pointer to char because it is pointing to a char.
What is p pointing at?
It is pointing at a char*. Therefore, it is a pointer to a pointer to a char. That is p is of type char**.
&ptr is a char ** simply because ptr is a char*. list is not a pointer, it's an array. But ptr is declared as char *, so it's a pointer.
ptr is initialised from a pointer list + 2. The expression list + 2 uses the operator +, which performs the array-to-pointer conversion on its operands (if applicable). Therefore, when evaluating list + 2, a temporary pointer to char is created from list using the array-to-pointer conversion. Then another temporary pointer is created by adding 2 to the first one, and this second temporary is then used to initialise ptr.
An array's name "decays" into a pointer to its first element under most circumstances.
In this case, the array consists of 2 bytes. Its name list is a char * pointing to the W.
Consequently, list + 2 points to the r. This pointer is stored into ptr, a char * as well.
A char * is a pointer to char. Consequently, a char ** is a pointer to a pointer to char, and that's exactly what &ptr is.
Array is not a pointer. It is an array. However, array can decay to pointer in certain contexts, of which most notable is passing an array to a function.
A pointer is also the first element of an array, so the address of the first element of the array and the pointer of the array would be the same
Hi I am learning C++ Primer and have a simple question. Please help me out.
So I know that "int *p = (*q)[10]" where p is a pointer to an array of 10. The question is, in a function definition: "void print(int (*q)[10])" where this pointer is a parameter. how could I get the copy of that pointer. Will that be "int *p = q"?
I technically don't know how to test my correctness in C++.
Thanks
int (*q)[10]
declares q as a pointer to array of 10 ints. Only arrays decay to pointers to their underlying type, but pointers to arrays do not decay to pointers to underlying type, so trying int* p = q; will result in a compilation error. What you need is
int (*p)[10] = q; // copies the pointer q to p