简体   繁体   English

const char ** x和const char * x []如何相似?

[英]How is const char** x and const char* x[] similar?

I have a hard time understanding or finding a simple explanation of what const char** x is and how to use it? 我很难理解或找到const char** x的简单解释以及如何使用它?

I kind of understand that char* x[] is an array of char pointers. 我有点理解char* x[]是一个char指针数组。

One explanation for the char** x I found says that "they are variable pointers to an array of variable pointers to const chars ". 我发现char** x一个解释是“它们是指向const chars的变量指针数组的变量指针”。

I am confused. 我很困惑。 Is x an array of pointers or just one pointer that points to an array of pointers? x是一个指针数组还是只指向一个指针数组的指针?

If I wrote T *x , you'd understand that, I assume? 如果我写了T *x ,你会理解,我认为? x is simply a pointer to an object of type T . x只是指向T类型对象的指针。 And that object may be the first element in an array of T . 并且该对象可能T数组中的第一个元素。 Whereas T x[10] really is an array of 10 T . T x[10]确实是10 T的数组。

In your case, T is const char * . 在你的情况下, Tconst char * So x is a pointer to a const char * . 所以x是指向const char *的指针。

[] it mostly a shortcut for declaring arrays of thing, and not really a type. []它主要是用于声明事物数组的快捷方式,而不是真正的类型。 It is used when declaring the elements of the array, or specifying how many "slots" that array have. 它在声明数组元素或指定数组有多少“槽”时使用。

But C don't handle entire arrays as if it was one single thing, so the resultant variable you get from that operation is a char * pointer pointing to the first element of that array, so that char x[] and char *x is somewhat implied of being the same type. 但是C不会像处理整个数组一样处理整个数组,所以从该操作得到的结果变量是指向该数组的第一个元素的char *指针,因此char x[]char *x是有些暗示是同一类型。

When declaring char x[] = "string"; 声明char x[] = "string"; , for instance, x is a variable of type char * that points to the first element of the array, x[0] which value is 's' . 例如, xchar *类型的变量,指向数组的第一个元素x[0] ,其值为's'

You can reapply the concept to a matrix or an array of arrays, which is the same as a pointer to a collecion of pointers. 您可以将该概念重新应用于矩阵或数组数组,这与指向指针集合的指针相同。

So while char *x may be a string, char **x may be a list of strings. 因此,虽然char *x可以是字符串,但char **x可以是字符串列表。

for every type you use * it is a pointer to that type. 对于您使用的每种类型*它是指向该类型的指针。 it might point to one element or to the first element (at the first time you assign it) of a sequence of elements on the memory. 它可能指向一个元素或指向内存中元素序列的第一个元素(在第一次分配它时)。 with a pointer you can use pointer arithmetik for example x++ to navigate to the next element, you can also use the index operator x[1] on it. 使用指针你可以使用指针arithmetik例如x++导航到下一个元素,你也可以使用索引运算符x[1] pointer arithmetik cannot be applied to a const pointer, witch is obvious since you declared it to be constant. 指针arithmetik不能应用于const指针,因为你声明它是常量,所以很明显。

for every type you use [] it is an array. 对于你使用的每种类型[]它都是一个数组。 with an array you cannot use pointer arithmetik, only the the [] operator lets you access the elements of an array. 使用数组你不能使用指针arithmetik,只有[]运算符允许你访问数组的元素。

you can say that a const pointer is similar the an array when it comes to accessing element. 你可以说const指针在访问元素时类似于数组。

Use array when you know at compile time what size it should have. 在编译时知道应该具有的大小时使用数组。 these will reside on the stack. 这些将驻留在堆栈上。

Use pointers when you have to allocate memory at runtime or you wich to use pointer arithmetik. 必须在运行时分配内存或使用指针arithmetik时使用指针。 memory allocated at runtime resides on the heap. 在运行时分配的内存驻留在堆上。

here a lecture that might help you understand better. 这里的讲座可以帮助你更好地理解。

I hope i didn't tell any mistakes, it's been a while since i used C the last time :/ 我希望我没有说出任何错误,因为我最后一次使用C已经有一段时间了:/

Here's one example: 这是一个例子:

char ch;
char *pch = &ch;
char **ppch = &pch;

In this case, no array is involved. 在这种情况下,不涉及任何数组。

There is one variable that holds a character ( ch ). 有一个变量包含一个字符( ch )。

Then there is one variable that holds a pointer ( pch ). 然后有一个变量,它包含一个指针( pch )。 This is simply an address of a location in memory that holds data. 这只是存储器中保存数据的位置的地址。 But the compiler and the programmer are also interested in the type of the value that is stored in that location (for example, to know how many bytes it takes, or which operations are allowed on that value). 但是编译器和程序员也对存储在该位置的值的类型感兴趣(例如,知道它需要多少字节,或者该值允许哪些操作)。 So the pointer has a type that is related to the type of the value it's pointing to. 因此指针的类型与它指向的值的类型相关。 In this case, pch is pointing to a character value, so the type is char * . 在这种情况下, pch指向一个字符值,因此类型为char *

And then there's another variable that holds a pointer ( ppch ). 然后是另一个包含指针的变量( ppch )。 Again it's just an address of a location in memory, but this time the value that is stored in that location is a pointer. 同样,它只是内存中某个位置的地址,但这次存储在该位置的值是一个指针。 So there are two pointers involved, ppch and the pointer it's pointing to. 所以有两个指针, ppch和它指向的指针。 Both pointers have a type. 两个指针都有一个类型。 ppch is a char ** - pointer to a pointer to char. ppch是一个char ** - 指向char的指针。 The value it's pointing to is a char * - pointer to a character. 它指向的值是char * - 指向字符的指针。

A pointer can point to a single value, but in some cases it's also useful if there is a sequence of values with the same type (an array). 指针可以指向单个值,但在某些情况下,如果存在具有相同类型(数组)的值序列,它也很有用。 In that case, the pointer can point to any of the values in the sequence, and using pointer arithmetic it can be changed to point to other values in the same sequence. 在这种情况下,指针可以指向序列中的任何值,并且使用指针算法可以将其更改为指向同一序列中的其他值。

So just like char * is a pointer that can point to a character, it can also point to any value in a sequence of a characters, and in many cases it's useful if it points to the first value in the sequence. 因此,就像char *是一个可以指向一个字符的指针一样,它也可以指向一个字符序列中的任何值,并且在许多情况下,如果它指向序列中的第一个值,它就很有用。

char ** points to a char * value, which again can be a single value or one of many in a sequence of values (and more specifically, the first in the sequence). char **指向char *值,该值也可以是单个值或值序列中的许多值之一(更具体地,序列中的第一个)。

This is NOT the same as char *array[] which is the actual sequence of pointers. 这与char *array[] ,后者是实际的指针序列。 The difference is important: 差异很重要:

char *pointers[5];
char **pp;

Here, char *pointers[5] is an array of 5 pointers. 这里, char *pointers[5]是一个包含5个指针的数组。 It's the actual sequence. 这是实际的顺序。 sizeof(pointers) is 5 times the size of a single pointer. sizeof(pointers)是单个指针大小的5倍。

But pp is just a pointer - it's a variable that holds a single pointer, and sizeof(pp) is the size of a single pointer. pp只是一个指针 - 它是一个包含单个指针的变量,而sizeof(pp)是一个指针的大小。 As it's a pointer to pointer, it can also point to the first element of pointers (or to any other char * value, including other elements of pointers ). 因为它是指向指针的指针,它也可以指向pointers的第一个元素(或指向任何其他char *值,包括pointers其他元素)。

Now there's only the question of const . 现在只有const的问题。 This only affects the type that it appears with (this is a bit confusing, because C allows different orders, and const char is the same as char const ). 这只会影响它出现的类型(这有点令人困惑,因为C允许不同的顺序,而const charchar const相同)。 So const char **pp is a non-const pointer (meaning the pointer can change) to a non-const pointer (so that pointer can also change) to a const char (meaning that the value of the character cannot be modified by pp ). 所以const char **pp是一个非const指针(意思是指针可以改变)到一个非const指针(这样指针也可以改变)到一个const char(意味着该字符的值不能被pp修改) )。

So pp itself can be changed by the program - it can point to different pointers. 所以pp本身可以被程序改变 - 它可以指向不同的指针。 The pointer that it's pointing to can also change - it can point to different characters. 它指向的指针也可以改变 - 它可以指向不同的字符。 But the characters themselves cannot be changed using pp . 但是使用pp无法改变角色本身。

For a reasonable example, we need a few const char pointers, and a few characters to point to. 对于一个合理的例子,我们需要一些const char指针,并指向几个字符。 The easiest way to get those is to use arrays: 最简单的方法是使用数组:

char seq1[5] = { 'a', 'b', 'c', 'd', 'e' };
char seq2[3] = { 'x', 'y', 'z' };
const char *p1;
const char *p2;
const char **pp;

p1 = &seq1[0]; /* valid, same as p1 = seq1 */
p1 = &seq1[3]; /* valid */
*p1 = 's';  /* invalid - the character that p1 points to cannot be changed by p1 */
p2 = seq2;  /* valid */
pp = &p1;  /* valid */
*pp = &seq1[2];  /* valid - pp is a non-const pointer, so the value it points to can change */
pp = &p2;  /* valid - pp itself is non-const */
**pp = 't';  /* invalid - same as *(*pp) which is *p2 which is const when accessed by pp */

Note that the meaning of const is not that the value cannot ever change, but that it cannot be changed by the const variable (or the const pointer). 请注意, const的含义不是值不能改变,而是const变量(或const指针)不能改变它。 The following example should clarify: 以下示例应阐明:

char ch;
char *pch = &ch;
const char *cpch = &ch;

ch = 'a';  /* fine - ch is not const */
*pch = 'b';  /* fine - pch does not point to a const value */
*cpch = 'c';  /* invalid - cpch points to a const value */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM