Reputation: 22064
In the following example code, I use string as array, if the name of str is an pointer to the first element of the str, in this case the first character of string, which is s, the size of str, should be 8, but it gives the 6 instead.
#include <stdio.h>
char str[] = "string";
char *ptr = "string";
int main(void){
int first = sizeof(str);
int second = sizeof(str[0]);
int third = sizeof(ptr);
int size_of_array = sizeof(str)/sizeof(str[0]);
printf("the size is %d, %d, %d, %d", size_of_array, first, second, third);
return 0;
}
it seems like the str is not an pointer, the size of str is not the size of ptr? I'm confused about t
Upvotes: 2
Views: 401
Reputation: 66224
First, the meat of your question: The compiler treats sizeof strictly in terms of declaration size. In the following code, assume a pointer variable holds a 32 bit (4 byte) address:
char str1[] = "abcd";
char *pstr = str1;
// str1 is declared to be a fixed array of 5 chars (4+nul)
size_t str1size = sizeof(str1); // str1size = 5;
// pstr is declared to be a 32 bit pointer to a memory address.
size_t pstrSize = sizeof(pstr) // size of a 32 bit pointer; 4.
To grasp the results you're seeing, review differences of arrays and pointer variables, (of which there are fewer than most think).
The core differences in C between arrays and pointer variables is
The first of these I simply cannot stress enough if you want to really wrap your head around arrays and pointers in C. Other than that, their relationship is incestuous at best. Pointer variables are at addresses like arrays (or any other variable). But unlike arrays, they also hold an address as their value. Arrays are their very address.
The first is best demonstrated with the following:
char str1[] = "abcd";
char *pstr = NULL;
pstr = str1; // ok. pstr holds the address *at* str1.
str1[0] = *pstr; // ok. copies 'a' on to 'a'.
pstr++; // ok. increment the address held in pstr by one item (char) size.
str1[0] = *pstr; // ok. copies 'b' over 'a'.
pstr = str1+1; // ok. pstr holds the address *at* str1 + one item (char) size.
str1 = pstr; // does not compile. str1's address cannot be changed.
Note that the pointer variable itself holds an address, while a fixed array is an address. Thus the last statement reversed is perfectly fine.
pstr = str1; // ok. put the str1 address in pstr, a pointer variable.
Upvotes: 5
Reputation: 222923
Oddly, none of the previous answers directly address the question asked in the title.
No, the name of an array is not a pointer to its first element.
In most expressions, an expression that is an array is converted to a pointer to the first element. Because this happens in most expressions, people tend to think of arrays as pointers. However, there are four exceptions. An array is not converted to a pointer when it is the operand of sizeof
, _Alignof
, or &
or when it is a string literal used to initialize an array. Because one of your examples uses an array as an operand of sizeof
, it uses the array, not a pointer to the first element.
Thus, in sizeof(str[0])
, str[0]
is parsed first. In this subexpression, str
is not the operand of sizeof
, so it is converted to a pointer. Then that pointer is used with the subscript operator, and the result is the first element of the array. Then sizeof
evaluates to the size of that element, which is one.
In sizeof(str)
, str
is the operand of sizeof
. So it is not converted to a pointer; it is the array. Then sizeof
evaluates to the size of that array, which is seven.
Note that this conversion does not just occur for identifiers (names); it occurs for any expression. Thus, if p
is a pointer to array, as declared with float (*p)[4];
, then *p
is an array of four float, so it is converted to a pointer to float (when it is not the operand of sizeof
, _Alignof
, or &
).
Upvotes: 1
Reputation: 63807
Long story short; an array is not a pointer, and pointers are not arrays.
Because of implicit conversions where you seem to be able to use an array in a context which requires a pointer1 lot of novice (and sadly experienced) developers confuses the two.
Your own snippet is a perfect example on the fact that arrays are not pointers, and pointers are not arrays.
1. "Important to note that arrays decay to pointers in many circumstances as that is a constant source of confusion." – Ed S.
Your sizeof
's will operate of the "real" type of your variable, which is why the numbers you are getting doesn't match what you thought under the assumption that array-names are equivalent to pointers.
Just to make myself clear to readers of this question; arrays are not pointers, and pointers are not arrays..
Upvotes: 5
Reputation: 10368
Yes and no, str is an array but when it appears in an expression, it is converted to a pointer to the first member of the array.
The strange thing is that when you do a sizeof(str) actually it should give you a 7 instead of a 6 since it includes the NUL terminator.
s t r i n g \0
If you used strlen() though, it would return 6.
Upvotes: 1