0

假设我们有一个这样的字符指针:

static char *example[]={"doctor","who","hello"};

我对这种情况下发生的事情感到有些困惑。

  1. 指针是否example只是有自己的地址?

  2. 我在数组中的每个字符串是否都有一个彼此不同的内存地址*example

  3. 指针是否example只是简单地引用每个地址并初始化每个地址中的内容,如字符串声明所示?

我只使用 C 几个月,所以我只是想抓住事物的基本要素,我听说指针是 C 最重要的方面。

4

4 回答 4

5

变量是否example只是有它自己的地址?

是的,变量有自己的地址。

我在数组中的每个字符串是否都有一个彼此不同的内存地址*example

是的,每个字符串都有自己的地址,彼此不同。它也不同于变量的地址example。但是,表达式*example与变量不同example。见下。

指针示例是否只是简单地引用每个地址并初始化每个地址中的内容,如字符串声明所示?

变量example引用字符串数组的意义在于(不是的地址)的值是数组的地址example

于 2013-09-02T21:17:47.213 回答
1

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]);

总结一下:

  1. 指向的指针数组 char与其第一个元素具有相同的地址。
  2. 每个后续元素,即数组中的每个后续指针,都有自己的地址。
  3. 这些指针中的每一个都指向(第一个char)一个字符串,该字符串有自己的地址。

希望这很清楚。

于 2013-09-02T22:35:58.533 回答
0

图片可能会有所帮助。以下内容并不代表任何特定的架构 - 所有地址值都是凭空提取的。


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"


1. 正因为如此,试图修改字符串文字内容的行为是未定义的——它可能会按预期工作,可能会崩溃,或者可能完全无法编译。编译器不需要以任何特定方式处理这种情况,因此不同编译器之间的行为会有所不同。您永远不应尝试修改字符串文字的内容。

2. 此规则的例外情况是数组表达式是一元运算符sizeof或一元运算符的操作数&,或者是用于在声明中初始化另一个数组的字符串文字。

于 2013-09-04T00:09:10.807 回答
0

如果你声明

char *example[] = {"doctor","who","hello"};

你得到一个大小为 3 的数组,每个数组包含一个 char* 指针。它与

char *example[3] = {"doctor","who","hello"};

但是,我们真的需要看看如何在您的代码中声明示例才能回答。

于 2013-09-02T21:19:13.080 回答