简体   繁体   中英

sizeof() behaviour in C programming

This is my program..

int main(void) {

    printf("%lu\n", sizeof(""));

    // first if else statement
    if(1 > -2) printf("Yes");
    else printf("No");

    printf("\n");

    // second if else statement    
    if( sizeof("") > -2) printf("Yes");
    else printf("No");
}

In first printf() why it's printing 1 as output,though I've passed an empty string? In first if-else statement I got the correct output -> Yes as expected, but in second if-else statement It prints the outout -> No, Can anyone explain me why this is happening?

My output is.. 1 Yes No

Thanks in advance:-)

sizeof("") is one because string literals represent character arrays that contain the given characters followed by '\0' . So "" represents the character array {'\0'} .

sizeof("") > -2 is false because sizeof returns a size_t , which is an unsigned integer type. The comparison causes -2 to be converted to size_t , which causes it to wrap around and become a number much larger than one.

All strings in C end in a \0 null character. This signifies the sting end.

When programming in C its always good to visualize how the data is actually stored in memory, as you can see here, "Hello" is 5 characters long, however 6 characters must be given to the char array to leave space for this null character.

C 中的 Sting 内存表示

Heres what your example looks like as suggested by Bob Jarvis:

在此处输入图像描述

As for the sizeof("") > -2 being false, have a look at sepp2k's answer

Following on from @sepp2k's explanation of why sizeof("") < -2 is true, here's a modified version of your program which shows the results clearly:

#include <stdio.h>

int main(void) {

    printf("%lu\n", sizeof(""));

    // first if else statement
    if(1 > -2) printf("Yes");
    else printf("No");

    printf("\n");

    // second if else statement    
    if( sizeof("") > -2) printf("Yes");
    else printf("No");

    printf("\n");

    // third if else statement    
    if((long int)sizeof("") > -2) printf("Yes\n");
    else printf("No\n");

    printf("sizeof(\"\") = %lu  -2 = %d  -2 = %u\n", sizeof(""), -2, (unsigned int)-2);
}

This outputs

1
Yes
No
Yes
sizeof("") = 1  -2 = -2  -2 = 4294967294

As you can see, when -2 is treated as an unsigned int it becomes a very large number. To understand why this is you might want to study and understand the two's-complement representation of negative numbers.

From the C Standard (5.2.1 Character sets)

  1. ... A byte with all bits set to 0 , called the null character, shall exist in the basic execution character set; it is used to terminate a character string .

and (6.4.5 String literals)

6 In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals.78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.

So each string literal is stored as a character array with static storage duration including the terminating zero.

The empty string literal "" is stored like

char empty_literal[] = { '\0' };

and has the type char[1] . Hence the operator sizeof for this literal (character array) will yield the value 1 of the type size_t that is an unsigned integer type.

When a binary operation is evaluated the compiler at first determines their common type. For example in the condition of the if statement

if(1 > -2) printf("Yes");

there is used the relational operator >. According to the C Standard (6.5.8 Relational operators)

3 If both of the operands have arithmetic type, the usual arithmetic conversions are performed.

As in the condition the both operands 1 and -2 have the type int then the common type of the operands is integer and naturally 1 is greater than -2.

In the condition of this if statement

if( sizeof("") > -2) printf("Yes");

the first operand has the type size_t while teh second operand has the type int. The rank of the type size_t is greater than the rank of the type int so the second operand is converted to the type size_t by propagating the sign bit and the result representation is considered as a representation of unsigned value.

Even if the type size_t had the same conversion rank as the type int nevertheless according to the rules of the usual arithmetic conversions the object of the signed type int was converted to the type unsigned int .

From the C Standard (6.3.1.8 Usual arithmetic conversions)

Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

Here is a demonstrative program

#include <stdio.h>

int main(void) 
{
    unsigned int x = 0;
    signed int y = -1;

    printf( "x + y > 0 is %s\n", x + y > 0 ? "true" : "false" );

    return 0;
}

Its output is

x + y > 0 is true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM