2017-04-13 86 views
-2

据我所知,字符串被CUL中的NUL '\0'字节终止。然而,我不明白为什么0在字符串文字中的行为不同于0在堆栈中创建的char数组中。当在文字中检查NUL终止符时,数组中间的零不会被视为这样。NUL字符和静态字符数组/字符串在C

例如:

#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 

int main() 
{ 

    /* here, one would expect strlen to evaluate to 2 */ 
    char *confusion = "11001"; 
    size_t len = strlen(confusion); 
    printf("length = %zu\n", len); /* why is this == 5, as opposed to 2? */ 



    /* why is the entire segment printed here, instead of the first two bytes?*/ 
    char *p = confusion; 
    while (*p != '\0') 
     putchar(*p++); 
    putchar('\n'); 



    /* this evaluates to true ... OK */ 
    if ((char)0 == '\0') 
     printf("is null\n"); 


    /* and if we do this ... */ 
    char s[6]; 
    s[0] = 1; 
    s[1] = 1; 
    s[2] = 0; 
    s[3] = 0; 
    s[4] = 1; 
    s[5] = '\0'; 

    len = strlen(s); /* len == 2, as expected. */ 
    printf("length = %zu\n", len); 

    return 0; 
} 

输出:

length = 5 
11001 
is null 
length = 2 

为什么会发生这种情况?

+0

字符串文字** **是一个'char'阵! C语言中没有堆栈。而指针不是一个数组。 “在这里,人们会希望strlen评价为2” - 为什么?看起来好像对数组,指针和字符串有一些误解。 – Olaf

+2

因为'0'!= 0 – John3136

+1

字符'0'的值为48([通常](https://en.wikipedia.org/wiki/EBCDIC))。空终止符“'\ 0''的值为零。 –

回答

1

变量“混乱”是指向一个文本字符串的字符。 所以内存看起来像

[11001\0] 

所以,当你打印变量“混乱”,将打印的一切,直到它由\ 0表示第一个空字符。
11001中的零不为空,因为它被双引号包围,所以它们几乎为零。

但是,在变量's'的char数组赋值中,您正在为0到 char变量赋值十进制值。当你这样做时,ASCII字符值为NULL字符的ASCII十进制值0被分配给它。所以字符数组看起来像在存储

[happyface, happyface, NULL] 

ASCII字符happyface有1 ASCII十进制值所以,当您打印时,它会照常进行到第NULL,因此 strlen的是2。

这里的诀窍是理解当给它分配一个十进制值时真正赋予一个字符变量的是什么。

试试这个代码:

#include <stdio.h> 

int 
main(void) 
{ 
    char c = 0; 

    printf("%c\n", c); //Prints the ASCII character which is NULL. 
    printf("%d\n", c); //Prints the decimal value. 

    return 0; 

}

0

'0'和0不是相同的值。 (第一个是48,通常,尽管技术上精确的值是实现定义的,并且写入48来指代字符'0'被认为是非常糟糕的样式。)

如果'0'终止了字符字符串,你不能把零置于字符串中,这会有点......限制。