9

我对以下代码行感到困惑:

char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };

我理解的方式是,首先存储每个单词,然后数组的每个位置words将指向每个单词的第一个字符。这些字符串是如何存储的?这里是否正在进行动态分配,或者这些单词是否存储在堆栈中?

如果它们存储在堆栈中,它们以哪种方式存储?例如,如果我打印words如下的一些内容:

#include <stdio.h>
int main () {
    char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };
    printf("\n\n(*words)[0] = %s", words[0]);
    printf("\n\n(*words)[0]+1 = %s", words[0]+1);
    return 0;
}

而不是打印aaaand bbbb,我得到的是aaaand aa。我真的不明白这是什么原因,因为在我看来,words[0]+1应该指向字符串bbbb而不是aaa. 这里发生了什么?

4

8 回答 8

15

这就像..

在此处输入图像描述

因为 words 是一个指针字符数组,所以单词的每个数组索引都将保存字符串文字的地址,即如果要打印字符串文字的基地址

 printf("%s",words[0])// index 0 will print aaa.
于 2012-09-01T04:29:00.857 回答
6

不同之处在于words[0]+1不一样words[0+1]

前者指向 中的第二个字符words[0],而后者指向第二个单词。

于 2012-08-31T22:05:38.817 回答
3

words[0] 指向“aaa”中的第一个“a”。

words[0]+1 将该指针移动一个字符,因此它指向第二个“a”。

words[1] 指向“bbbb”

words[1]+1 点 "bbb",例如 "bbbb" 中的第二个 'b'。

于 2012-08-31T22:05:15.323 回答
2

在我看来,words[0]+1 应该指向字符串 bbbb 而不是 aaa 的第二个字符

words[0],它本身就是一个 char 指针——你可以通过添加一个字符来获得“aaa”的第二个字符。你想要的是words + 1或者&words[0] + 1正确的是“bbbb”。

此外,字符串本身是在启动可执行文件时分配的,并且它们可能由链接器放入二进制文件的数据或 bss 部分。此外,当您声明和初始化时words,它将像任何其他自动数组一样在堆栈上分配,并且其项目将分配给指向每个字符串常量开头的指针。

于 2012-08-31T22:05:59.310 回答
1

文字字符串存储在静态内存中。它们的实际位置取决于实现,但文字字符串存储在某处,通常在可执行文件的数据部分中——这既不是动态分配也不是堆栈分配。然后,您的数组包含指向这些位置的指针。

words[0]+1 应该指向字符串 bbbb 而不是 aaa 的第二个字符。

这根本不是数组索引的工作方式。您使用 索引字符串数组words[0],现在您有了一个字符串,并且任何操作都适用于该字符串。您不能对下标之外的数组索引进行算术运算。要获取字符串"bbbb",您将使用words[1].

于 2012-08-31T22:05:32.453 回答
1

堆栈和堆空间都是动态分配的——也就是说,它们是在运行时分配的。您的编译代码是动态分配的,在堆上还是栈上?显然两者都没有。常量的存储类似于代码的存储......它们存储在磁盘上的可执行文件中并加载到只读内存中。(学徒注意:这是典型实现中的工作方式;语言标准没有强制要求。)

words[0]是“aaaa”的第一个“a”的地址。向该地址添加 1 肯定会产生“aaaa”的第二个“a”的地址。“bbbb”的地址在words[1].

在您的 printf 格式中,您有“(*words)[0]”,但这是不同的。*words是一样的words[0](*words)[0]与 相同**words,它是“aaaa”的第一个“a”(不是它的地址)。您将使用 打印(*words)[0]%c而不是%s

于 2012-08-31T22:29:41.250 回答
0

words[0] 返回 aaa 的地址。向其添加 1 会增加地址以指向第二个 a。

你的意思是有单词[0+1]?

那应该给你你所期望的。

于 2012-08-31T22:05:19.803 回答
0
char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };

所有 4 个字符串都有静态存储持续时间,并在程序启动之前分配。

在初始化器中,数组被转换为指向的指针,charwords使用指针值初始化数组。

于 2012-08-31T22:05:26.047 回答