首页 > 解决方案 > C编译器的区别?Char 中的 NUL 控制字符

问题描述

下面是将生成 char 数组但是否显式添加 Null 字符的 C 代码。结果在两个编译器中是出乎意料的,我不确定为什么我们甚至必须显式添加 Null 字符?

//
//  stringBugorNot.c
//  
//
//

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


 int main(void)
{
     char aString[3] = {'a', 'b','c'};
     char bString[4] = {'a', 'b', 'c', '\0'};

     printf("\n");
     printf("len of a is: %lu\n", strlen(aString));
     printf("len of b is: %lu\n", strlen(bString));

     printf("\n");

     //Portion A

     printf("last element of a is: '%c'\n", aString[strlen(aString)]);
     printf("last element of b is: '%c'\n", bString[strlen(bString)]);

     printf("\n");

     //Portion B

     printf("last element of a is: '%c'\n", aString[strlen(aString) - 1]);
     printf("last element of b is: '%c'\n", bString[strlen(bString) - 1]);


}

注释

+clang 将给出运行时错误,因为“aString”超出范围.. 有意义 +gcc 不会给出任何错误,只是按预期输出“无”空值。但也许 gcc 更聪明并为我添加了 null ?实际内存大小不同吗?


叮当输出---->

a 的长度为:3

b 的 len 是:3

bugOrNot.c:16:41:运行时错误:索引 3 超出类型“char [3]”的范围

a 的最后一个元素是:''

b 的最后一个元素是:''

a 的最后一个元素是:'c'

b 的最后一个元素是:'c'


GCC 输出 ---->

a 的长度为:9

b 的 len 是:3

a 的最后一个元素是:''

b 的最后一个元素是:''

a 的最后一个元素是:''

b 的最后一个元素是:'c'

标签: c

解决方案


您看到的意外行为在 C 标准中称为未定义行为(UB):

  • 调用strlenaString是UB,因为没有空终止
  • 在其未定义索引处解引用aString是 UB,除非索引为 0、1 或 2
  • gcc 可以通过bString在 4 字节边界对齐来无意中插入空终止符。不过,这并没有改变它仍然是 UB 的事实。

推荐阅读