转义字符组成的字符串字面量的大小

5

相关代码:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    cout << sizeof("\n\r\t") << endl; // prints 4
    cout << strlen("\n\r\t") << endl; // print 3
    return 0;
}

我很困惑,因为我一直以为sizeof char的标准大小应该是1个字节,但是在上面的代码中,输出的结果是4。

这是否有解释或者对于转义字符有例外情况?请帮助我理解。

4个回答

6
这里唯一的区别是strlen不包括空字符,而sizeof会包括它。在这种情况下,C文档中的strlen更好,因为它包含了以下语句:

空字符不包括在长度内。

为了澄清一些问题,字符串字面量是一个包含空字符的数组,从草案C++标准的第2.14.5节“字符串字面量”第8段说起:

普通字符串字面量和UTF-8字符串字面量也被称为窄字符串字面量。窄字符串字面量的类型为“n const char的数组”,其中n是如下定义的字符串的大小,并具有静态存储期(3.7)。

第15段说:

[...]窄字符串字面量的大小是转义序列和其他字符的总数,加上每个通用字符名的多字节编码至少为1,加上终止符“\0”的至少1个。

并且应用于数组的sizeof将给出数组中的总字节数,来自第5.3.3节“Sizeof”的第3段:

[...]当应用于数组时,结果是数组中的总字节数。这意味着n个元素的数组的大小是n倍的元素大小。


哈哈,我刚刚在相关问题中看到了这个。不过还是谢谢你。 - smac89

4

This

"\n\r\t"

这是一个所谓的字符串字面量。它以终止零存储在内存中,作为常量字符数组。每个转义字符都是一个字符。

因此,这个字符串字面量有三个明确指定的字符加上终止零。总共有四个字符在字面量中。

至于函数strlen,它不考虑终止零。因此,它只报告了在字符串字面量中明确定义的三个字符。

函数strlen使用终止零作为标记,在该标记处停止计算字符串中的字符数。

至于运算符sizeof,它返回对象占用的总内存字节数。由于您的字符串字面量类型为const char[4],因此sizeof将返回4,即字符串字面量占用的总内存字节数。


每个转义字符都是一个字符。你的意思是每个“转义序列”是一个字符。每个“转义字符”计为1/2个字符。 - cowlinator

3

字符串以空字符\0结束,因此字符串的长度比实际字符数多1。

\n\r\t\0都只占用一个字节,因此总共只占用4个字节!

这个问题的选定答案中摘录一段话,与上文相呼应:

字符串字面值的类型为“大小为N的[const] char数组”,其中N包括终止符null。

请记住,当传递给sizeof时,数组不会衰减为指针。


1
通过在字符串字面值上调用sizeof(),您实际上正在尝试查找内存中字符串字面值的大小。这包括由编译器自动附加到字符串字面值的空终止字符。

这是不正确的,字符串字面量是一个数组,对数组应用sizeof将返回数组中的总字节数。 - Shafik Yaghmour
@ShafikYaghmour 我试过之后立刻意识到了,我已经编辑过了。 - turnt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接