假设我们有一个这样的字符指针:
static char *example[]={"doctor","who","hello"};
我对这种情况下发生的事情感到有些困惑。
指针是否
example
只是有自己的地址?我在数组中的每个字符串是否都有一个彼此不同的内存地址
*example
?指针是否
example
只是简单地引用每个地址并初始化每个地址中的内容,如字符串声明所示?
我只使用 C 几个月,所以我只是想抓住事物的基本要素,我听说指针是 C 最重要的方面。
变量是否
example
只是有它自己的地址?
是的,变量有自己的地址。
我在数组中的每个字符串是否都有一个彼此不同的内存地址
*example
?
是的,每个字符串都有自己的地址,彼此不同。它也不同于变量的地址example
。但是,表达式*example
与变量不同example
。见下。
指针示例是否只是简单地引用每个地址并初始化每个地址中的内容,如字符串声明所示?
变量example
引用字符串数组的意义在于(不是它的地址)的值是数组的地址。example
static char* example[]
声明example
为指向 的指针数组char
。该数组被初始化为三个字符串文字,因此example[0]
is "doctor"
、example[1]
is"who"
和example[2]
is "hello"
。
由于example
是一个数组,因此数组标识符example
将计算为数组第一个元素的地址。如果你尝试这样的事情:
printf ("%p %p %p\n", example, &example, &example[0]);
您会看到它们都具有相同的值。然而,所有这些在语义上都是不同的类型。
example
有类型array of pointers to char
&example
有类型pointer to array of pointers to char
&example[0]
有类型pointer to pointer to char
。
数组的每个元素都有自己的地址。尝试这个:
printf ("%p %p %p\n", &example[0], &example[1], &example[2]);
第一个将与数组的地址相同,但其他的将从该地址偏移系统上指针的大小(通常对于 32 位系统为 4 个字节,对于 64 位系统为 8 个字节)。
数组中的char
每个指针指向的是字符串文字example
的第一个。char
每个字符串文字都有自己的地址,可能位于只读内存段中。你也可以试试这个:
printf ("%p %p\n", &example[0], example[0]);
&example[0]
是指向 的指针数组中第一个指针的地址char
。
example[0]
是指针数组中的第一个指针。想想一个数组int
。该数组的每个元素都有一个地址和一个值,后者是一个int
. 由于example
是一个指针数组,每个元素example
都有一个地址和一个值,后者是一个指针。
&example[1]
您可以对等重复练习:
printf ("%p %p\n", &example[1], example[1]);
printf ("%p %p\n", &example[2], example[2]);
总结一下:
char
与其第一个元素具有相同的地址。char
)一个字符串,该字符串有自己的地址。希望这很清楚。
图片可能会有所帮助。以下内容并不代表任何特定的架构 - 所有地址值都是凭空提取的。
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
0x00004000 'd' 'o' 'c' 't'
0x00004004 'o' 'r' 0x00 'w'
0x00004008 'h' 'o' 0x00 'h'
0x0000400c 'e' 'l' 'l' 'o'
0x00004010 0x00 ?? ?? ??
... ... ...
example: 0x80001000 0x00 0x00 0x40 0x00
0x80001004 0x00 0x00 0x40 0x07
0x80001008 0x00 0x00 0x40 0x0b
字符串文字"doctor"
,"who"
和"hello"
都以这样的方式存储,即它们在程序的生命周期内分配(它们具有静态存储持续时间),并且它们可以存储在只读数据段1中。
字符串文字"doctor"
存储在 address 0x00004000
,"who"
存储在 address 0x00004007
,并"hello"
存储在 address 0x0000400b
。
该数组example
还通过static
关键字具有静态存储持续时间,但实际上可能存储在与字符串文字不同的内存区域中。数组从 address 开始0x80001000
,每个元素占用四个字节,so &example[0] == 0x80001000
、&example[1] == 0x80001004
和&example[2] == 0x80001008
。
example
请注意,指向数组第一个元素的名为变量的变量没有单独的存储位置。在 C 中,第一个元素的地址与数组本身的地址相同。 这很重要,也是 C 语言中最常被误解的方面之一。数组不是指针;相反,在大多数情况下,数组表达式将被转换(“衰减”)为指针表达式2,并且表达式的值将是第一个元素的地址。如果您真的感兴趣, Dennis Ritchie的这篇论文概述了这种行为的原因;向下滚动到“胚胎 C”部分以获得解释。
存储的值example[0]
是字符串字面量的地址"doctor"
。类似地,example[1]
存储字符串字面量的地址"who"
,并example[3]
存储字符串字面量的地址"hello"
。
2. 此规则的例外情况是数组表达式是一元运算符sizeof
或一元运算符的操作数&
,或者是用于在声明中初始化另一个数组的字符串文字。
如果你声明
char *example[] = {"doctor","who","hello"};
你得到一个大小为 3 的数组,每个数组包含一个 char* 指针。它与
char *example[3] = {"doctor","who","hello"};
但是,我们真的需要看看如何在您的代码中声明示例才能回答。