【问题标题】:Sizeof(char[]) in CC中的大小(char [])
【发布时间】:2015-05-07 13:02:24
【问题描述】:

考虑这段代码:

 char name[]="123";
 char name1[]="1234";

这个结果

The size of name (char[]):4
The size of name1 (char[]):5

为什么char[]的大小总是加一?

【问题讨论】:

  • 字符串以 NUL 结尾,需要一个额外的字节。
  • 正确,但请注意您也可以初始化未终止的字符串(不要!)char name[8] = "12345678"; sizeof(name) = 8; name[8] = random!!

标签: c arrays sizeof


【解决方案1】:

注意sizeofstrlen 之间的区别。第一个是给出整个数据项大小的运算符。第二个是返回字符串长度的函数,该长度将小于其sizeof(除非您设法使字符串溢出),具体取决于实际使用了多少分配的空间。

在你的例子中

char name[]="123";

sizeof(name) 是 4,因为终止 '\0',而strlen(name) 是 3。

但在这个例子中:

char str[20] = "abc";

sizeof(str) 是 20,strlen(str) 是 3。

【讨论】:

  • 比我自己的回答还要好:-),+1
  • 'strlen' 也是在运行时实例化的,所以如果你使用固定大小的数组(如本例所示),最好选择 'sizeof' 以保证小毫秒的安全节目时间。
  • 我总是更喜欢正确的,而不是更快的。节省的时间将是纳秒,而不是毫秒。而且,许多编译器足够聪明,可以自己判断出示例中的 strlen (str) 为 3,因此无需调用它。
  • IMO 这应该是公认的答案,因为看起来 OP 不知道它们的区别以及它们的用途。
【解决方案2】:

正如迈克尔在 cmets 中指出的那样,字符串以零结尾。所以在内存中第一个字符串看起来像这样

"123\0"

其中\0 是单个字符,ASCII 值为 0。那么上述字符串的大小为 4。

如果你没有这个终止字符,你怎么知道字符串(或char[])在哪里结束?好吧,实际上另一种方法是将长度存储在某处。有些语言会这样做。 C 没有。

【讨论】:

  • 好的,但是为什么?你能解释更多吗?
  • 对“然后上面的字符串大小为 4.”进行吹毛求疵,如果定义为 char s= [] = "123\0";,则大小为 5 ... :-)
【解决方案3】:

在 C 中,字符串存储为 chars 的数组。使用可识别的终止字符('\0' 或只是0),您可以将指针传递给字符串,而无需任何进一步的元数据。处理字符串时,从指针指向的内存中读取字符,直到到达终止值。

由于您的数组初始化使用的是字符串文字:

char name[]="123";

相当于:

char name[]={'1','2','3',0};

如果您希望数组大小为 3(没有终止字符,因为您不存储字符串,您将需要使用:

char name[]={'1','2','3'};

char name[3]="123";

(谢谢alk) 这将按照您的预期进行。

【讨论】:

  • "如果您希望数组大小为 3 ...",您也可以使用 char name[3] = "123"
  • @alk 谢谢,我忘了那个。
  • 虽然 char name[3] = "123" 表示没有尾随 nul 字符,这意味着例如 strlen(name) 可能会崩溃或更糟。
  • @gnasher729 是的。尽管目的是生成一个没有空终止符(而不是字符串)的字符数组,但您不会期望在其上运行 strlen()。就个人而言,除非我正在运行一个大型应用程序并且使用大量这样的数组进行对齐或缓存未命中,否则我会很乐意在我的数组中获取额外的字符,这样就不会发生这种情况,即使是偶然的。我可能应该在我的示例中使用char array[](因为“名称”意味着一个字符串),但我选择保留问题命名。
【解决方案4】:

因为 C 中的字符串末尾附加了一个空字符。

就像你的情况一样

name[0] = '1'
name[1] = '2'
name[2] = '3'
name[3] = '\0'

name1[0] = '1'
name1[1] = '2'
name1[2] = '3'
name1[3] = '4'
name1[4] = '\0'

【讨论】:

    【解决方案5】:

    C 中的String(以及可能在每种编程语言中——在幕后)是一个字符数组,由\0 终止,ASCII 值为 0。

    当分配:char arr[] = "1234"; 时,您分配一个字符串文字,默认情况下,它以 null 结尾(\0 也称为 null),如您所见 here

    为避免出现空值(假设您只需要 chars 的数组而不是字符串),您可以通过以下方式声明它 char arr[] = {'1', '2', '3', '4'}; 并且程序将按照您的意愿运行(sizeof(arr) 将是 4 )。

    【讨论】:

    • 不是所有的编程语言。在字符串是计数序列的语言中,字符串后面的 NUL(如果有)只是为了尽量减少不尊重计数的互操作代码(如 C)的问题。
    • @TomBlodget 通过说“可能”,我说我不确定 - 实际上我很确定有些编程语言的字符串不是以空值结尾的。
    【解决方案6】:
    name = {'1','2','3','\0'};
    name1 = {'1','2','3','4','\0'};
    

    所以

    sizeof(name) = 4;
    sizeof(name1) = 5;
    

    sizeof 返回对象的大小,在这种情况下,对象是一个数组,并且定义了您的数组在第一种情况下为 4 个字节,在第二种情况下为 5 个字节。

    【讨论】:

      【解决方案7】:

      在 C 中,字符串文字添加了一个空终止字符。

      你的字符串,

       char name[]="123";
       char name1[]="1234";
      

      看起来更像:

       char name[]="123\0";
       char name1[]="1234\0";
      

      因此,大小总是加一。请记住,从文件或任何来源读取字符串时,存储字符串的变量应始终为空终止字符留出额外空间。

      例如,如果您希望读取最大大小为 100 的字符串,则缓冲区变量的大小应为 101。

      【讨论】:

        【解决方案8】:

        每个字符串都以 char nullbyte '\0' 结尾,它会将长度加 1。

        【讨论】:

        • 嗯,并非总是如此。例如,char name[3] = "123"; 不是 NUL 终止的。
        猜你喜欢
        • 2021-10-11
        • 1970-01-01
        • 2020-10-18
        • 2012-03-21
        • 2018-04-14
        • 1970-01-01
        • 2021-12-13
        • 1970-01-01
        • 2023-02-10
        相关资源
        最近更新 更多