something in the pointer confuse me
to declare a pointer to int and then define it
int *p, a;
p = &a;
a = 3;
it can be changed into
int a = 3;
int *p = &a;
I'm confused in the latter case. Isn't the value of *p is the value of the object which p point to ( the value of a in this example) so why in the former case it's
int *p = &a;
which is the address of a but not the value of a. Shouldn't it be
int p = &a
in order to state that p is the pointer and the address it point to is the address of the object a
Additionally, I see in some case there is (int*) p. Does it have any different to normal declaration?
* in declaration
int *p = &a;
is not an indirection operator. It just inform the compiler that p is a pointer type. * acts a dereferencing operator only when it appears in a statement. This means that *p in int *p = &a; is not same as *p as an alias of a.
Related
In C, the statement int *var_name; by convention means that *var_name is of type int, which implies that var_name is an integer pointer.
But now consider this sequence of statements.
int a = 5;
int *var_name = &a;
But here how are we assigning address of a to *var_name which is of type int?
You are not assigning the address to *var_name, but to var_name. And this variable is of type "pointer to int", as you found.
Oh, and it is an initialization, not an assignment.
That's just the way the syntax in C works.
int *p = &a;
is completely equivalent to:
int *p;
p = &a;
It's not so difficult to understand why it would not make sense if it worked the way you thought. Consider this code:
int *p;
p = &a;
*p = 42;
Now imagine flipping the last two statements, like this:
int *p;
*p = 42; // To which address do we write 42? p is not initialized.
p = &a;
So although the meaning of int *p = &a;, which is int *p; p = &a; might be unintuitive, it's actually the only sane way to define it.
In this declaration:
int *var_name = &a;
there is declared the variable var_name of the pointer type int * and this variable (pointer) is initialized by the address of the variable a.
It seems you mixing the symbol * in declarations and in expressions.
In declarations it denotes a pointer. In expressions it denotes the dereference operator.
Consider the following demonstration program:
#include <stdio.h>
int main( void )
{
int a = 5;
int *var_name = &a;
printf( "The address stored in var_name is %p\n", ( void * )var_name );
printf( "The address of the variable a is %p\n", ( void * )&a );
printf( "The value of the object pointed to by var_name is %d\n", *var_name );
printf( "The value stored in the variable a is %d\n", a );
}
Its output might look like
The address stored in var_name is 00EFFAC0
The address of the variable a is 00EFFAC0
The value of the object pointed to by var_name is 5
The value stored in the variable a is 5
That is in this line:
int *var_name = &a;
*var_name means a declarator of a pointer type.
In this call:
printf( "The value of the object pointed to by var_name is %d\n", *var_name );
*var_name means an expression with the dereference operator *.
Code
short **p = (short **)malloc(sizeof(short *));
*p = malloc(sizeof(short));
**p = 10;
printf("**p = %d", **p);
Output
**p = 10
In this code, a multiple pointer **p is declared and *p is used without any declaration(maybe it's by **p).
What does *p mean in my case? Sorry for very simple question.
I saw C standard and stack overflow, but I couldn't find out something.
For any array or pointer p and index i, the expression p[i] is exactly equal to *(p + i) (where * is the unary dereference operator, the result of it on a pointer is the value that the pointer is pointing to).
So if we have p[0] that's then exactly equal to *(p + 0), which is equal to *(p) which is equal to *p. Going backwards from that, *p is equal to p[0].
So
*p = malloc(sizeof(short));
is equal to
p[0] = malloc(sizeof(short));
And
**p = 10;
is equal to
p[0][0] = 10;
(**p is equal to *(*(p + 0) + 0) which is equal to *(p[0] + 0) which is then equal to p[0][0])
It's important to note that the asterisk * can mean different things in different contexts.
It can be used when declaring a variable, and then it means "declare as pointer":
int *p; // Declare p as a pointer to an int value
It can be used to dereference a pointer, to get the value the pointer is pointing to:
*p = 0; // Equal to p[0] = 0
And it can be used as the multiplication operator:
r = a * b; // Multiply the values in a and b, store the resulting value in r
short **p = (short **)malloc(sizeof(short *));
This line declares a pointer to a pointer p. Additionally the value of p is set to the return value from malloc. It is equivalent to
short **p;
p = (short **)malloc(sizeof(short *));
The second line
*p = malloc(sizeof(short));
Here *p is the value of p. *p is of type pointer. *p is set to the return value of malloc. It is equivalent to
p[0] = malloc(sizeof(short));
The third line
**p = 10;
**p is the value of the value of p. It is of type short. It is equivalent to
p[0][0] = 10
In effect what the code above does is to allocate a 2D array of short, then allocate memory for the first row, and then set the element p[0][0] to 10.
As a general comment on your code, you should not use typecast in malloc. See Do I cast the result of malloc?
What does *p mean when **p is already declared?
short **p = (short **)malloc(sizeof(short *));
(better written as)
short **p = malloc (sizeof *p);
Declares the pointer-to-pointer-to short p and allocates storage for a signle pointer with malloc and assigns the beginning address for that block of memory to p. See: In C, there is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?
*p = malloc(sizeof(short));
(equivalent to)
p[0] = malloc (sizeof *p[0]);
Allocates storage for a single short and assigns the starting address for that block of memory to p[0].
**p = 10;
(equivalent to)
*p[0] = 10;
(or)
p[0][0] = 10;
Assigns the value 10 to the dereference pointer *p[0] (or **p or p[0][0]) updating the value at that memory address to 10.
printf("**p = %d", **p);
Prints the value stored in the block of memory pointed to by p[0] (the value accessed by dereferencing the pointer as *p[0] or **p)
The way to keep this straight in your head, is p is a single pointer of type pointer-to-pointer-to short. There are 2-level of indirection (e.g. pointer-to-pointer). To remove one level of indirection, you use the unary * operator, e.g.
*p /* has type pointer-to short */
or the [..] also acts as a dereference such that:
p[0] /* also has type pointer-to short */
You still have a pointer-to so you must remove one more level of indirection to refernce the value stored at the memory location pointed to by the pointer. (e.g. the pointer holds the address where the short is stored as its value). So you need:
**p /* has type short */
and
*p[0] /* also has type short */
as would
p[0][0] /* also has type short */
The other piece to keep straight is the type controls pointer-arithmetic. So p++ adds 8-bytes to the pointer-to-ponter address so it now points to the next pointer. If you do short *q = (*p)++; (or short *q = p[0]++, adds 2-bytes to the address for the pointer-to-short, soqnow points to the nextshortin the block of memory beginning at*p(orp[0]`). (there is no 2nd short because you only allocated 1 -- but you get the point)
Let me know if you have further questions.
Let me put it in different way,
consider an example,
int x;
int *y = &x;
int **z = &y;
x = 10;
Which simplifies to this,
Note: Only for illustration purpose I have chosen address of x,y,z as 0x1000,0x2000,0x3000 respectively.
What does *p mean in my case?
In short the snippetshort **p = (short **)malloc(sizeof(short *)); is dynamically allocating a pointer to a pointer of type short i.e same asy in my example.
int num = 78;
int *p;
int array[SIZE] = {0,1,2,3,4};
char c[SIZE] = {'A', 'B', 'C', 'D', 'E'};
p = array[3];
*p = (int) *c;
p++;
array[4] = num;
p++;
p = c;
p++;
I'm trying to figure out the memory behind this above code. I understand that the pointer p initially points to the 3rd element of the array(which is 3). I have no idea what the next line *p = (int) *c; means. Can anyone please explain that line of code??
Edit:
After the p is incremented as such can anyone explain what it would be pointing to?
You should use 'p = &array[3];'. The pointer will then point to the third element of the array i.e. 'C'
*p = (int) *c;
c[size] is an array. c is the base pointer of the array. so *c is the value at the base pointer which is 'A'. This statement will put 'A' in the third element of the array. So the array now contains A, B, A, D, E
p = array[3]; // int * = int
is an error; the types don't match, and the compiler will yell at you for it. The type of p is int *, and the type of array[3] is int.
There are two ways to fix this, depending on what you want to do. If you want to set p to point to array[3] (which is what you want to do in this case), you would write
p = &array[3]; // int * = int *
If you want to write the value of array[3] to the object that p points to (which is not what you want to do in this case, since p isn't pointing anywhere valid yet), you would write
*p = array[3]; // int = int
In this case, we want to set p to point to array[3], so we use the first statement. After doing that, the following are true:
p == &array[3] // int *
*p == array[3] == 2 // int
Now we have the statement
*p = (int) *c;
is saying "take the value of the char object that c points to, convert it to an int value1, and assign the result to the object that p points to."
Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize an array of char in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.
The expression c has type "5-element array of char". Since it is not the operand of the sizeof or unary & operators, it is converted to an expression of type char *, and the value of the expression is the address of the first element in the array, c[0]. Thus:
c == &c[0] // char *
*c == c[0] == 'A' == 65 (ASCII) // char
Taking all that together, that means
*p = (int) *c;
is another way of writing
*p = (int) c[0];
which is another way of writing
array[3] = (int) c[0];
which is another way of writing
array[3] = (int) 'A';
which is another way of writing
array[3] = 65;
(int) is a cast expression; it means that the value following it should be treated as type int.
*p = (int) *c;
*c means that you take the value at the address of c
(int) casts it to an int
*p= writes to the address p points to
So if you fix what droppy said, there will be the numerical value of c[0] in the 3rd part of array
so it would be 1,2,65,4,5
I try use a pointer to a constant integer number in C:
void *p = NULL;
p = (int *) 1;
printf("p=%d\n", *(int *)p);
but I got a segment fault.....
I cannot figure out how a pointer to a constant number in C w/o declaring a variable.
You are not taking the pointer to a constant but you are converting the constant to a pointer. You should do something like:
const int one = 1;
const int *p;
p = &one;
You cannot however do something like:
p = &1;
since literal constants haven't a memory location.
*(int *)p
You are derefrencing p, which is a pointer that has a value of 1. It's unlikely to be a valid address, segmentation fault is not a surprise.
P.S: p is not a pointer to const integer, it has a value of a constant integer.
p = (int *) 1; does not set the pointer p to point to a memory location with value 1. This sets the value of the pointer to 1, i.e, sets the pointer to point to the memory location with address 1.
try this:
void *p = NULL;
const int num = 1;
p = (int*)(&num);
printf("p=%d\n", *((int *)p));
int a=4;
int *p=&a;
This syntax is right but when we write like this
int a;
int *p;
*p=&a;
The third line is an error and i know that but, why is it possible to do so in first code
int *p=&a;
We even do this when we pass the value by reference to functions ...
Thanks for the reply
with int *p=&a;, you are
declaring a variable (p) which is a pointer to an int
assigning the address of a to p
An equivalent code would be
int *p; // declare a pointer variable 'p'
p = &a; // assign the address of a to 'p'
The third line *p=&a; is an error because *p denotes the (integer) value of the pointer whose address is p, the value is an int and not a address of an int (i.e., not a pointer to an int)
The type is int *. So if the general pattern is:
T a;
T b;
a = b;
then with T = int *, the pattern is:
int * p;
p = &n; // n is an int
The "*" in the type specifier int * should not be confused with the almost entirely unrelated unary operator that is also called "*".
when you type
int *p;
you are declaring the pointer p.
using the * again after it has been declared would de-reference the pointer.
so
*p = &a;
would be saying "The value within pointer p = the reference to the value a"
the correct solution is
int *p;
p = &a