V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wyc9296
V2EX  ›  编程

突然觉得 C 语言字符串数组的初始化有点怪

  •  
  •   wyc9296 · 2022-01-06 22:11:28 +08:00 · 1769 次点击
    这是一个创建于 1083 天前的主题,其中的信息可能已经有所发展或是发生改变。

    既然"abc"是返回常量区字符串的首字符的地址,为什么定义字符串数组时可以用char array[] = "abc";?这里定义的array[]是数组,而不是指针吧?数组怎么会等于指针?如果想解释成:数组名是数组首元素的地址,那么char array[] = {'a','b','c','\0'};这种表达好像又没法解释了?

    ```c
    char array1[] = {'a','b','c','\0'};
    char array2[] = "abc";
    char *pr1 = (char[]){'a','b','c','\0'}; // 用复合字面量表示 
    char *pr2 = "abc";
    ```
    
    7 条回复    2022-01-06 23:04:42 +08:00
    LeoJ
        1
    LeoJ  
       2022-01-06 22:45:40 +08:00
    数组名就是首元素地址啊。\0 表示字符串结束,"abc"实际写入的就是'a' 'b' 'c' '\0',可以理解在 C 语言中""就是个语法糖而已,反正 C 只有 char 类型,没有 string 类型~
    ipwx
        2
    ipwx  
       2022-01-06 22:49:43 +08:00
    在 C++ 里面就没这么奇怪了。

    第一、第二种:相当于常量初始化了数组。

    第三、第四种:虽然能编译,但是会警告,说其实应该赋值给 const char*。
    Origami404
        3
    Origami404  
       2022-01-06 22:53:56 +08:00 via Android
    你可以认为是字符数组初始化的语法糖,这是“如同赋值”规则的一些例外…
    理论上初始化跟赋值是完全两个东西,只是标准要求初始化的效果如同赋值,但实际上初始化的一些语法跟赋值要求是不一样的
    commoccoom
        4
    commoccoom  
       2022-01-06 22:57:29 +08:00
    字符串常量和字符串数组不是同一样东西
    ```
    #include <stdio.h>
    int main(void)
    {
    char str1[3]="abc";
    printf("%x\n",&str1);
    printf("%x\n",str1);
    printf("%x\n",&str1[0]);
    printf("---------------\n");
    char *str2="abc";
    printf("%x\n",&str2);
    printf("%x\n",str2);
    printf("%x\n",&str2[0]);
    return 0;
    }
    ```
    输出
    ```
    8f7d9f0d
    8f7d9f0d
    8f7d9f0d
    ---------------
    8f7d9f00
    bf410018
    bf410018
    ```
    wxd92
        5
    wxd92  
       2022-01-06 22:57:46 +08:00
    @ipwx 第四种是 const 的,第三种可修改的吧
    前三种其实是开辟新空间,把字符串 copy 到 new allocted memory 里; 第四种只是指针指向常量数组
    fishCatcher
        6
    fishCatcher  
       2022-01-06 23:03:48 +08:00 via iPhone
    数组和指针是两个东西,你用 sizeof 试试就知道了啊
    ipwx
        7
    ipwx  
       2022-01-06 23:04:42 +08:00
    @wxd92 ummm 我确实没仔细考虑。但是我觉得不太可能出现这种 implicit new allocated (至少不可能在堆上

    https://godbolt.org/z/M6sPzsWf4

    根据 compiler explorer ,是栈空间。第三种和第一种效果一致,虽然可能生成的破代码更慢。
    ----

    顺便 gcc 拒绝在 c++ 模式下编译第三种
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1108 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:55 · PVG 02:55 · LAX 10:55 · JFK 13:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.