+6  A: 

It takes a type.

sizeof(char) is always one. The variable p itself is a pointer, and on your platform that has a size of 4. Then you do &p, or a pointer to a pointer, which also has a size of 4.

On most modern desktop systems, a 32-bit architecture will have 4 byte pointers, while a 64-bit architecture will have 8 byte pointers.

sizeof itself is a keyword, resolved at compile-time, not a function. In C99, arrays can be variable length, and sizeof will wait until run-time to resolve this size.

GMan
Actually, I'm pretty sure the parenthesis are required when its operand is a type name.
bcat
Oops, you're right. I'll fix it.
GMan
You didn't fix it - you should say 'sizeof(char) is always one'. You can also pass variables to sizeof (and then you don't need the parentheses). In most contexts, sizeof() generates a compile-time constant; the exception is a C99 VLA - variable-length array, which means sizeof(arrayname) must be evaluated at runtime.
Jonathan Leffler
Alright, one more attempt :o
GMan
A: 
sizeof (char)   = 1
sizeof (void *) = 4

The first one is 1 because you are passing a char. (p points to a char) 2nd and 3rd calls receive a char* / void* object, so they yield 4.

Tom
+2  A: 

Becuase you are working on 32bit machine.

*p is a character == 1 byte.
p  is a pointer   == 4 bytes.
&p is an address of a pointer == 4 bytes. Same as char**
AraK
A: 

The first answer is saying that a char is 1 byte. (derefing your pointer to a the actual char data)

The second is saying that the pointer value is a 4 byte value, that is the memory location is represented by a 4 byte value.

The third is saying that the address of the pointer is a 4 byte value.

Size of can take all of those arguments, and it is reporting accurate response for all of the values.

Cheers.

another average joe
+8  A: 

sizeof isn't a function, it's a keyword. You could drop the parentheses and it would work just fine. Because it's not a function, it works with any type or object that you give it - it's much more flexible than a function.

Mark Ransom
its good info, but I dont think that´s what he was looking for
Tom
+1 for mentioning that it's (usually) a compile-time operator. In C99, sizeof can be used at runtime to determine the size of a dynamically allocated array. And there is one situation where it'snot allowed: expressions of "function" type (e.g. "sizeof (main)").
Jim Lewis
@Tom: Maybe not, but the question wasn't very clear. I hope they find this helpful nevertheless.
Mark Ransom
You can only drop the parentheses if you are taking the sizeof a value. If you are doing `sizeof(type)`, then you must have the parentheses.
newacct
That's because one of the valid operands for sizeof is a "parenthesized type-id" (the other being an object expression). So technically, you're applying sizeof to `(type)`, not to `type`. Really that's a distinction without a difference, but `sizeof *p` isn't "dropping the parentheses" any more that `1 + 2` is "dropping the parentheses" from `(1) + (2)`. Unlike function calls, operators just don't need parentheses.
Steve Jessop
If you give sizeof(SomeType), you must use the parentheses. Since you can use parentheses with variables, I simply use 'sizeof(whatever)' always using parentheses; this infuriated a colleague who was adamant that it was crucial to distinguish between the variable and type usages - a distinction I still find to be without value.
Jonathan Leffler
+1  A: 

sizeof is not a function; it's an operator. It can be used in two ways: as sizeof(typename) and as sizeof expression. The parentheses are required when used with a type name. Parentheses are not needed when the operand is an expression, though for clarity's sake many programmers will parenthesize the expression regardless. Note that unlike most programming languages operators, sizeof expression does not evaluate its argument under normal circumstances, i.e., when its operand is not a C99 variable-length array.

bcat
Technically, it's used in two ways: `sizeof(typename)` and `sizeof expression`. Of course, any expression can be surrounded with parentheses if you feel like it, and it's often wise to do so since nobody ever remembers the precedence of sizeof. `sizeof (a) ? 1 : 2`, is 1, as is `sizeof a ? 1 : 2`, whereas `sizeof (a ? 1 : 2)` is `sizeof int`.
Steve Jessop
Strictly speaking, in the most recent specification of C language - C99 - 'sizeof's argument can be evaluated. It is evaluated when 'sizeof' is used with variable-length arrays (VLAs).
AndreyT
@AndreyT: you are right that sizeof() may be evaluated at runtime, but the argument is still not evaluated - just the size of the argument. This matters with 'sizeof(1/0.0)'; the expression is a double value - and because it is not evaluated, there is no exception. Fortunately, you can't divide an array, so the VLA part doesn't come into this discussion.
Jonathan Leffler
OK, I've edited my answer to clarify the parentheses issue and address C99 VLAs. Thanks folks!
bcat
Well, it all depends on the specific meaning of the term "evaluated". Note, that C99 itself in 6.5.3.4/2 explicitly states that in case of VLA the argument of 'sizeof' is evaluated:"[...]If the type of the operand is a variable length arraytype, the operand is evaluated; otherwise, the operand is not evaluated[...]"
AndreyT
A: 

In addition to the other replies, beware of the possible terminological mixup.

In C world, 'byte' is the same as 'char'. I.e. each 'char' is 1 'byte' by definition. This meaning of 'byte' is not necessarily connected to the machine 'byte' in the underlying hardware. A C 'byte' (i.e. 'char') can consist of several machine 'bytes'. However, in C program you have no access to machine bytes. Everything is measured in C 'bytes' (i.e. in 'chars') and 'sizeof' gives your the size measured in 'chars'.

For these reasons, 'sizeof(char)' is always 1 regardless of how many machine bytes each 'char' actually consists of.

AndreyT
That said, a C implementation in which char was bigger than the smallest addressable unit of memory on the architecture would be very unsporting, since it would limit your options for low-level programming on that machine.
Steve Jessop
A: 

The operand of the sizeof operator is a type.

If you use sizeof with an object or a value, its type is used instead.

sizeof 65; /* same as `sizeof (int);` */
sizeof 'X'; /* same as `sizeof (int);` */
sizeof 42.0; /* same as `sizeof (double);` */
float f;
sizeof f; /* same as `sizeof (float);` */
/* etc ... */

You can specify a type directly to the sizeof operator (as in the "same as" above). The parenthesis are needed "to cast the operand to the right type" (as in (int)2.5), not as syntax for sizeof itself

#include <math.h>
sizeof (12 * log(100)); /* same as `sizeof (double);` */
                        /* without the parenthesis, this would be */
                        /* (sizeof 12) * log(100); */
pmg
A: 

Also note:

sizeof 'a' == 1   // C++ 

but

sizeof 'a' == 4   /* C */ 

(To be precise, sizeof 'a' == sizeof(int) in C as posted by pmg).

In C, the 'a' gets promoted to an int before it is evaulated. One of the few incompatibilities between the two languages.

Andy Foulks