Confusion about how pointers are declared in C - c

The syntax commonly used in C to initialize pointers is
int *p = &x;
where p is our pointer and x is a previously declared variable. I unfortunately don't understand this syntax: *p is not equal to &x, but is instead equal to x. So why isn't the correct syntax
int *p = x;?
Does the compiler simply make an exception to the normal rules of variable assignment when dealing with pointers?

read it this way
int* p = &x;
ie int* is a type - a pointer to an int;

C declaration syntax is admittedly confusing. It generally follows the rule that "declaration follows use", but that's not a hard and fast rule.
The type name int* means "pointer to int", but to define an object p of type "pointer to int", we don't simply write that type name followed by the name of the object:
int* p;
Instead, we write:
int *p;
which means that *p is of type int; it follows from that that p must be of type int*.
You've probably noticed that both declarations are the same except for the spacing -- and the compiler doesn't care about spacing. In fact, some programmers prefer to write int* p;, even though it doesn't strictly follow the grammar, because it's clearer in this case.
The distinction becomes important if you want to define multiple objects in a single declaration:
int *p, *q;
means that *p and *q are both of type int. And
int *x, y;
means that *x and y are of type int -- which means that x is an int* and y is an int. Programmers who prefer to place the * next to the int need to split this up into two lines (which is a good idea anyway).
So for an object declaration, the extra specifiers are associated with the name being defined, not with the type. But an initializer applies to the newly created object. So this:
int *p;
means that *p is of type int, but this:
int *p = &x;
means that p itself is initialized with the value &x.
I won't try to argue that this is how C's declaration syntax should have been defined. It has its own consistent logic to it, but it's caused a lot of confusion. But it is the way it is.

The * character has a different meaning depending on where you find it. I can think of three meaning off the top of my head:
1. In a declaration
int *x;
Here, we are writing a variable declaration. We are creating a variable named x with type int *.
2. As a dereference in an expression
int *x = malloc(sizeof(int));
int y = *x;
Here we are using the same token but note that it is now inside an expression! (The right hand side of the equal sign is an expression). Here it means dereference.
3. As multiplication
int *x = malloc(sizeof(int));
int y = *x * *x;
Here we are using the same character for multiplication!
So what gives?
The compiler is able to use the context around the * character to determine which of these three cases we are in. It's certainly arguable that we should have different characters to represent these three things, but that's not the language that we have.

Going back to your declaration.
int *p = &x;
Let's take the first half. The "int *p" tells the compiler that the variable 'p' has a location in memory as a value and it should be interpreted as an 'int'. The second half, '&x', means to get me the location in memory of the variable x. So you can save 'location in memory of variable x' into a variable that represents 'location in memory.'
A real world analogy would be if you have houses on a street, each with an address (one of the houses would be 'x' in your example), and you also have a postcard, 'p,' on which you can write the address of a house. You can't put the house, x, on the postcard. You can only put the address of the house, &x, on the postcard.

int *p = &x;
When prefixed with a * in a declaration, an identifier is defined to be a pointer to the given type. For example, p is a pointer to x; Read it like this:
declare a pointer to an int called p
to the pointer p, assign the following value: the address of x
If we want to use p to get the value of x, we do what is called dereferencing: *p
For example:
int x = 35;
int *p = &x;
printf("x = %d\n", *p); // Prints x = 35
printf("%p\n", p); // Prints the address of x (which is the same as the value of p)
printf("%p\n", &p); // Prints the address of the variable p

int x = 5; // Declaring an integer 'x' and initializing it with the value 5.
int *p1 = &x; // Declaring Pointer 'p1' & Initializing it with address of 'x'.
printf("x = %d\n", *p1); // De-referencing Pointer 'p1' to get value of 'x'.
int *p2 = NULL; // Declaraing a Pointer to an int. Initialize it to NULL.
p2 = &x; // Assigning address of 'x' to pointer 'p2'.
printf("x = %d\n", *p2); // De-referencing Pointer 'p2' to get value of 'x'.

Related

Is "int *x" a pointer to the type int or is it a pointer to an integer value?

In int *x x is a pointer to integer.
If we initialize with a statement something like this: int *x = &p now x is pointing to the address of "p".
The value that it produces is: 6422036
Does that mean in int *x x is a pointer to the type int or it's a pointer to an integer value?
Is it conceptually something like int *x = &int as default?
When I compile this:
#include <stdio.h>
main ()
{
int *x;
printf("%d", x);
return 0;
}
It gives the value 16.
What does it mean?
I think your question is based on a misunderstanding, so I am going to do some bean-counting on your phrasings. (Not contradicting ikegami by the way, just trying to provide a different approach or viewpoint.)
In int *x x is a pointer to integer.
Yes.
if we initialize the statement with something like this: int *x = &p now x is pointing to the address of p.
Not exactly, now x contains the address of p (which hopefully is an int). It is considered to point to p.
The value that it produces is: 6422036
If you say so, but that is not reproducable and you should probably never think or know about that value. Any other value at this point would means the same - or nothing.
Does that mean in int *x x is a pointer to the type int or it's a pointer to an integer value?
Yes.
To be precise, for a C programmer those are one and the same thing.
Whatever it is pointing to is an integer value, i.e. it is of int type. (Skipping the differences of unsigned int, long int, short etc., I am convinced you are not asking about that.)
If you see a difference between those two, then your understanding is not C (I suspect it comes from a different language, see introspection as discussed by ikegami.)
is it conceptually something like int *x = &int as default?
No. There is no such thing as &int in C. It is more like
int *x; /* Don't you dare dereference this before you assigned a decent address.
and be sure to assign an address of something you are actually allowed
to at least read - or expect little demons flying out of your nose. */
Note that "demons flying out of your nose" is practically a technical term used among programmers to describe that absolutely anything can happen, usually undesired things. Most undesired possible result is that it passes all tests and then fails catastrophically in the most inconvenient situation.
Actually it is called undefined behaviour.
C doesn't have reflection. There's no int type in memory, just values of that type. As such, x isn't a pointer to the type int. It is indeed a pointer to an integer value.
Given int *x, we can say:
*x is an int
x is an int*, which is to a pointer to an int.
That assumes x has been properly initialized and isn't NULL. This isn't the case in your program. Reading x before giving it a value is a bug.
Also, providing a pointer to %d is a bug. To display a pointer, you need
printf("%p\n", (void*)x); // One of the weird times when a `void*` cast is needed.
Again, this is only legit after you initialize x.
A valid program:
#include <stdio.h>
int main(void)
{
int i = 123;
int *p = &i;
printf("%p\n", (void*)p);
printf("%p\n", (void*)&i);
printf("%p\n", (void*)&p);
printf("%d\n", i);
printf("%d\n", *p);
return 0;
}
Does that mean in int *x x is a pointer to the type int or it's a pointer to an integer value?
x is an object stores values of type int *; that is, it stores the address of an int object.
It gives the value 16.
What does it mean?
It means you've invoked undefined behavior - you're using the wrong format specifier for the type.
The proper way to print a pointer value is
printf( "%p\n", (void *) x );
In the declaration
int *x;
the initial value of x is indeterminate - it could be anything, from 0x00000000 to 0x00000010 (16) to 0xDEADBEEF to anything else.
There's nothing magic about pointer variables - they store values of a specific type, like an int variable stores integer values and double variable stores floating-point values.
Pointer declaration syntax and operations on pointers are a little non-intuitive and hard to grasp at first, but pointer values themselves are relatively simple things to understand; they're just addresses1 of objects (or functions) in memory.
There's no single pointer type - an int * is a distinct type from a double *, which is a distinct type from a char *, etc. Different pointer types may have different sizes or representations, but on platforms like x86 they all have the same representation.
In a declaration, the presence of a unary * in the declarator means the variable has pointer type:
T *p; // p is a pointer to T
T *ap[N]; // ap is an array of pointers to T
T (*pa)[N]; // pa is a pointer to an array of T
T *fp(); // fp is a function returning a value of type pointer to T
T (*pf)(); // pf is a pointer to a function returning a value of type T
T **pp; // pp is a pointer to pointer to T - it stores the address of
// an object of type T *
In an expression, the presence of the unary * operator means we want to dereference the pointer and obtain the value of the thing it points to:
int x = 10;
int *p = &x; // save the address of x in p
printf( "%d\n", *p ); // print the value stored in x by dereferencing p
More properly, they're abstractions of addresses. Whether those addresses are physical or virtual depends on the environment you're operating in.

How to evaluate double pointers in c?

I am learning c, and I am quite confused about this double pointer question.
int x = 44;
int *p = &x;
int **t = &p;
bool a = (*t = &x);
I need to tell whether a will be true or false, and the correct answer is true. My thoughts were that t points to the address of p, and p points to the address of x. I know if you put **t, it should point to the address of x, but I thought if you just put *t it should point to the address of p. Can anyone explain?
int x = 44;
Declares integer variable x, which stores value of 44.
int *p = &x;
Declares integer pointer variable called p, p now stores the address of x.
int **t = &p;
Declares pointer to pointer of type int called t, t stores the address of p. (Pointers have addresses too)
bool a = (*t = &x);
In C;
'*' = Extracts the value from an address (Dereference)
'&' = Gives address of variable (Reference)
Since t is a pointer to the value stored in p. *t will be the value stored in p, which is the address of x. (We figured this out in the second line)
On the other hand since the & is used on variable x. This will extract the address of x.
Therefore *t == &x, which sets the boolean value a to true.
I know if you put **t, it should point to the address of x, but I thought if you just put *t it should point to the address of p.
Well, that is both right and wrong. The "point to the address of" should read "designate" and it is right.
First of all, you declared 3 variables
int x = 42;
int *p = &x;
int **t = &p;
Now this could be read as x is an int, *p is an int and **t is an int. Then we initialize x to value 42, then p to address of x, and t to address of p.
Given
int *p = &x;
the two L-value expressions x and *p not only are both of type int, and have the same value; they designate the same object. Just like 10565305 and Amy Finck designate the same user. This is also called aliasing - *p aliases x, just like Amy Fink and User 10565305 are your aliases on Stack Overflow (and the name x is not the object itself, just like you're a person, not a name).
Likewise with int **t = &p, we now notice that just like above, *t and p designate the same object, p. And ps current value is that of expression &x. Hence *t == &x must be true.
As for *ts type, if **t is an int, then *t must be int * (the law of conservation of stars in pointers ;) which of course matches the type of p, and type of &x.
It will be true. Here is the explanation:
In bool a = (*t = &x); the variable t holds address of p. You are de-referencing t i.e *t will point to the content stored in location of p.
The content stored in address of p is address of x. Remember *p = &x. Comparing *t == &x will then be true.
In the question you have mentioned *t = &x, if that is the original code it is still true, as assignment in (*t = &x); returns a non-null pointer. When that non-null pointer is converted to a boolean, it becomes true.
The first line declares a variable 'x' of type 'int', and assigns the numeric literal value 44 to that variable.
int x = 44;
The next line (2) declares a variable 'p' of type 'pointer to int', and assigns the value of the expression '&x' (which is the address of x, a pointer to int),
int *p = &x;
The next line (3) declares a variable 't' of type 'pointer to, pointer to int' (a pointer that contains a pointer to an int type), and assigns the expression '&p' (which is the address of p, a pointer to int,
int **t = &p;
The variable t is a 'doubly-indirected pointer'.
Now comes the 'tricky part'.
The next line (4) declares a variable 'a' which is a bool(ean) variable (true/false), and assigns the value of the expression on the rhs (right hand side, '(*t = &x)'. The parenthesis are there to ensure the intended order of precedence is observed. So we evaluate the expression '*t = &x'.
bool a = (*t = &x);
Here is the 'tricky' part, the code provided has an assignment '=' operator! If this were comparison, then the '==' operator would appear. So this statement takes the address of x (pointer to int), and stores it into *t (the location pointed at by t, and that location is a pointer to int).
Were this comparison, the expression would compare the same values, and would be true. But this is assignment. And an assignment expression returns the value assigned, which is the address of x (pointer to x). On most systems, that pointer is a location in memory (and could only be zero(NULL) if the variable were stored at the zero address).
The expression is of type 'pointer to int', but is converted (cast) to type bool. Since C considers false=0 and true anything not equal to 0, the value is converted from (likely not NULL) pointer to int to bool (true).
Had the parenthesis been omitted, then the assignment would still occur (right to left order of evaluation for assignment operator), but then the cast would occur. But remove the parenthesis, compile it and see what your compiler says.
You said:
I need to tell whether a will be true or false, and the correct answer is true. My thoughts were that t points to the address of p, and p points to the address of x. I know if you put **t, it should point to the address of x, but I thought if you just put *t it should point to the address of p. Can anyone explain?
Here is my attempt an an explanation:
The bold part is where you are confused. **t == x == *p, and *t == &x == p.
**t references the value stored in at x's address, not the address itself.
*t =p references the address of x, and dereferencing either of them give you the value of x.
Does this explanation clear things up? I can expand or make a sample program if it helps.
sample scratch code would be to printf these values to gain clarity:
int x = 42; //&x = 0x1234DEAD (or some other address, just picked one for an example)
int * p = &x; // p = 0x1234DEAD and &p = 0x5678BEEF (agian an example address)
int **t = &p; // t = 0x5678BEEF
printf("%d and %d and %d\n",**t, *p, x); //should be 42;
printf("%p and %p\n",*t, p); //should be 0x1234DEAD;
printf("%p\n",t); //should be 0x5678BEEF;
My thoughts were that t points to the address of p
Yes.
and p points to the address of x
Yes.
I know if you put **t, it should point to the address of x
No, **t is x.
but I thought if you just put *t it should point to the address of p.
No, *t is p.
The dereference operator "gives you" the pointed-to thing. Hence, since, p is also &x (because that's what you set it to), *t == &x.
It's moot though because you didn't actually compare with ==, you assigned with =, so your expression evaluates to the result of that assignment, which is &x, which is a non-NULL pointer, so the whole thing is "true-like". (Only a null pointer converts to false).

When to use * in pointer assignment? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
As I'm learning C I often see pointers.
I get that a pointer is holding the hexadecimal value of a distinct location in memory. So a pointer is nothing other than e.g.:0x7fff5fbff85c
Every pointer is also of a distinct type.
int var = 10;
int *ptr = &var;
Ptr here points to the location of var. To get the value of var I have to dereference the pointer with *ptr.
Like
printf("Var = %d", *ptr);
would print `Var = 10;
However If I do a non inline declaration of a pointer like:
int var = 10;
int *ptr;
ptr = &var;
I don't have to use the * in the third line when I'm actually assigning the memory adress to the pointer.
But when I got a function that takes a pointer:
int var = 10;
void assignPointer(int *ptr) {
*ptr = 10;
}
Oh, wait! As I'm writing this I recognized that there are two different assignments for pointers:
*ptr = 10;
and
ptr = &var;
What is the difference? Am I in the first case first dereferencing the pointer, assigning 10 to the location that its holding?
And in the second case I'am assigning the actual location to the pointer.
I'm a little bit confused when to use the * and when not to in terms of assignment.
And if I'm working with arrays, why do I need pointers at all?
int array[];
"array" here is already holding the hexadecimal memory location. Doesn't that make it a pointer? So If I wanted to assign something to array wouldn't I write:
*array = [10, 2];
First I'm dereferencing, then I'm assigning.
I'm lost :(
EDIT: Maybe it's a bit unclear.
I don't know when you have to use a * when you are working with pointers an when not.
Everything that is carrying a hexadecimal is a pointer right?
The variable name of an array is carrying it's hexadecimal memory location. So why isn't it a pointer?
EDIT2: Thank you people you helped me a lot!
I don't know when you have to use a * when you are working with pointers an when not. Everything that is carrying a hexadecimal is a pointer right? The variable name of an array is carrying it's hexadecimal memory location. So why isn't it a pointer?
Last thing first - the name of an array is not a pointer; it does not store an address anywhere. When you define an array, it will be laid out more or less like the following:
+---+
arr: | | arr[0] Increasing address
+---+ |
| | arr[1] |
+---+ |
... |
+---+ |
| | arr[n-1] V
+---+
There is no storage set aside for an object arr separate from the array elements arr[0] through arr[n-1]. C does not store any metadata such as length or starting address as part of the array object.
Instead, there is a rule that says if an array expression appears in your code and that expression is not the operand of the sizeof or unary & operators, it will be converted ("decay") to a pointer expression, and the value of the pointer expression will be the address of the first element of the array.
So given the declaration
T arr[N]; // for any type T
then the following are true:
Expression Type Decays to Value
---------- ---- --------- -----
arr T [N] T * Address of first element
&arr T (*)[N] n/a Address of array (same value
as above
*arr T n/a Value of arr[0]
arr[i] T n/a Value of i'th element
&arr[i] T * n/a Address of i'th element
sizeof arr size_t Number of storage units (bytes)
taken up by arr
The expressions arr, &arr, and &arr[0] all yield the same value (the address of the first element of the array is the same as the address of the array), but their types aren't all the same; arr and &arr[0] have type T *, while &arr has type T (*)[N] (pointer to N-element array of T).
Everything that is carrying a hexadecimal is a pointer right?
Hexadecimal is just a particular representation of binary data; it's not a type in and of itself. And not everything that can be written or displayed in hex is a pointer. I can assign the value 0xDEADBEEF to any 32-bit integer type; that doesn't make it a pointer.
The exact representation of a pointer can vary between architectures; it can even vary between different pointer types on the same architecture. For a flat memory model (like any modern desktop architecture) it will be a simple integral value. For a segmented architecture (like the old 8086/DOS days) it could be a pair of values for page # and offset.
A pointer value may not be as wide as the type used to store it. For example, the old Motorola 68000 only had 24 address lines, so any pointer value would only be 24 bits wide. However, to make life easier, most compilers used 32-bit types to represent pointers, leaving the upper 8 bits unused (powers of 2 are convenient).
I don't know when you have to use a * when you are working with pointers an when not.
Pretty simple - when you want to refer to the pointed-to entity, use the *; when you want to refer to the pointer itself, leave it off.
Another way to look at it - the expression *ptr is equivalent to the expression var, so any time you want to refer to the contents of var you would use *ptr.
A more concrete example might help. Assume the following:
void bar( T *p )
{
*p = new_value(); // write new value to *p
}
void foo( void )
{
T var;
bar( &var ); // write a new value to var
}
In the example above, the following are true:
p == &var
*p == var
If I write something to *p, I'm actually updating var. If I write something to p, I'm setting it to point to something other than var.
This code above is actually the primary reason why pointers exist in the first place. In C, all function arguments are passed by value; that is, the formal parameter in the function definition is a separate object from the actual parameter in the function call. Any updates to the formal parameter are not reflected in the actual parameter. If we change the code as follows:
void bar( T p )
{
p = new_value(); // write new value to p
}
void foo( void )
{
T var;
bar( var ); // var is not updated
}
The value of p is changed, but since p is a different object in memory from var, the value in var remains unchanged. The only way for a function to update the actual parameter is through a pointer.
So, if you want to update the thing p points to, write to *p. If you want to set p to point to a different object, write to p:
int x = 0, y = 1;
int *p = &x; // p initially points to x
printf( "&x = %p, x = %d, p = %p, *p = %d\n", (void *) &x, x, (void *) p, *p );
*p = 3;
printf( "&x = %p, x = %d, p = %p, *p = %d\n", (void *) &x, x, (void *) p, *p );
p = y; // set p to point to y
printf( "&y = %p, y = %d, p = %p, *p = %d\n", (void *) &y, y, (void *) p, *p );
At this point you're probably asking, "why do I use the asterisk in int *p = &x and not in p = y?" In the first case, we're declaring p as a pointer and initializing it in the same operation, and the * is required by the declaration syntax. In that case, we're writing to p, not *p. It would be equivalent to writing
int *p;
p = &x;
Also note that in a declaration the * is bound to the variable name, not the type specifier; it's parsed as int (*p);.
C declarations are based on the types of expressions, not objects. If p is a pointer to an int, and we want to refer to the pointed-to value, we use the * operator to dereference it, like so:
x = *p;
The type of the expression *p is int, so the declaration is written as
int *p;
C syntax is weird like this. When you declare a variable, the * is only there to indicate the pointer type. It does not actually dereference anything. Thus,
int *foo = &bar;
is as if you wrote
int *foo;
foo = &bar;
Pointers are declared similar to regular variables.The asterisk character precede the name of the pointer during declaration to distinguish it as a pointer.At declaration you are not de-referencing,e.g.:
int a = 0;
int *p = &a // here the pointer of type int is declared and assigned the address of the variable a
After the declaration statement,to assign the pointer an address or value,you use it's name without the asterisk character,e.g:
int a;
int *p;
p = &a;
To assign the target of the pointer a value,you dereference it by preceding the pointer name with *:
int a = 0;
int *p;
p = &a;
*p = 1;
Dereferenced pointer is the memory it points to. Just don't confuse declaring the pointer and using it.
It may be a bit easier to understand if you write * in declaration near the type:
int* p;
In
int some_int = 10;
int* p = &some_int; // the same as int *p; p = &some_int;
*p = 20; // actually does some_int = 20;
You are pretty much correct.
Am I in the first case first dereferencing the pointer, assigning 10 to the location that its holding? And in the second case I'am assigning the actual location to the pointer.
Exactly. These are two logically different actions as you see.
"array" here is already holding the hexadecimal memory location. Doesn't that make it a pointer?
And you got the grasp of it as well here. For the sake of your understanding I would say that arrays are pointers. However in reality it is not that simple -- arrays only decay into pointers in most circumstances. If you are really into that matter, you can find a couple of great posts here.
But, since it is only a pointer, you can't "assign to array". How to handle an array in pointer context is usually explained in a pretty good way in any C book under the "Strings" section.
You are right about the difference between assignment and dereferencing.
What you need to understand is that your array variable is a pointer to the first element of your continuous memory zone
So you can access the first element by dereferencing the pointer :
*array = 10;
You can access the nth element by dereferencing a pointer to the nth element :
*(array + (n * sizeof(my_array_type)) ) = 10;
Where the address is the pointer to the first element plus the offset to the nth element (computed using the size of an element in this array times n).
You can also use the equivalent syntax the access the nth element :
array[n] = 10;
One of your examples isn't valid. *ptr = 10;. The reason is that 10 is a value but there is no memory assigned to it.
You can think of your examples as "assigning something to point at the address" or "the address of something is". So,
int *ptr is a pointer to the address of something. So ptr = &val; means ptr equals the address of val. Then you can say *ptr = 10; or val = 10; cause both *ptr and val are looking at the same memory location and, therefore, the same value. (Note I didn't say "pointing").

Getting value using indirection operator

If value are stored in an address, then what does this declaration do
int a = 10;
It store the value in a or in address of &a. And if it store the value in address of a, then why we can't using indirection to this variable like this:
printf("%d", *a);
If not, then how we can say that the each value has an unique address and we can access them using indirection operator.
Edit: If I think that indirection is used only on pointer, then consider this:
int b[10];
b[0] = 4; // Give it some value
Now we know that b[0] is a scalar quantity and can be used anywhere where scalar value are required. But in this case, we can use indirection to it like this:
printf("%d", *b); // print 4
Isn't interesting to see that we can use pointer on this scalar variable, but cannot use on variable declare without array.
In my opinion, compiler automatically generates an indirection for variable declare like this:
int a = 4;
So, indirection is not possible on this because we are putting another indirection on it which is not legal except in cases when variables are declares like that:
int a = 4;
int *b = &a;
int **c = &b;
Edit 2: You can take scanf("%d", &a) as a proof which says store the value in address of a not in a.
Up to a certain point you are right: a stores an int and lives at the address &a.
But indirection can only be used on pointers. So you could do either of
int a = 10;
int *p = &a;
printf("%d", a);
printf("%d", *(&a));
printf("%d", *p);
When the variable is of type int (rather than int *), the compiler knows that it needs to do the indirection for you, and you shouldn't try to make it do it. That is, when you have int a = 10;, the compiler stores the value at a memory location which is represented by &a (ignoring registers) and it knows that when you write printf("%d\n", a); it is required to fetch the value stored at &a automatically without you having to think about telling it to dereference something.
When the variable is of type int * (e.g. int *p), there are two ways you can read the value:
Fetch the value (an address) that is held in p
Fetch the value held at the address stored in p
These are two different operations, so two notations are needed:
int a = 10;
int *p = &a;
int *q = p;
int r = *p;
Of course, p also has its own address.
It's not really clear what the question is here, so I'll just explain the situation...
Each (global) variable is located somewhere in memory. When it is assigned a value, that value will in memory at the location of the variable.
If you, in C, use the variable, you actually use the value stored at the location of the variable.
One way to see this is that if & takes the address of an object, and * dereferences (follows) a pointer, then * &a is the same as simply a.
When you do
int a = 10;
The compiler allocates memory of enough size to accomodate an int. This location has to be identified(this is at this particular place i.e. the address) and labelled(this location is called a).It then stores the data at that point. The label allows you easier access. If the language was designed in a way that you would only have access to locations via pointers (i.e dereferencing them to get values) it will be difficult.
You can say its like, You live on some piece of land which can be pinpointed by an exact latitude and longitude. But its better to keep a name for that location, MyHouse etc. rather than referring to the latitude/longitude everytime. Both name and longi/lati refer to the same thing.
a is the label. &a is more like longi/lati
Edit: Regarding int b[10]. array names are not plain labels. They also act as pointers and hence you can use * to dereference them
First of all, you cannot use the indirection operator on anything that does not have a pointer type.
Remember that declarations in C are based on the types of expressions, not objects; the declaration
int a = 10;
says that the expression a has type int, and will evaluate to the value of 10 (at least until someone assigns a different value to it). So when you write
printf("%d\n", a);
the compiler knows to retrieve the value stored at the memory location bound to the expression a. Think of this as a direct access.
Now consider the declaration
int *p = &a;
This declaration says that the expression *p has type int, and will evaluate to the value of whatever p is currently pointing to (in this case, *p will evaluate to 10 since p is initialized with the address of a); the indirection operator is part of the declaration (and is bound to the declarator *p, not the type specifier int). The variable p is a pointer to an integer, and it stores the address of another integer variable (in this case, the address of the variable a). Thus, if we want to access the integer value, we must dereference p:
printf("%d\n", *p);
This is an indirect access to the value 10; instead of accessing it through the variable a, we're accessing it through p which points to a.

Is this C code wrong?

I know that pointers contain the addresses of variables, for example:
int c = 5;
int *p;
p = &c;
printf("%d",*p); // Outputs 5.
But what if I want to send an address to a function:
void function (int *p)
{
p++;
}
int c;
function (&c);
When function is called, the value of &c is assigned to int *p. I guess that the exact instruction is: *p = &c;, but I don't understand what this means.
I prefer to write int* p = &c;, that is, a pointer to type int is being assigned the address of c.
Pointer notation can be confusing, as you've noticed, because these two are equivalent:
int *p = &c;
and
int *p;
p = &c;
Hope this helps!
EDIT: The confusion comes because * is used both as the dereference operator, and for declaring a pointer. So when p contains the address of c, *p dereferences the pointer and returns the value of c. But when you say int *p = &c;, the * is saying "p is a pointer to an int", but is not doing any dereferencing.
*p = &c; means:
Get the address of c in memory which is determined at compile-time link-time (Thanks Mikeage) e.g, 0x1234 as an example. The pointer to type int, i.e. *p is assigned to 0x1234, which does not sound right to me, I think you should be doing it this way, p = &c then *p would have the value pointed to by the address of c. And therefore *p would have the value of what c was assigned to (that is called dereferencing - by putting a * before the pointer variable then you can obtain the value).
In your function you are trying to increment the value pointed to by p.
void function (int *p)
{
*p++;
}
// It would be called like this
int c = 5;
function(&c); // Now c would have 6!
The key point is you want to pass by reference which is what the parameter &c does.
If you omit the passing by reference like this:
void function (int p)
{
p++;
}
// And call it like this
int c = 5;
function(c); // c is still 5
Now c would still be 5, but within the function itself c is 6, but no copy is passed back out as it is incremented within the local stack for the function itself.
I can't really make out your question, but the function looks like bug to me and what you meant is, perhaps,
++(*p)
Otherwise it's a no-op.
If you want the function to increment c when called with &c, then write this:
void function(int *p) { ++(*p); }
function(int *p) means that p is the function parameter. So whatever value the caller gives, that will be assigned to p (not to *p).
The type of p is int *. That is, p is a pointer-to-int.
If p is a pointer-to-int, then *p is the int it points to.
c is an int. Therefore &c is a pointer-to-int, and the int it points to is c. Therefore, if p is &c, then *p is c.
With my version of the function, this code:
int c = 5;
function(&c);
Does the same as this code:
int c = 5; // same as before
int *p; // parameter of the function
p = &c; // assign the caller's value to the parameter
++(*p); // body of the function, increments *p, which is the same as c.
Which does the same as this code:
int c = 5;
++c;
Are you sure p++; is what you mean to do in your function? That's incrementing the location pointed to by p, it's not incrementing the value at the current location. If you're wanting to increment the value (i.e. make c become 6), then what you want is (*p)++;.
Others have answered your question. I will just add that a helpful way of reading pointer declarations is this. Let's say I have the following declaration:
int i;
This is really easy. Here, i is an int. Now, let's say I have this:
int *pi;
Here, you can either say that pi is a pointer to an int (which is correct). Another way to look at it would be that *pi is an int, i.e., when you have *pi in your code, that *pi will be of type int. Having understood that, I think it's easy to see that ++pi or pi++ doesn't increment the int, because pi is the wrong type. You want (*pi)++. The parentheses are needed because in C, the operator ++ has higher precedence than the unary operator *. Since you don't use any of the side effects of the increment, you can as well do: ++*p.
Of course, as with all the pointers, pi has to point to something useful for the above to make sense.

Resources