0

我正在学习指针,但我不明白指针如何与 C 风格的字符串一起工作。为什么这两个是等价的?

char a[] = "Gme";
char* p = a; //Why am I allowed to assign "Gme" to a pointer (pointer is an address)

cout << p << " " << *(p+1); //Why does it print "gme" with "cout<<p" (I mean, I am printing an address)?

char a[] = "Gme";
char* p = &a[0];   // How is this the same as char* p = a;

cout << p << " " << *(p+1);

总的来说,我不明白指针如何与字符串一起工作。字符如何存储在内存中?如果我们将字符串视为字符数组,为什么我不能打印字符元素的地址?

提前致谢 :)

4

3 回答 3

5

这与它们是 C 风格的字符串没有任何关系。对于任何数组都是如此。例如,您可以这样做:

int arr[10];
int* p = arr;

您可以这样做的原因是因为有一种称为数组到指针转换的标准转换。这会将表示数组(如arr上面)的表达式转换为指向其第一个元素的指针。我们知道 的第一个元素arr是 an int,所以我们从这个转换中得到的指针是 an int*

char a[] = "Gme";
char* p = a;

在这个例子中,我们知道a是一个数组char。它有 4 个元素:字母Gme和终止空字符。当您使用 初始化pa,您正在执行数组到指针的转换以获取指向数组第一个元素的指针。第一个元素是字符G,所以p是指向该字符的指针。

std::cout(以及标准 I/O 库的其余部分)在您输出char*. 它不是简单地打印指针包含的地址,而是假定指针指向以空字符结尾的字符串中的第一个字符(通常它是正确的)。它使字符串的每个字母都在递增和取消引用您传递的指针。

于 2013-05-20T17:33:10.917 回答
3

总的来说,我不明白指针如何与字符串一起工作。字符如何存储在内存中?

这是一个已经回答的大话题。

char s[] 和 char *s 有什么区别?是一个很好的起点。


如果我们将字符串视为字符数组,为什么我不能打印字符元素的地址?

你可以。你只需要做一些额外的工作来向编译器阐明你想要什么。

运算符有一个重载,<<它接受一个 ostream 和一个char*将右操作数解释为以 NUL 结尾的字符串。

如果您只想cout << ...查看 的指针性p,而不是其字符串性,则将其强制转换为,以便在选择要使用的重载void*时,函数调用调度程序可用的唯一选项是将其视为指针的选项。operator<<

于 2013-05-20T17:29:49.263 回答
-1

C-String 是一个由元素组成的数组。char

数组是内存中的一系列值,不能存储在单个变量中(因为变量通常有 64 位的限制),因此变量指向数组中的第一个元素(例如,包含第一个元素的地址)。

因此 chara[] = "Gme"创建了一个由“G”、“m”和“e”组成的数组,将其存储在内存中,并a包含第一个元素的地址(在本例中为“G”)。

char* p = a;是有效的,因为a它是作为指针隐式创建的,所以您只需将数组第一个元素的地址重新分配给 p。

char* p = &a[0];是有效的,因为 a[0] 是 的第 0个元素的a。通过添加&,您将获取 的第 0 个元素的地址a。所以 p 现在指向数组的第一个元素,a所以现在 p 也可以被视为一个数组。

于 2013-05-20T17:36:44.723 回答