C 编程中的 sizeof() 行为

sizeof() behaviour in C programming

这是我的程序..

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() 中打印 1 作为输出,尽管我传递了一个空字符串? 在第一个 if-else 语句中,我得到了正确的输出 -> 正如预期的那样,但在第二个 if-else 语句中它打印了输出 -> 不,任何人都可以解释为什么会这样吗?

我的输出是.. 1个 是的 否

提前致谢:-)

C 中的所有字符串都以 [=10=] 空字符结尾。这表示刺结束。

在用 C 语言编程时,最好将数据实际存储在内存中的方式可视化,正如您在此处看到的那样,"Hello" 的长度为 5 个字符,但是必须为 char 数组提供 6 个字符才能为这个空字符保留 space。

根据 Bob Jarvis 的建议,您的示例如下所示:

至于sizeof("") > -2是假的,看看sepp2k的回答

sizeof("") 是一个,因为字符串文字表示包含给定字符 后跟 '\0' 的字符数组。所以""表示字符数组{'[=12=]'}.

sizeof("") > -2是假的,因为sizeofreturns一个size_t,是一个无符号整数类型。比较导致 -2 被转换为 size_t,这导致它回绕并成为比 1 大得多的数字。

根据 @sepp2k 对为什么 sizeof("") < -2 为真的解释,这里是你的程序的修改版本,它清楚地显示了结果:

#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);
}

这输出

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

如您所见,当 -2 被视为 unsigned int 时,它变成了一个非常大的数字。要理解这是为什么,您可能需要研究和理解负数的补码表示。

来自 C 标准(5.2.1 字符集):

  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.

和(6.4.5 字符串文字):

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.

因此每个字符串文字都存储为一个字符数组,其静态存储持续时间包括终止零。

空字符串文字 "" 的存储方式如下:

char empty_literal[] = { '[=10=]' };

类型为 char[1]。因此,此文字(字符数组)的运算符 sizeof 将产生类型 size_t 的值 1,该类型是无符号整数类型。

当计算二元运算时,编译器首先确定它们的公共类型。例如在if语句的条件中:

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

使用了关系运算符>。根据 C 标准(6.5.8 关系运算符):

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

因为在条件中操作数 1-2 的类型都是 int 那么操作数的共同类型是整数,自然 1 大于 -2。

在这个if语句的条件下:

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

第一个操作数的类型为 size_t,而第二个操作数的类型为 int。 size_t 类型的秩大于 int 类型的秩,因此第二个操作数通过传播符号位转换为 size_t 类型,结果表示被视为无符号值的表示.

即使类型 size_t 与类型 int 具有相同的转换级别,但根据通常的算术转换规则,带符号类型 int 的对象被转换类型 unsigned int.

来自 C 标准(6.3.1.8 常用算术转换):

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.

这里有一个演示程序:

#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;
}

它的输出是:

x + y > 0 is true