在C中用字符串常量初始化数组的机制

时间:2017-10-04 06:37:17

标签: c arrays c-strings

定义是什么:

char arr_of_chars[] = "hello world";

在内存中的某处创建一个常量字符数组(null终止),然后将该数组的内容复制到arr_of_chars,或直接将其分配给arr_of_chars

这里有什么机制?

4 个答案:

答案 0 :(得分:1)

C未指定您提出的问题。简而言之,C是根据抽象机及其可观察行为指定的。在这种情况下,这意味着您所知道的是从字符串文字初始化的数组变量arr_of_chars

在谈论细分,复制等时,您已经在谈论C的具体实现以及他们正在做什么。假设您的arr_of_chars位于文件范围并且给定了一个知道具有数据段的二进制文件的目标机器/系统,C编译器可以将初始化的数组直接放入数据段中 - 可观察的行为将是与运行时首先将字节复制到数组的方法没有什么不同。

答案 1 :(得分:0)

  

" ...在内存中的某处创建一个常量字符数组(null终止),然后将该数组的内容复制到arr_of_chars"

事实上。字符串文字"hello world"存储在程序的.rodata部分的某处,除非编译器设法完全优化它(取决于您的数组的范围)。从那里它被复制到您的数组中。

答案 2 :(得分:0)

这将在const段中创建一个以空字符结尾的字符串hello world\0

在main函数中,该字符串将被复制到字符数组中。

让我重点介绍一下装配输出中的几行,然后将其包含在内。

PUBLIC  ??_C@_0M@LACCCNMM@hello?5world?$AA@

这会创建一个公共令牌。

CONST   SEGMENT
??_C@_0M@LACCCNMM@hello?5world?$AA@ DB 'hello world', 00H
CONST   ENDS

这会将常量以null结尾的字符串分配给令牌。

lea rax, QWORD PTR arr_of_chars$[rbp]
lea rcx, OFFSET FLAT:??_C@_0M@LACCCNMM@hello?5world?$AA@
mov rdi, rax      ; Set destination to stack location
mov rsi, rcx      ; Set source to public token
mov ecx, 12       ; Set counter to number of times to repeat
rep movsb         ; Copy single byte from source to destination and increment locations

这将设置源和目标,并按字符12次复制字符,这是" hello world"和null终止符。目标是堆栈上的位置,源是公共令牌。

答案 3 :(得分:0)

它是c。

中存储字符串的主题

字符串可以通过以下方式存储,

  1. 字符串作为字符数组
  2. 使用字符指针的字符串
  3. 当字符串被声明为字符数组时,它们就像C中的其他类型的数组一样存储。例如,如果str []是一个自动变量,那么字符串存储在堆栈段中,如果它是全局变量或静态变量则存储在数据部分。

    实施例。

    char str[] = "Hello_world";
    

    如果使用字符指针存储字符串,可以通过两种方式完成,

    1. 只读共享段中的字符串。

      实施例

      char *str  =  "Hello_World";
      
    2. 在上面的行中,“Hello_World”存储在共享只读位置,但指针str存储在读写存储器中。您可以将str更改为指向其他内容,但不能在当前str中更改值。所以这种字符串只应在我们不想在程序的后期修改字符串时使用。

      1. 在堆段中动态分配。

        char *str = NULL;
        int size = 6;
        
        str = (char *) malloc(sizeof(char)*size);
        
        *(str+0) = 'H'; 
        *(str+1) = 'E';  
        *(str+2) = 'L';  
        *(str+3) = 'L';  
        *(str+4) = 'O';  
        *(str+5) = '\0';