字符数组是否是在C中表示String常量的另一种方式?

时间:2017-05-22 18:33:06

标签: c arrays string

char a[ ]= "HELLO";

我们可以说上面的HELLO是一个字符串常量。我对此有疑问,因为我们可以改变像a[0]='A'这样的字符串元素。那么,我们仍可以将"HELLO"声称为字符串常量,因为它最后包含NULL吗?

5 个答案:

答案 0 :(得分:4)

是的,"HELLO"仍然是一个字符串常量(更具体地说,它是一个字符串 literal )。

但是,数组a(其内容初始化为该常量的副本)不是。

答案 1 :(得分:2)

"HELLO"是一个字符串文字 - 它以char的数组存储,以便在程序的生命周期内可用。 可能存储在只读内存段中,具体取决于实现(在我的系统上)。尝试修改字符串文字的内容会导致未定义的行为。

a不是字符串文字 - 它是char的数组,其已初始化,其中包含字符串文字"HELLO"的内容。您可以根据需要更改a的内容(尽管您不能存储长度超过5个字符的字符串)。

这是一个简短的程序,用于显示字符串文字"HELLO"和数组a之间的关系(以及用于测量的指针):

#include <stdio.h>
#include "dumper.h"

int main( void )
{
  char a[] = "HELLO";
  char *p = "HELLO";

  char *names[] = { "\"HELLO\"", "a", "p" };
  void *addrs[] = { "HELLO", a, &p };
  size_t sizes[] = { sizeof "HELLO", sizeof a, sizeof p };

  dumper( names, addrs, sizes, 3, stdout );

  return 0;
}

dumper是我编写的一个实用程序,它显示每个对象的内存映射。编译和运行时,我们得到以下输出:

       Item         Address   00   01   02   03
       ----         -------   --   --   --   --
    "HELLO"        0x400b30   48   45   4c   4c    HELL
                   0x400b34   4f   00   22   48    O."H

          a  0x7fff89062330   48   45   4c   4c    HELL
             0x7fff89062334   4f   00   00   00    O...

          p  0x7fff89062328   30   0b   40   00    0.@.
             0x7fff8906232c   00   00   00   00    ....

字符串文字"HELLO"存储为从地址0x400b30开始的ASCII(或UTF8)字符序列。

数组a从地址0x7fff89062330开始存储 - 如您所见,它包含字符串"HELLO"副本

指针p从地址0x7fff89062328开始存储 - 它存储字符串文字"HELLO"地址(x86是little-endian,所以多从最低有效字节开始存储字节值 - 您需要从右到左,从下到上读取。

您注意到的一件事是"HELLO"与变量ap之间的地址差异。在我的系统上,"HELLO"存储在.rodata内存段中:

$ objdump -j .rodata -d strings2

strings2:     file format elf64-x86-64

Disassembly of section .rodata:

0000000000400b2c :
  400b2c:       01 00 02 00 48 45 4c 4c 4f 00 22 48 45 4c 4c 4f     ....HELLO."HELLO
  400b3c:       22 00 61 00 70 00 41 64 64 72 65 73 73 00 49 74     ".
  ...
从运行时堆栈分配

ap,它从高地址开始,向低地址“向下”增长。

答案 2 :(得分:1)

没有

常量是一个不会通过执行程序而改变(或不应该改变)的变量。只要你可以a[1] = 'd',它就不是常数。

要在c中定义常量字符串,您可以采用以下三种方式:

#define WHATEVER = "HELLO";
const char WHATEVER[] = "HELLO";
static const char WHATEVER[] = "HELLO";

其他定义不会创建一个常量字符串,而是一个可变的char数组,这是另一回事。

答案 3 :(得分:0)

我会说这是一个字符串,但不是字符串常量。字符串是以空字符结尾的字符数组。字符串常量必须是不可变的。当字符串出现在用双引号定义的代码中时(例如"hello"),它被认为是字符串文字。内存中的实际字符数组将是一个字符串。

答案 4 :(得分:0)

不,这不是C中的字符串常量。顺便说一下,C语言中的任何字符串都必须以'\ 0'结尾,例如:

// '\0' explicitly included as the last element
char str[] = "HELLO";  

// '\0' has to be the last element in this case
char str2[] = {'H', 'E', 'L', 'L', 'O', '\0'}; 

如果你想在你的C代码中添加一个字符串常量,这是一个例子:

const const_str[] = "HELLO";

常量字符串的另一个例子:

#define CONST_STR "HELLO"