指向string和char catch 22的指针

时间:2015-08-31 12:52:05

标签: c++ c pointers

我正在研究指针,当我看到char *p[10]时,我被困住了。因为有些东西被误解了。有人可以一步一步地解释为什么我的逻辑是错误的,错误是什么,我认为错在哪里以及我应该如何思考。因为我想要准确学习。还有int *p[10];呢? 此外,例如x是指向char的指针,但只是char而不是chars。但是怎么来char *x = "possible";

enter image description here

我认为上面的一个应该是正确的,但我已经看到char *name[] = { "no month","jan","feb" };我真的很困惑。

enter image description here

4 个答案:

答案 0 :(得分:4)

您的char *p[10]图表显示了一个数组,其中每个元素都指向一个字符 你可以像这样构建它:

char f = 'f';
char i = 'i';
char l1 = 'l';
char l2 = 'l';
char a1 = 'a';
char r1 = 'r';
char r2 = 'r';
char a2 = 'a';
char y = 'y';
char nul = '\0';
char *p[10] = { &f, &i, &l1, &l2, &a1, &r1, &r2, &a2, &y, &nul };

这与数组

非常不同
char p[10] = {'f', 'i', 'l', 'l', 'a', 'r', 'r', 'a', 'y', '\0'};

char p[10] = "fillarray";

是字符数组,而不是指针。

指针同样可以指向数组的第一个元素,正如您可能在

这样的结构中看到的那样。
const char *p = "fillarray";

其中p包含由文字定义的数组的第一个元素的地址。

这是有效的,因为数组可以衰减到指向其第一个元素的指针。

如果你创建一个指针数组,就会发生同样的事情:

/* Each element is a pointer to the first element of the corresponding string in the initialiser. */
const char *name[] = { "no month","jan","feb" };

您可以使用

获得相同的结果
const char* name[3];
name[0] = "no month";
name[1] = "jan";
name[2] = "feb";

答案 1 :(得分:2)

char c = 'a';

此处,c是一个字符,通常是ASCII编码数据的单字节。

char* ptr = &c;

ptrchar指针。在C中,它所做的只是指向一个内存位置,并不保证该位置的内容。您可以使用char*将char传递给函数,以允许函数允许函数对char进行更改(通过引用传递)。

常见的C 约定是指char*指向一个内存位置,其中多个字符按顺序存储,后跟空字符\0。此约定称为C字符串:

 char const* cstr = "hello";

cstr指向一个6字节长的内存块,以空字符结尾。虽然可以将指针更改为指向其他内容,但无法修改数据本身。

char的数组看起来相似,但行为略有不同。

 char arr[] = "hello";

这里arr是一个6 char s的内存块。由于arr表示内存本身,因此无法将其更改为指向其他位置。可以修改数据。

现在,

char const* name[] = { "Jan", " Feb"..., "Dec"};

是指向字符的指针数组。 name是一个内存块,每个内存块都包含一个指向以null结尾的字符串的指针。

在图表中,我认为string*被意外使用而不是char*。左侧和右侧之间的差异确实不是技术差异,而是使用char*的方式的差异。在左侧,每个char*指向一个字符,而在右侧,每个char*指向一个以空字符结尾的字符块。

答案 2 :(得分:1)

两者都是对的。

C或C ++中的指针可以指向单个项目(单个char),也可以指向项目数组中的第一个(char[])。
因此char *p[10];定义可能指向10个单个字符或10个数组(即10个字符串)。

答案 3 :(得分:1)

让我们回到基础。

首先,char * p只是一个指针。 p只包含一个内存地址。该内存地址可以指向任何地方,任何地方。按照惯例,我们总是使用NULL(或者,我讨厌这种方法,将它分配给零 - 是的,它们是相同的“东西”,但是传统上NULL一直与指针一起使用,所以当你的眼睛掠过代码,你看到NULL - 你认为“指针”)。

无论如何,指向的内存地址可以包含任何内容。因此,要在语言中使用,我们键入它,在这种情况下,它是一个指向字符(char * p)的指针。这可以通过类型转换来覆盖,但这是以后的时间。

其次,我们知道任何时候我们看到p [10],我们正在处理一个数组。同样,数组可以是一个字符数组,一个int数组等等 - 但它仍然是一个数组。

你的例子:char * p [10],只不过是一个包含10个字符指针的数组。没有更多,没有更少。你的问题是因为你试图将“字符串”概念强加于此。 C中没有字符串.C中没有对象。绝对可以使用以NULL结尾的字符串的概念。但是C中的“字符串”只不过是一个字符数组,以NULL结尾(或者,如果使用某些相应的函数,则可以使用特定数量的字符 - strncpy而不是strcpy等)。但是,对于它的所有外观和明显的用途,C中没有字符串。它们只不过是字符数组,有一些支持函数在遇到NULL时碰巧停止通过数组。

所以 - char a [10] - 只是一个长度为10个字符的字符数组。你可以填写你想要的任何字符。如果其中一个是NULL字符,则终止通常称为“C样式字符串”的内容。有些函数支持这种类型的字符数组(即“字符串”),但它仍然使用字符数组。

你的混乱是因为你试图混合C ++字符串对象,并将这个概念强加到C字符数组上。正如ugoren所说 - 你的例子都是正确的 - 因为你正在处理字符指针数组,而不是字符串。再一次,在该字符数组中的某处放置一个NULL很好地支持几个C函数,这些函数使您能够使用“类似字符串”的概念 - 但它们不是真正的字符串。当然,除非你想说它一个字符串只是一个字符跟在另一个字符之后 - 一个数组。