代码之家  ›  专栏  ›  技术社区  ›  quinmars

(字符串)文本的范围

  •  28
  • quinmars  · 技术社区  · 16 年前

    我总是尽量避免返回字符串文本,因为我担心它们不是在函数外部定义的。但我不确定情况是否如此。例如,让我们以这个函数为例:

    
    const char *
    return_a_string(void)
    {
        return "blah";
    }
    

    这是正确的代码吗?它确实适用于我,但可能只适用于我的编译器(gcc)。所以问题是,(字符串)文本是否有作用域,或者它们是否一直存在/定义?

    7 回复  |  直到 13 年前
        1
  •  40
  •   Brian R. Bondy    16 年前

    这个代码适用于所有平台。该字符串作为静态字符串文本编译到二进制文件中。例如,如果您在Windows上,甚至可以用记事本打开.exe并搜索字符串本身。

    因为它是一个静态字符串,所以文字范围并不重要。

    字符串池:

    需要注意的一点是,在某些情况下,相同的字符串文本可以“合并”以节省可执行文件中的空间。在这种情况下,相同的每个字符串文字可能具有相同的内存地址。不过,你不应该认为情况会或不会是这样。

    在大多数编译器中,您可以设置是否对string文本使用静态字符串池。

    字符串文本的最大大小:

    几个编译器的字符串文本的大小是最大的。例如,对于VC++,这大约是2048字节。

    修改字符串文字会给出未定义的行为:

    永远不应该修改字符串文字。它有一个未定义的行为。

    char * sz = "this is a test";
    sz[0] = 'T'; //<--- undefined results
    

    宽字符串文字:

    以上所有内容都同样适用于宽字符串文本。

    示例:l“这是一个宽字符串文本”;

    C++标准声明: (lex.string节)

    1字符串是一个序列 字符数(定义见 莱克森 )由双引号包围,可以从 字母L,如“…”或L“…”中所示。不以开头的字符串文本 L是一个普通的字符串文字,也被称为窄字符串 字符串文本。普通字符串文本具有“n数组”类型 康斯特 char”和静态存储持续时间( 基础STC ,其中n是 大小 以下定义的字符串,并用给定的 字符。以l开头的字符串文字,如l“asdf”, 是 宽字符串文本。宽字符串文本具有类型“array of n const wchar_t“并具有静态存储持续时间,其中n是大小 属于 字符串定义如下,并用给定的charac初始化- 特斯。

    2是否所有字符串文本都是不同的(即存储在 不重叠的对象)是实现定义的。效果 属于 试图修改字符串文字未定义。

        2
  •  9
  •   Sumit Trehan    13 年前

    我给你举个例子,让你的困惑变得更加清晰

    char *f()
    {
    char a[]="SUMIT";
    return a;
    }
    

    这行不通。

    但是

    char *f()
    {
    char *a="SUMIT";
    return a;
    }
    

    这是可行的。

    原因:“sumit”是一个具有全局范围的文本。 而数组只是一个字符序列'S'、'U'、'M'、'I'、'T''\0' 范围有限,程序一返回就消失。

    希望这有帮助

        3
  •  5
  •   Steve Jessop    16 年前

    这在C(或C++)中是有效的,正如其他人所解释的。

    我能想到的一点是,如果您使用的是DLL,那么如果卸载了包含此代码的DLL,指针将不会保持有效。

    C(或C++)标准在运行时不理解或考虑加载和卸载代码,因此,任何这样的操作都将面临实现定义的后果:在这种情况下,结果是,字符串应该是静态存储持续时间,从调用代码的POV中出现,而不是为F持久化。计划的全部持续时间。

        4
  •  3
  •   Bill K    16 年前

    是的,没关系。它们生活在一个全局字符串表中。

        5
  •  3
  •   Adam Rosenfield    16 年前

    不,字符串文本没有作用域,因此您的代码保证可以跨所有平台和编译器工作。它们存储在程序的二进制映像中,因此您可以随时访问它们。但是,尝试写信给他们(通过扔掉 const )将导致未定义的行为。

        6
  •  0
  •   PhiLho    16 年前

    实际上,您返回一个指针,指向存储在可执行文件的数据段中的以零结尾的字符串,这是加载程序时加载的区域。只需避免尝试更改字符,它可能会产生不可预知的结果…

        7
  •  0
  •   Jason Coco superfell    16 年前

    注意布莱恩提到的未定义的结果是非常重要的。由于您已经声明函数返回const char*类型,所以应该可以这样做,但在许多平台上,字符串文本被放置到可执行文件(通常是文本段)的只读段中,修改它们将导致大多数平台上的访问冲突。