Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C字符串文字的最大长度与最大字符[]不同?_C_Standards - Fatal编程技术网

为什么C字符串文字的最大长度与最大字符[]不同?

为什么C字符串文字的最大长度与最大字符[]不同?,c,standards,C,Standards,澄清:假设字符串文本可以重写为常量 char[](见下文),将文字的最大长度设置为比 char[]s只是语法上的不便。为什么C标准 鼓励这一点 C89标准对字符串文字有翻译限制: 字符串文字或宽字符串文字中的509个字符(串联后) 字符数组没有限制;或许 对象中的32767字节(仅在托管环境中) 适用(我不确定对象或托管环境是什么意思),但无论如何,这是一个更高的限制 我的理解是,字符串文字相当于包含字符的字符数组,即:总是可以重写如下内容: const char* str = "foo";

澄清:假设字符串文本可以重写为
常量
char[]
(见下文),将文字的最大长度设置为比
char[]
s只是语法上的不便。为什么C标准 鼓励这一点


C89标准对字符串文字有翻译限制:

字符串文字或宽字符串文字中的509个字符(串联后)

字符数组没有限制;或许

对象中的32767字节(仅在托管环境中)

适用(我不确定对象或托管环境是什么意思),但无论如何,这是一个更高的限制

我的理解是,字符串文字相当于包含字符的字符数组,即:总是可以重写如下内容:

const char* str = "foo";
进入这个

static const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' };
const char* str = __THE_LITERAL;

那么,为什么要对文字进行如此严格的限制呢?

正如前面所解释的,不是509个字符是字符串的限制,而是ANSI兼容性所要求的最小值

我认为标准的制造商们把数字509从他们的屁股里拔了出来,但是除非我们从中得到一些官方文件,否则我们没有办法知道

至于一个字符串文字中可以包含多少个字符,这取决于编译器

以下是一些例子:

  • MSVC:2048
  • GCC:无限制(最多100000个字符),但在510个字符后给出警告:

    长度为100000的字符串文字超过了C90编译器需要支持的最大长度509


对字符串文本的限制是编译时的要求;逻辑源代码行的长度也有类似的限制。编译器可以使用固定大小的数据结构来保存源代码行和字符串文本

(C99将这些特定限制从509个字符增加到4095个字符。)

另一方面,可以在运行时构建对象(例如
char
的数组)。这些限制可能是由目标机器体系结构施加的,而不是由编译器的设计施加的


请注意,这些不是强加给程序的上限。编译器根本不需要施加任何有限的限制。如果编译器对行长度施加了限制,则它必须至少为509或4095个字符。(我认为,大多数实际的编译器不会强加固定的限制,而是动态地分配内存。)

很抱歉回答得太晚,但我想说明这两种情况之间的区别(Richard J.Ross已经指出,它们并不等同。)

假设您尝试以下方法:

const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' };
const char* str = __THE_LITERAL;
char *str_writable = (char *) str;  // Not so const anymore
str_writable[0] = 'g';
现在
str
包含“goo”

但如果你这样做:

const char* str = "foo";
char *str_writable = (char *) str;
str_writable[0] = 'g';
结果:SEGFULT!(至少在我的平台上。)

这里是基本的区别:在第一种情况下,您有一个初始化为“foo”的数组,但在第二种情况下,您有一个实际的字符串文本

另一方面

const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' };
完全等同于

const char __THE_LITERAL[] = "foo";
这里,
=
充当数组初始值设定项,而不是赋值。这与我的想法大不相同

const char *str = "foo";

当字符串文本的地址被分配给
str

时,他们选择509而不是65533或253是非常奇怪的。您可能希望阅读这篇文章:对程序源的限制与对编译程序的限制无关。@SethCarnegie:也许509是为了允许一个512字节的缓冲区,其中两个字节用于一个字节
“\r\n”
行终止符和一个用于
'\0'
字符串终止符。有趣的信息,但它实际上没有回答这个问题。@KeithThompson我不同意。它回答了这个问题,因为它解释了它不是一个“限制”,而是一个“最小值”,所以在大多数编译器上,没有区别。我认为关键的一点是,标准中引用的509是一个最小值,而不是最大值。@npostavs我认为这就是你不正确的地方。
const char*
与初始化的
const char[]
有很大不同,特别是它位于内存中。@RichardJ.RossIII,关于您关于509来自何处的评论:我不认为它来自某人的屁股。这是509个字符,为单字节字符串结尾字符(
\0
)留出了空间和一个双字节指针。至少,这是我的猜测。虽然如果编译器是32位可执行文件,当然会有实际限制,但它肯定无法处理4G以上的字符串文字(尽管存在对象文件格式限制)。实际的限制当然要低得多。初始化的
const char[]
不是也在编译时生成的吗?@npostavs:可以,但是32767字节的限制(在C99中增加到65536)适用于运行时对象,不管它们是如何生成的。哦,我的意思是,这个字面值是一个静态变量,在这种情况下,segfault会导致两种情况。@npostavs:Hmm,你说得对。有趣。实际上,我把
=“foo”
完全当作
={f'、'o'、'o'、'\0'}
来对待是错误的。如果我使用超过509个字符执行相同的操作,gcc会在第一种情况下发出警告,但在第二种情况下不会。我想这是因为Keith Thompson上面说的——编译器可能会使用固定大小的数据结构来处理文本。