当使用字符串文字初始化字符数组时,数组表达式不会转换为指针

时间:2017-08-12 20:51:17

标签: c

来自C in a Nutshell:

  

在大多数情况下,编译器会隐式转换表达式   将数组类型(例如数组的名称)转换为指向的指针   数组的第一个元素。

     

数组表达式不会仅转换为指针   以下情况:

     

•当数组是sizeof运算符的操作数时

     

•当数组是地址运算符&

的操作数时      

当字符串文字用于初始化char数组时,   wchar_t,char16_t或char32_t

  1. 你能解释一下最后一个子弹的意思吗? 反面的例子?我在书中找不到最后一个例子 子弹。
  2. 为什么是一个字符数组,而不是其他元素类型?

2 个答案:

答案 0 :(得分:2)

char *ptr = "Hello OP!!";

ptr是指向存储在RODATA段中的字符串文字的第一个char的指针。当您取消引用它时,您只能读取而不能写入值,因为字符串文字是常量字符数组。

char arr[] = "Hello OP!! How are you my friend?";

在这种情况下:

  1. arr数组长度大小为文本分配空间,包括尾随零。
  2. 将字符串文字复制到为arr数组
  3. 分配的空间中

    在这种情况下,arr用作内存中复制字符串文字的位置。

    您可以读取和写入arr元素被读取和读取写

    现在回答这个问题

    • 数组的sizeof是所有数组元素的大小(以字节为单位)。如果数组被转换为指针 - 大小将是指针的大小,在这种情况下显然是错误的
    • 数组只是内存中容纳其所有元素的连续空间。因此,数组的地址始终是此内存位置的地址
    • 我已经在上面解释的第三种情况

    你可以看到代码 https://godbolt.org/g/xVL5cR

    ** TIM的注意事项**字符串文字不会转换为任何内容。字符串文字只存储为char(wchar_t ....)数组,最后在RO内存中使用NUL(NOT NULL)终止符。

答案 1 :(得分:1)

  

为什么是一个字符数组,而不是其他元素类型?

它的字符串文字具有静态存储持续时间,因此存在于程序生命周期的内存中。

尝试修改字符串文字(使用指向文字的指针)会导致未定义的行为:它们可能存储在只读存储中(例如{{1} })或与其他字符串文字结合使用。

任何其他常量都不会像这样存储,所以这就是为什么只有字符数组(文字)。

  

你能解释一下最后一个子弹的意思吗?   反面的例子?我在书中找不到最后一个例子   子弹。

字符串文字初始化如下所示:

.rodata

字符串文字从静态存储持续时间复制到自动存储持续时间,可以修改它。

虽然

char ptr[] = "Hello world!";     // This is char[]
char ptr[] = L"Hello world!";    // This is wchar_t[]
char ptr[] = u8"Hello world!";   // This is char[]
char ptr[] = u"Hello world!";    // This is char16_t[]
char ptr[] = U"Hello world!";    // This is char32_t[]

不会是字符串文字,也不会有静态持续时间存储