【发布时间】:2018-12-22 21:26:49
【问题描述】:
我今天一直在搞乱 c,当我注释掉这段代码中的第三个缓冲区时,我不明白输出的差异:
#include <unistd.h>
#include <string.h>
#include <stdio.h>
void main() {
unsigned char letters[10];
memset(letters, 0x00, 10);
memset(letters, 0x41, 10);
printf(letters);
printf(" Total buffer len: %d bytes\n",strlen(letters));
char nletters[10];
memset(nletters, 0x00, 10);
memset(nletters, 0x42, 10);
printf(nletters);
printf(" Total buffer len: %d bytes\n",strlen(nletters));
int nums[10];
memset(nums, 0x00, 10);
memset(nums, 0x43, 10);
printf(nums);
printf(" Total buffer len: %d bytes\n",strlen(nums));
return 0;
}
不同之处在于移除了 nums 缓冲区周围的 cmets:
AAAAAAAAAA�7ǝ�U Total buffer len: 16 bytes
BBBBBBBBBBAAAAAAAAAA�7ǝ�U Total buffer len: 26 bytes
并保留缓冲区:
AAAAAAAAAA Total buffer len: 10 bytes
BBBBBBBBBBAAAAAAAAAA Total buffer len: 20 bytes
CCCCCCCCCC��U Total buffer len: 14 bytes
我没有得到的是:
看在上帝的份上,注释掉第三个缓冲区会如何影响其他缓冲区的大小?
缓冲区末尾的额外字节是什么?如何丢失/管理它们(如果我选择连接缓冲区)?
为什么选择是否注释第三个缓冲区时,打印的缓冲区大小和初始化的大小不一致?
缓冲区 2 应该是 10 个字节,为什么是 20 个?我不希望是20,我只要求10。我不认为这是不合理的。
【问题讨论】:
-
欢迎来到软件工程。我们只支持good、on-topic 提问。 Many sites 有 different rules。如果存在,请随时将您的问题带到适当的站点。首先搜索现有答案。编辑您的问题以适应网站需求。请don't cross post 未在此处删除您的问题。
-
您缺少空终止的概念。 C 字符串应该有一个空字符来指示字符串的结尾。如果字符串末尾没有空终止字符,则无法预测程序的行为,因为
strlen正在访问正在传递的数组之外的内存。就 C 而言,提供空终止符是程序员的责任。现在,让我问你:如果最后还需要一个空终止字节,那么存储 10 个真实/用户字符需要多少字节的实际 char/unsigned char 存储? -
另外,请考虑
sizeof(letters)和strlen(letters)之间的区别。前者是一个编译时常量,它转到letters的实际声明(并且只给出不考虑或考虑空终止字符的原始大小),而后者是运行时搜索空终止字符以查找存储在(可能)足够大的空间中的实际字符串(没有空字符)的长度。 -
编译时,始终启用警告,然后修复这些警告,(对于
gcc,至少使用:-Wall -Wextra -Wconversion -pedantic -std=gnu11)除其他外,(无论 Visual Studio 允许什么) functionmain()的返回类型始终为int,而不是void。为什么main()被声明为返回void但包含语句:return 0;? -
这是重复的:该用户在几个 SO 网站上发布了完全相同的问题,但用户名略有不同