What exactly is a variable name in C? - c

The value of an array name is the address of the start of (zeroth element) the array; therefore, the & is not necessary.
Ex:
scanf("%s", string1);
Then what is the value of the integer or character variable names which we have to use & operator? Not addresses like array names I hope. What are they? This is confusing.
Ex:
scanf("%d", &number1);
What is number1 exactly? Is it an address too?

The value of an array name is the address of the start of(zeroth element) the array
No, it isn't. It's just that arrays can decay into a pointer to their first element in certain conditions (when passed to a function or assigned to a pointer, for example).
therefore, the & is not necessary. !!!!!!!
Writing 7 exclamation marks is not necessary either. Note that if arr is an array, then arr and &arr are not the same at all (as you migh assume). arr is of type T [N] where T is the type of an element in the array, and N is the number of elements. The type of &arr, however, is a "pointer-to-array-of N items of type T" (T (*)[N]). This difference is important (not only) because pointer arithmetic will yield in different results on a pointer-to-T and on a pointer-to-array-of-T.
Then what is the value of the integer or character variable names which we have to use & operator? Not addresses like array names I hope.
No, not like arrays (because they are not arrays), but & still is the addressof operator. &variable gives a pointer to the variable, of which the type is T *, if the type of variable was T.
In this specific case, you claimed that number1 was an int, so &number1 is an expression of type int *.

What is number1 exactly? Is it an address too?
Based on your type modifier, number1 is presumably an int, but of course we don't know that for sure because you're not telling us. If I understand correctly what you're asking, number1 is an integer and &number1 is a pointer to that integer.
Then what is the value of the integer or character variable names?
The value of an unmodified variable name is the value of that variable. Arrays are a special case, as you noted. Array names are not actually variables. Given:
int a[10];
int *pa;
you can legally do this:
pa = a;
but not this:
a = pa;
a is the name of an array, not a variable.
Update: For those who think it's weird to say that an array name is not a variable, I was practically quoting the second edition of The C Programming Language by Kernighan and Ritchie. (Ritchie was the creator of C.) Now I'll quote them directly, from page 99 of the second edition:
A pointer is a variable, so pa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa and a++ are illegal.

Oh my, you do indeed have a lot to learn about C. But perhaps the confusion is mostly about arrays & pointers. For practical purposes, an array variable is just a pointer. Realistically, it's not -- its type is indeed an array, but it is implicitly converted to a pointer of the type it is an array of. I hope that helps.

If you declare number1 and give it some value:
int number1;
number1 = 1234;
then &number1 is the address of the memory location where the variable is stored. If you peek into that memory location, you will find it holds 1234, the value of the variable.
If array_of_numbers is declared as:
int array_of_numbers[100];
then the first number in the array is array_of_numbers[0], the address of the first element in the array is &array_of_numbers[0].
array_of_numbers is exactly the same thing as &array_of_numbers[0].
the scanf("%d", &number1); expects address(es) where to put the variable(s), if you did
number1=1234;
scanf("%d", number1);
the scanf function will get whatever number it parses for %d, and try to stuff it into memory location 1234, which is not what you normally want.

See , If you declared it like:
int number1;
Then &number1 is basically the location which will store the contents of number1.
so, when you write :
scanf("%d"&number1);
The compiler stores whatever number you input into the location specified by &number1.So,'&number1'
is somewhat the address where the contents of number1 will stored.
Next time you want to use the contents of number1,they will be picked up from the memory location specified by &number.
I'd like to mention this example:
int a,b,c;
scanf("%d %d ",&a,&b);/*&a and &b are just locations assigned to a and b, in which we store integers*/
c=a+b;
At,c=a+b,here a and b will represent the integers you stored in the memory locations assigned to them ,but c will represent the memory location assigned to c,NOTICE:that there is no &operator infront of c,we just use & operator in function like scanf which are input/output functions defined in stdio.h .
When you declare int number1;
number1 can represent an address too,for eg:
when you write number1=4; here number1 represent the memory location . because you are storing 4 into it.

Related

Pointers, addresses and arrays in C

So I know that pointers are variables that store the address(s) of some other variables. But the thing that I am confused with is this:
I know that using the name of the array in most of the contexts would decay it to the base address of the element. But I get confused here:
When we declare an array say int arr[5], and then say scanf("%d",arr+1), here arr is an address right? We did not explicitly store it in any variable i.e, a pointer. So how does arr+1 arithmetic work similar to pointer arithmetic? Also this: *(arr+1) would give us the value in the address arr+1. I do realize that we can dereference an address, but here I kind of find it difficult to work with it because I kind of lose the "hey this pointer points to this address.." here. And my final question would be, is this the exact way that we can differentiate an address from a random value in a computer? Like arr+1 leads to the address of the next integer in this case, and not normal +1 (pointer arithmetic basically).
I hope that my question does not have any ambiguity.
Your problem starts with this misunderstanding:
So I know that pointers are variables that store the address(s) of some other variables.
"Pointer" is a type category. There are values of pointer types, which are also referred to as "addresses", and there also variables declared to hold such values. This is entirely analogous to there being values of type int and variables declared to hold int values. Also, just as we might refer to either an int value or an int variable as "an int", people can and do refer to both pointer values and pointer variables as "pointers".
Additionally, it is a bit imprecise and a bit misleading to say that pointer values are the addresses of variables. They are the addresses of objects, and although in-scope variables do represent objects, not all objects correspond to variables.
When we declare an array say int arr[5], and then say scanf("%d",arr+1), here arr is an address right?
When the scanf call is evaluated, the array value of arr is automatically converted to a pointer value, the address of the first array element.
We did not explicitly store it in any variable i.e, a pointer.
You do not need to store a pointer value in a variable in order to use it in an expression. In fact, just the opposite: if you want to use the value of a pointer variable in an arithmetic expression, you must first read the value from it -- a process called "lvalue conversion". The same applies to variables of all types and expressions involving most operators. Most operations are defined in terms of values, and variables are just one way to convey those.
So how does arr+1 arithmetic work similar to pointer arithmetic?
There is no "similar to" here. It is pointer arithmetic. arr is automatically converted to a pointer value. That value is a suitable operand for the addition operator, provided that the other operand is of integer type. This is a pointer arithmetic expression.
Also this: *(arr+1) would give us the value in the address arr+1.
Yes, though it would be more idiomatic to say the value at address arr+1.
I do realize that we can dereference an address, but here I kind of find it difficult to work with it because I kind of lose the "hey this pointer points to this address.."
Well, most people would write *(arr+1) as arr[1], which is 100% equivalent, but easier to read and usually clearer. Other than that, I'm not sure what you're asking, if anything.
is this the exact way that we can differentiate an address from a random value in a computer? Like arr+1 leads to the address of the next integer in this case, and not normal +1 (pointer arithmetic basically).
How a C program interprets a given sequence of bytes is determined by the data type it attributes to the sequence. That is exactly the function of data typing. There is no difference discernable in the underlying physical memory, it is all a manner of the program's interpretation. x+1 is pointer arithmetic if x has pointer type, including as the result of automatic conversion from an array. It is integer addition if x has type int, long, etc.. It is floating-point addition if x has type double, float, or long double.
Let's suppose we have:
int n = 1;
int arr[100];
arr + n: yes this is an address.
arr + n: yes, we do doing pointer arithmetic here.
arr + n is the same thing as &arr[n].
*(arr + n) is the same thing as arr[n].
Example of pointer arithmetic:
Let's suppose the size of an int is 4 bytes and arr is the address 0x10000:
arr + n is 0x10000 + n * 4
sor for example arr+2 is the address 0x10008
Your last question is somewhat unclear but if you understood the above it should be clear.

Difference between &ar[0][0] and ar [duplicate]

I am having a tough time understanding the type and use of the name of the array in C. It might seems a long post but please bear with me.
I understand that the following statement declares a to be of type int [] i.e array of integers.
int a[30];
While a also points the first element of array and things like *(a+2) are valid. Thus, making a look like a pointer to an integer. But actually the types int [] and int* are different; while the former is an array type and later is a pointer to an integer.
Also a variable of type int [] gets converted into a variable of type int* when passing it to functions; as in C arrays are passed by reference (with the exception of the sizeof operator).
Here comes the point which makes me dangle. Have a look at the following piece of code:
int main()
{
int (*p)[3];
int a[3] = { 5, 4, 6 };
p = &a;
printf("a:%d\t&a:%d\n",a,&a);
printf("%d",*(*p + 2));
}
OUTPUT:
a:2686720 &a:2686720
6
So, how does the above code work? I have two questions:
a and &a have the same values. Why?
What exactly does int (*p)[3]; do? It declares a pointer to an array, I know this. But how is a pointer to an array different from the pointer to the first element of the array and name of the array?
Can anyone clarify things up? I am having a hell of a lot of confusions.
I know that I should use %p as a placeholder instead of using %d for printing the value of pointer variables. As using the integer placeholder might print truncated addresses. But I just want to keep things simple.
Other answers already explained the issue. I am trying to explain it with some diagram. Hope this will help.
When you declare an array
int a[3] = {5, 4, 6}
the memory arrangement looks like
Now answering your question:
a and &a have the same values.How?
As you already know that a is of array type and array name a becomes a pointer to first element of array a (after decay),i.e it points to the address 0x100. Note that 0x100 also is the starting address of the memory block (array a). And you should know that, in general, the address of the first byte is said to be the address of the variable. That is, if a variable is of 100 bytes, then its address is equal to the address of its first byte.
&a is address of the entire memory block, i.e it is an address of array a. See the diagram:
Now you can understand why a and &a both have same address value although both are of different type.
What exactly it does int (*p)[3]; Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?
See the above figure, it is explained clearly how pointer to an array is different from the pointer to an array element.
When you assign &a to p, then p points to the entire array having starting address 0x100.
NOTE: Regarding to the line
... as in C arrays are passed by references (with exception of sizeof function).
In C, arguments are passed by value. No pass by reference in C. When an ordinary variable is passed to a function, its value is copied; any changes to corresponding parameter do not affect the variable.
Arrays are also passed by value, but difference is that the array name decays to pointer to first element and this pointer assigned to the parameter (here, pointer value is copied) of the function; the array itself isn't copied.
In contrast to ordinary variable, an array used as an argument is not protected against any change, since no copy is made of the array itself, instead copy of pointer to first element is made.
You should also note that sizeof is not a function and array name does not act as an argument in this case. sizeof is an operator and array name serves as an operand. Same holds true when array name is an operand of the unary & operator.
a and &a have the same values.How?
They have the same value but different types. Array objects have no padding between elements (before or after) so the address of the array and the address of the first element of the array are the same.
That is:
(void *) a == (void *) &a
What exactly it does int (*p)[3]; Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?
These are two different pointer types. Take for example, pointer arithmetic:
a + 1 /* address of the second element of the array */
&a + 1 /* address one past the last element of the array */
EDIT: due to popular demand I added below some information about conversion of arrays.
With three exceptions, in an expression an object of type array of T is converted to a value of type pointer to T pointing to the first element of the array. The exceptions are if the object is the operand of sizeof or & unary operator or if the object is a string literal initializing an array.
For example this statement:
printf("a:%d\t&a:%d\n", a, &a);
is actually equivalent to:
printf("a:%d\t&a:%d\n", &a[0], &a);
Also please note that d conversion specifier can only be use to print a signed integer; to print a pointer value you have to use p specifier (and the argument must be void *). So to do things correctly use:
printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);
respectively:
printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);
a corresponds to the pointer pointing at 0th element of the array. Whereas,the same is the case with &a.It just gives the starting address of the array.
As,a --> pointer pointing to starting element of array a[],it does not know about other element's location..
&a --->address location for storing array a[] which stores first element location,but knows every element's location.
Similarly,other elements location will be (a+2),(a+4) and so upto the end of the array.
Hence,you got such result.
int (*p)[3] is a pointer to the array. had it been int *p[3],it would been meant entirely different. It'd have meant an array of pointers which would have been totally different from this context.
Pointer to an array will automatically take care of all the other
elements in the array.In this case,your's is (p);
Whereas,the pointer to the first element of the array,i.e., a will
only know about first element of the array.You'll have to manually
give pointer arithmetic directions to access next elements.See,in this
case---we can get second element from a by adding 2 to a,i.e.
a+2,third element by adding 4 to a,i.e., a+4 and so on. // mind the
difference of two as it is an integer array!
In answer to question 1, this is simply an aspect of the C language as designed, unlike most other modern languages C/C++ allows direct manipulation of addresses in memory and has built in facilities to 'understand' that. There are many articles online that explain this better than I could in this small space. Here is one and I am sure there are many others: http://www.cprogramming.com/tutorial/c/lesson8.html
From C99 Standard n1124 6.3.2.1 p3
Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined.
a and &a have the same value because a long time ago you were required to use the address operator & on arrays to get the array's address, but it is no longer necessary. The name of the array (a in this case) these days just represents the memory address of the array itself, which is also what you get from &a. It's a shorthand that the compiler handles for you.

Pointer and array 'a' and '&a' giving same output? [duplicate]

I am having a tough time understanding the type and use of the name of the array in C. It might seems a long post but please bear with me.
I understand that the following statement declares a to be of type int [] i.e array of integers.
int a[30];
While a also points the first element of array and things like *(a+2) are valid. Thus, making a look like a pointer to an integer. But actually the types int [] and int* are different; while the former is an array type and later is a pointer to an integer.
Also a variable of type int [] gets converted into a variable of type int* when passing it to functions; as in C arrays are passed by reference (with the exception of the sizeof operator).
Here comes the point which makes me dangle. Have a look at the following piece of code:
int main()
{
int (*p)[3];
int a[3] = { 5, 4, 6 };
p = &a;
printf("a:%d\t&a:%d\n",a,&a);
printf("%d",*(*p + 2));
}
OUTPUT:
a:2686720 &a:2686720
6
So, how does the above code work? I have two questions:
a and &a have the same values. Why?
What exactly does int (*p)[3]; do? It declares a pointer to an array, I know this. But how is a pointer to an array different from the pointer to the first element of the array and name of the array?
Can anyone clarify things up? I am having a hell of a lot of confusions.
I know that I should use %p as a placeholder instead of using %d for printing the value of pointer variables. As using the integer placeholder might print truncated addresses. But I just want to keep things simple.
Other answers already explained the issue. I am trying to explain it with some diagram. Hope this will help.
When you declare an array
int a[3] = {5, 4, 6}
the memory arrangement looks like
Now answering your question:
a and &a have the same values.How?
As you already know that a is of array type and array name a becomes a pointer to first element of array a (after decay),i.e it points to the address 0x100. Note that 0x100 also is the starting address of the memory block (array a). And you should know that, in general, the address of the first byte is said to be the address of the variable. That is, if a variable is of 100 bytes, then its address is equal to the address of its first byte.
&a is address of the entire memory block, i.e it is an address of array a. See the diagram:
Now you can understand why a and &a both have same address value although both are of different type.
What exactly it does int (*p)[3]; Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?
See the above figure, it is explained clearly how pointer to an array is different from the pointer to an array element.
When you assign &a to p, then p points to the entire array having starting address 0x100.
NOTE: Regarding to the line
... as in C arrays are passed by references (with exception of sizeof function).
In C, arguments are passed by value. No pass by reference in C. When an ordinary variable is passed to a function, its value is copied; any changes to corresponding parameter do not affect the variable.
Arrays are also passed by value, but difference is that the array name decays to pointer to first element and this pointer assigned to the parameter (here, pointer value is copied) of the function; the array itself isn't copied.
In contrast to ordinary variable, an array used as an argument is not protected against any change, since no copy is made of the array itself, instead copy of pointer to first element is made.
You should also note that sizeof is not a function and array name does not act as an argument in this case. sizeof is an operator and array name serves as an operand. Same holds true when array name is an operand of the unary & operator.
a and &a have the same values.How?
They have the same value but different types. Array objects have no padding between elements (before or after) so the address of the array and the address of the first element of the array are the same.
That is:
(void *) a == (void *) &a
What exactly it does int (*p)[3]; Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?
These are two different pointer types. Take for example, pointer arithmetic:
a + 1 /* address of the second element of the array */
&a + 1 /* address one past the last element of the array */
EDIT: due to popular demand I added below some information about conversion of arrays.
With three exceptions, in an expression an object of type array of T is converted to a value of type pointer to T pointing to the first element of the array. The exceptions are if the object is the operand of sizeof or & unary operator or if the object is a string literal initializing an array.
For example this statement:
printf("a:%d\t&a:%d\n", a, &a);
is actually equivalent to:
printf("a:%d\t&a:%d\n", &a[0], &a);
Also please note that d conversion specifier can only be use to print a signed integer; to print a pointer value you have to use p specifier (and the argument must be void *). So to do things correctly use:
printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);
respectively:
printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);
a corresponds to the pointer pointing at 0th element of the array. Whereas,the same is the case with &a.It just gives the starting address of the array.
As,a --> pointer pointing to starting element of array a[],it does not know about other element's location..
&a --->address location for storing array a[] which stores first element location,but knows every element's location.
Similarly,other elements location will be (a+2),(a+4) and so upto the end of the array.
Hence,you got such result.
int (*p)[3] is a pointer to the array. had it been int *p[3],it would been meant entirely different. It'd have meant an array of pointers which would have been totally different from this context.
Pointer to an array will automatically take care of all the other
elements in the array.In this case,your's is (p);
Whereas,the pointer to the first element of the array,i.e., a will
only know about first element of the array.You'll have to manually
give pointer arithmetic directions to access next elements.See,in this
case---we can get second element from a by adding 2 to a,i.e.
a+2,third element by adding 4 to a,i.e., a+4 and so on. // mind the
difference of two as it is an integer array!
In answer to question 1, this is simply an aspect of the C language as designed, unlike most other modern languages C/C++ allows direct manipulation of addresses in memory and has built in facilities to 'understand' that. There are many articles online that explain this better than I could in this small space. Here is one and I am sure there are many others: http://www.cprogramming.com/tutorial/c/lesson8.html
From C99 Standard n1124 6.3.2.1 p3
Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined.
a and &a have the same value because a long time ago you were required to use the address operator & on arrays to get the array's address, but it is no longer necessary. The name of the array (a in this case) these days just represents the memory address of the array itself, which is also what you get from &a. It's a shorthand that the compiler handles for you.

How &a is a pointer to a if it generates the address of a?

I'm new to programming, and at present I am learning about pointers in C.
I know that pointers are the variables which contain or hold address of another variable. Today when I was more learning about it with K&R I got confused in a line which says "&a is a pointer to a" in a given function swap(&a,&b) in Page No. 80. How &a is a pointer? It is not a variable, it is the address of the variable. Am I right?
I know that arguments can be passed to a function in two ways: call by value and call by reference. The caller's value of the argument is not changed in the first one, but it can be changed in the second one.
My question is I had read that if we want to change the value of the variable we have to pass the pointer to it (i.e. the location of the value we want to modify). What is meant by that? I mean, do we have to pass pointers to the function? And what is the meaning of the statement, "we have to pass the pointers to the location we want to modify".
A pointer is not a variable. A pointer is a value.
A variable, in C, designates a storage location, and a value can be stored in that location. Thus, if you have a variable a declared with int a, then a is a variable in which an integer value can be stored. If you have a variable int *x, then x is a variable in which a pointer to an integer value can be stored.
The address of a storage location can be obtained using the & operator. E.g., &a is the address of the storage location designated by a, or the address of a, and can be stored in (among other things) a variable of the corresponding type. Thus you can have:
int a = 42; /* a is a variable of type int, and has value 42 */
int* x = &a; /* x is a variable of type int*, and has value &a */
Although analogies in programming are often dangerous, you might think of things like page numbers in a book. The page number of a page is not the same thing as the page, but page numbers can still be written down on pages. E.g., the table of contents page has lots of page numbers written down on it. Thus:
actual_page p = ...; /* a page structure */
page_number n = &p; /* a page number */
A pointer is an address. A pointer variable is a variable holding an address.
It is perhaps analogous to the difference between a literal integer 1 and an integer variable int a. One might refer to both a and 1 as integers, just as you might refer to &a and int* p as pointers.
Note also that &a is not an lvalue and cannot be assigned - so it is as you say not a variable, but it is a pointer nonetheless, and can itself be assigned to a pointer variable.
If a is a variable of some type T, then &a is an expression which evaluates to the address of that variable, also known as a pointer to that variable—the terms are interchangeable. &a has the type T*, which is pronounced “pointer to T”.
int x = 4; // 4 has type int, so we can assign it to an int variable.
int *p = &x; // &x has type int*, so we can assign it to an int* variable.
The reason that you can modify function arguments passed by pointer is that a pointer introduces a sort of alias for a variable. You can alter it from multiple locations, either directly (via the variable) or indirectly (via the pointer).
// modifying x modifies *p.
++x;
printf("%d %d\n", x, *p);
// modifying *p modifies x.
++*p;
printf("%d %d\n", x, *p);
As others have observed, a pointer is a particular kind of value, not a particular kind of variable.
With regard to calling functions:
You cannot "pass a variable to a function" in C. If you put a variable name in the argument list of a function call then the value stored in that variable is passed, not the variable itself.
Although in a general sense programming languages may provide for passing function arguments either by value or by reference, C provides only pass by value. You can emulate pass by reference in C, however, by passing a pointer (value) to the location where another value is stored. That's what swap(&a, &b) does: you are passing the locations where the values of variables a and b are stored (that is, pointers to those values).
Pointer contains the address - so synonymous.
When you pass by reference, you are passing in the address - to directly modify the value.
A pointer is a type of variable that stores the address to an object.
Basically, the pointer is the address.
Think of it as a piece of paper. When it has a number printed on it, it's an integer (or other numeric type).
A pointer is a piece of paper that says "the data is on the peice of paper in location x", where "location x" is the address of the object.
How &a is a pointer to a if it generates the address of a?
The terms pointer and address in C are synonymous.
When you create a variable:
int a = 0;
It is created in memory at a specific memory location, or address, with sufficient memory to hold 1 int.
&a does not generate the address, it simply provides the address.
The & operator can be used to set the address of a pointer to a specific location, such as this:
int a = 0;//a now exists in memory at a specific location;
int *b = {0}; // b is created in memory as a pointer, and can be assigned a location
b = &a; //b is assigned the location (address) of the variable a
Stated a little differently, in the previous line, & is referred to as the address-of operator, so:
b = &x; Can be Read: Assign to b (a pointer) the address of a.

What exactly is the array name in c?

I am having a tough time understanding the type and use of the name of the array in C. It might seems a long post but please bear with me.
I understand that the following statement declares a to be of type int [] i.e array of integers.
int a[30];
While a also points the first element of array and things like *(a+2) are valid. Thus, making a look like a pointer to an integer. But actually the types int [] and int* are different; while the former is an array type and later is a pointer to an integer.
Also a variable of type int [] gets converted into a variable of type int* when passing it to functions; as in C arrays are passed by reference (with the exception of the sizeof operator).
Here comes the point which makes me dangle. Have a look at the following piece of code:
int main()
{
int (*p)[3];
int a[3] = { 5, 4, 6 };
p = &a;
printf("a:%d\t&a:%d\n",a,&a);
printf("%d",*(*p + 2));
}
OUTPUT:
a:2686720 &a:2686720
6
So, how does the above code work? I have two questions:
a and &a have the same values. Why?
What exactly does int (*p)[3]; do? It declares a pointer to an array, I know this. But how is a pointer to an array different from the pointer to the first element of the array and name of the array?
Can anyone clarify things up? I am having a hell of a lot of confusions.
I know that I should use %p as a placeholder instead of using %d for printing the value of pointer variables. As using the integer placeholder might print truncated addresses. But I just want to keep things simple.
Other answers already explained the issue. I am trying to explain it with some diagram. Hope this will help.
When you declare an array
int a[3] = {5, 4, 6}
the memory arrangement looks like
Now answering your question:
a and &a have the same values.How?
As you already know that a is of array type and array name a becomes a pointer to first element of array a (after decay),i.e it points to the address 0x100. Note that 0x100 also is the starting address of the memory block (array a). And you should know that, in general, the address of the first byte is said to be the address of the variable. That is, if a variable is of 100 bytes, then its address is equal to the address of its first byte.
&a is address of the entire memory block, i.e it is an address of array a. See the diagram:
Now you can understand why a and &a both have same address value although both are of different type.
What exactly it does int (*p)[3]; Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?
See the above figure, it is explained clearly how pointer to an array is different from the pointer to an array element.
When you assign &a to p, then p points to the entire array having starting address 0x100.
NOTE: Regarding to the line
... as in C arrays are passed by references (with exception of sizeof function).
In C, arguments are passed by value. No pass by reference in C. When an ordinary variable is passed to a function, its value is copied; any changes to corresponding parameter do not affect the variable.
Arrays are also passed by value, but difference is that the array name decays to pointer to first element and this pointer assigned to the parameter (here, pointer value is copied) of the function; the array itself isn't copied.
In contrast to ordinary variable, an array used as an argument is not protected against any change, since no copy is made of the array itself, instead copy of pointer to first element is made.
You should also note that sizeof is not a function and array name does not act as an argument in this case. sizeof is an operator and array name serves as an operand. Same holds true when array name is an operand of the unary & operator.
a and &a have the same values.How?
They have the same value but different types. Array objects have no padding between elements (before or after) so the address of the array and the address of the first element of the array are the same.
That is:
(void *) a == (void *) &a
What exactly it does int (*p)[3]; Declares a pointer to an array,i know this.But,how a pointer to an array is different from the pointer to the first element of the array and name of the array?
These are two different pointer types. Take for example, pointer arithmetic:
a + 1 /* address of the second element of the array */
&a + 1 /* address one past the last element of the array */
EDIT: due to popular demand I added below some information about conversion of arrays.
With three exceptions, in an expression an object of type array of T is converted to a value of type pointer to T pointing to the first element of the array. The exceptions are if the object is the operand of sizeof or & unary operator or if the object is a string literal initializing an array.
For example this statement:
printf("a:%d\t&a:%d\n", a, &a);
is actually equivalent to:
printf("a:%d\t&a:%d\n", &a[0], &a);
Also please note that d conversion specifier can only be use to print a signed integer; to print a pointer value you have to use p specifier (and the argument must be void *). So to do things correctly use:
printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);
respectively:
printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);
a corresponds to the pointer pointing at 0th element of the array. Whereas,the same is the case with &a.It just gives the starting address of the array.
As,a --> pointer pointing to starting element of array a[],it does not know about other element's location..
&a --->address location for storing array a[] which stores first element location,but knows every element's location.
Similarly,other elements location will be (a+2),(a+4) and so upto the end of the array.
Hence,you got such result.
int (*p)[3] is a pointer to the array. had it been int *p[3],it would been meant entirely different. It'd have meant an array of pointers which would have been totally different from this context.
Pointer to an array will automatically take care of all the other
elements in the array.In this case,your's is (p);
Whereas,the pointer to the first element of the array,i.e., a will
only know about first element of the array.You'll have to manually
give pointer arithmetic directions to access next elements.See,in this
case---we can get second element from a by adding 2 to a,i.e.
a+2,third element by adding 4 to a,i.e., a+4 and so on. // mind the
difference of two as it is an integer array!
In answer to question 1, this is simply an aspect of the C language as designed, unlike most other modern languages C/C++ allows direct manipulation of addresses in memory and has built in facilities to 'understand' that. There are many articles online that explain this better than I could in this small space. Here is one and I am sure there are many others: http://www.cprogramming.com/tutorial/c/lesson8.html
From C99 Standard n1124 6.3.2.1 p3
Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined.
a and &a have the same value because a long time ago you were required to use the address operator & on arrays to get the array's address, but it is no longer necessary. The name of the array (a in this case) these days just represents the memory address of the array itself, which is also what you get from &a. It's a shorthand that the compiler handles for you.

Resources