我正在研究指针,当我看到char *p[10]
时,我被困住了。因为有些东西被误解了。有人可以一步一步地解释为什么我的逻辑是错误的,错误是什么,我认为错在哪里以及我应该如何思考。因为我想要准确学习。还有int *p[10];
呢? 此外,例如x是指向char的指针,但只是char而不是chars。但是怎么来char *x = "possible";
我认为上面的一个应该是正确的,但我已经看到char *name[] = { "no month","jan","feb" };
我真的很困惑。
答案 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;
ptr
是char
指针。在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函数,这些函数使您能够使用“类似字符串”的概念 - 但它们不是真正的字符串。当然,除非你想说它一个字符串只是一个字符跟在另一个字符之后 - 一个数组。