字符串常量,数组和指针的不同形式
在 C 语言中,字符串 "hello"
存储在内存中是一个字符数组,它的内存布局通常如下:
1. 字符串常量区:
字符串常量(如 "hello"
)是存储在程序的数据段(通常称为 .data
或 .rodata
)中的。这个区域是只读的,用于存储程序中的常量数据,防止修改这些常量。
因此,字符串 "hello"
会在内存中作为字符数组 {'h', 'e', 'l', 'l', 'o', '\0'}
存储,其中 '\0'
是字符串的结束符,表示字符串的结束。
2. 字符数组和指针的区别:
-
char s1[] = "hello";
:
在这种情况下,编译器将"hello"
字符串复制到栈上为s1
分配一块内存,通常是类似{'h', 'e', 'l', 'l', 'o', '\0'}
的形式。这里,s1
是一个可以修改的字符数组,因此s1
在栈上有自己的副本,允许你修改它的内容。 -
char *s2 = "hello";
:
当你使用char *s2 = "hello";
时,s2
是一个指向常量字符串"hello"
的指针,s2
存储的是指向内存中的一个位置的地址,而该位置存储了字符串常量"hello"
。该字符串常量在只读数据段中。
3. 内存分配:
char s1[] = "hello";
会将字符串"hello"
存储到栈上的s1
数组中。char *s2 = "hello";
会将字符串"hello"
存储在只读数据段,并且s2
指向这个字符串常量的位置。
示例内存布局:
假设栈的起始位置为 0x1000
,并且字符串 "hello"
位于只读数据段的 0x2000
:
- 对于
char s1[] = "hello";
:- 栈空间
0x1000
位置存储:{'h', 'e', 'l', 'l', 'o', '\0'}
,即s1
数组的内容。
- 栈空间
- 对于
char *s2 = "hello";
:s2
存储在栈中,假设s2 = 0x2000
(指向字符串"hello"
在只读数据段的地址)。- 字符串
"hello"
存储在只读数据段的0x2000
位置:{'h', 'e', 'l', 'l', 'o', '\0'}
。
总结:
- 字符串
"hello"
在内存中是一个字符数组{'h', 'e', 'l', 'l', 'o', '\0'}
,并且存储在常量区域中(对于指针的情况)。 - 对于字符数组(如
s1[]
),会在栈中复制该字符串的内容,允许修改。 - 对于字符串常量(如
s2
),指针指向常量字符串区域,它们是不可修改的。