c - 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 标准中称为未定义行为(UB):
- 调用
strlen
的aString
是UB,因为没有空终止 - 在其未定义索引处解引用
aString
是 UB,除非索引为 0、1 或 2 - gcc 可以通过
bString
在 4 字节边界对齐来无意中插入空终止符。不过,这并没有改变它仍然是 UB 的事实。
推荐阅读
- python - Python 高低数猜谜游戏
- python - Django中的Keras顺序模型 - 保留会话?
- javascript - 表数据的for循环
- html - 如何实现 DataTables Fixed Header 功能?
- html - 将两个 DIV 并排放置
- chromium - 为什么我需要在 `npm install` 之后运行 `node install.js` 来“重新安装” Puppeteer?(错误:未下载 Chromium 修订版。)
- review - 如何获得其他开发人员的代码审查
- java - Spark JavaRDD 获取作为 JavaRDD 返回的十个第一个值
- javascript - HTML淡出选择日期并设置当前日期
- git - 已经用 https 克隆后如何 SSH 一个 git 存储库?