2016-05-12 106 views
-1

我有这样的代码初始化“的字符串”

#include<stdio.h> 
    #include<string.h> 

    int main(void) 
    { 
     size_t i; 
     char arr[5] = ""; 
     for(i = 0; i < 5; i++) 
      printf("%c ", arr[i]); 

     puts(""); 

     memset(arr, '0', 5); 
     for(i = 0; i < 5; i++) 
      printf("%c ", arr[i]); 
     return 0; 
} 

为什么第一个printf只打印空间,而第二打印归零

这究竟是为什么?

+0

你期待第一个打印什么?第二个呢? (真正的问题,它可能有助于他人回答他们的问题) –

+2

您正在将字符'0'替换为空字节到内存中。只需用''0'替换''0''。 – H2O

+0

你为什么要这样做?您的arr [5]仅包含“”和“\ 0”,并且您试图最多打印五个索引。你对此有什么期望? –

回答

-1

如果使用小于数组的字符串字面值初始化数组,则会将包括尾随NUL的字符串复制到数组中。任何多余的元素将根据用于初始化具有静态存储持续时间的变量的相同规则进行初始化,对于char0。 (q.v. C99 6.7.8/21)

第一个printf循环使用%c一次一个字符地打印阵列。 因此,当您在数组初始化为""(相当于{'\0'})时,数组将被初始化为全零:来自空终止符的第一个零和其他值,因为这是具有静态持续时间的char的默认值。由于零的十进制值表示NUL的ASCII值,因此printf会打印... NUL,它通常显示为空格。

对于第二个,您将数组设置为ASCII 0,因为您将所有值设置为0,这是十六进制值0x30(我忘记了十进制转换)。所以,既然你打印%c,将打印的ASCII 0

现在,如果你改变你的第一个printf打印%d,而不是%c,那么它会打印存储在数组中的整数值,这将全都是零。如果您更改第二个printf以打印%x,那么它将打印一堆0x30。

阅读%c,%d,%x和其他printf标志之间的区别,以及它们如何表现。

+2

一个简单的问题,为什么这个数组“*动态分配*”?另外,''''不是'NULL',它相当于'{'\ 0'}'''''''''是'null'而不是'NULL'。和'0x30' - >'3 * 16 == 48' !!!!! –

+1

大部分是正确的,但是应该是NUL或''\ 0'',而不是NULL。 NUL和''\ 0''代表一个ASCII 0(不要与ASCII'0'混淆,当然,因为*是* 48)。 NULL特别是null *指针*常量,它也是0(或'(void *)0'),但在空指针常量的情况下,一旦它转换为指针类型,它不一定对应于地址0,但仅限于*某些不与任何非空指针进行比较的地址。所有这些都需要比空终止的字符串更迂腐,所以最好保持概念不同。 – Ray

+0

@Ray事实证明,它是'空',它是'NUL'。我像你一样想到它。我知道我通常在大多数ascii表中看到'NUL',但根据[tag:c]标准它是'null'。 –