sizeof()行为在C语言编程中的应用

问题描述 投票:0回答:1

这是我的程序...

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语句中,我得到了正确的输出-> Yes,如预期的那样,但在第二条if-else语句中,它打印出了输出-> No,有人能解释一下为什么会发生这种情况吗?

我的输出是...1YesNo

先谢谢你:-)

c sizeof
1个回答
4
投票

C语言中所有的字符串都以 \0 空字符。这标志着蛰伏结束。

当用C语言编程时,最好能直观地看到数据是如何存储在内存中的,正如你在这里看到的,"Hello "是5个字符,但是必须给char数组6个字符,以便为这个null字符留下空间。

Sting memory representaion in C

下面是Bob Jarvis建议的例子。

enter image description here

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


6
投票

sizeof("") 是一个,因为字符串字元表示包含给定字符的字符数组。后面是'0'。. 所以... "" 代表字符数组 {'\0'}.

sizeof("") > -2 是假的,因为 sizeof 返回一个 size_t,这是一个无符号整数类型。比较会导致 -2 拟转为 size_t导致它被包裹起来,成为一个比1大得多的数字。


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 它变成了一个非常大的数字。要理解为什么会这样,你可能要学习和理解负数的二氏补码表示法。


1
投票

摘自C标准(5.2.1字符集

  1. ... 一个所有位都设置为0的字节称为空字符,应存在于基本执行字符集中;其 用于结束一个字符串.

和 (6.4.5 字符串文字)

6在翻译阶段7中,将一个值为零的字节或代码附加到由一个或多个字符串文字所产生的每个多字节字符序列上。) 然后,多字节字符序列被用来初始化一个静态存储持续时间和长度刚好足以包含该序列的数组。

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

空字符串字面意思是 "" 储存为

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

并具有以下类型 char[1]. 因此,这个字面(字符数组)的运算符 sizeof 将会产生值 1 属于 size_t 是一个无符号整数类型。

当二进制操作被评估时,编译器首先确定它们的共同类型。例如在if语句的条件中

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

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

3 如果两个操作数都有算术类型,则进行通常的算术转换。

如在两个操作数都是 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 通常的算术转换)

否则,如果具有无符号整数类型的操作数的等级大于或等于其他操作数类型的等级,则将具有有符号整数类型的操作数转换为具有无符号整数类型的操作数的类型。

下面是一个演示程序

#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
© www.soinside.com 2019 - 2024. All rights reserved.