【问题标题】:Why can't compiler derive string length for array of strings?为什么编译器不能为字符串数组派生字符串长度?
【发布时间】:2010-12-16 03:15:23
【问题描述】:

注意:这个问题受到this answer的影响。

以下是有效的 C 代码:

char myString[] = "This is my string";

这将在堆栈上分配一个长度为 18 的字符串(包括\0 字符)并为其分配指定的值。

但是,以下内容:

char myStrings[][] = {"My 1st string", "My 2nd string", "My 3rd string"};

无效,给出错误“数组类型的元素类型不完整”。

所以我必须像这样指定数组:

char myStrings[][20] = {"My 1st string", "My 2nd string", "My 3rd string"};

其中 20 是一个比我最长的字符串大的数字。

这会按预期编译和工作。

如果编译器在堆栈上分配单个字符串时可以动态感知字符串长度,为什么它不能对字符串数组这样做呢?

编辑:

澄清一下,这不是我遇到的现实生活中的编程问题 - 这只是病态的好奇心。

【问题讨论】:

    标签: c string stack memory-management


    【解决方案1】:

    因为编译器看到了这个

    char myStrings[][20] = {"My 1st string", "My 2nd string", "My 3rd string"};
    

    作为

    char myStrings[][20] = {(char*), (char*), (char*)};
    

    然后,errrr ... hmmm,通过“编译器魔术”,它可以将那些(char*) 中的字符复制到数组myStrings[0] 和myStrings[1],...。


    编辑

    你不能在 C 中使用“锯齿状数组”。假设你有

    char my_strings[][] = {"a", "ab", "abc", "foo foo fo foo foo", "abc", "ab", "a"};
    

    my_strings[0] 需要与my_strings[3] 相同的空间,因为该语言要求数组元素是连续的,并且它需要每个数组的特定大小。

    内存中的 my_strings 'a' '\0' '\0' ... '\0' 但必须是确定的大小 'a' 'b' '\0' ... '\0' 确定大小 ... 'f' 'o' 'o' ... '\0' ...

    要找到最大大小并初始化数组,编译器需要对字符串文字进行两次传递。

    【讨论】:

    • 每个字符串的“多余”字符内存不会包含垃圾。它将用零填充。 C 语言在初始化时使用的一般理念是,某些东西要么完全未初始化(整个东西都是垃圾),要么完全初始化(没有用户提供的初始化程序的部分是零初始化的)。例如,当您声明char s[100] = "a" 时,不仅s[0]s[1] 被初始化,而且从s[2]s[99] 的所有元素都保证为零初始化。
    • 谢谢安德烈。编辑了我的答案
    【解决方案2】:

    为什么不这样做:

    const char* myStrings[] = {"My 1st string", "My 2nd string", "My 3rd string"};
    

    【讨论】:

    • 有时你需要可修改的字符串
    • +1 @jeffamaphone 非常好。 @pmg,我认为,问这个问题的人的意图只是创建一个常量字符串。
    • 正如 pmg 所指出的,这意味着生成的字符串是只读的。
    • @Alphaneo - 不,这个问题比其他任何问题都更令人好奇,但可修改也是有用的。
    • 没错,但我发现在这些情况下,这几乎总是您真正想要的。另一种情况是他真的想要一个vector,如果他被困在C语言中,他就可以自己写了。
    【解决方案3】:

    一件事是“感知”一个字符串的长度。另一件事是计算许多字符串的最大长度。两者之间存在一定的直观质的差异。所以,语言作者可能认为前者简单有用,但后者过于编译,用处不大。

    【讨论】:

    • +1 好答案 - 更符合我的想法。
    【解决方案4】:

    char myString[] = "..." 是一个一维数组,它可以工作。 char myStrings[][] = {"...", "..."} 是一个具有(可能)不同行长度的二维数组,这将不起作用。 char myStrings[][20] 是一个具有固定行长的二维数组,它可以工作。

    根据 C 标准,编译器无法感知二维数组中字符串的长度。

    但我想,这在 Java 中是可能的。

    【讨论】:

    • 这在 Java 中是可能的,因为字符串数组总是指针数组。
    猜你喜欢
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2016-05-12
    相关资源
    最近更新 更多