C语言 在 C 中,带有两个星号 (**) 的变量声明是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4318881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In C, what does a variable declaration with two asterisks (**) mean?
提问by Scott Davies
I am working with C and I'm a bit rusty. I am aware that *has three uses:
我正在使用 C 并且我有点生疏。我知道它*有三个用途:
- Declaring a pointer.
- Dereferencing a pointer.
- Multiplication
- 声明一个指针。
- 取消引用指针。
- 乘法
However, what does it mean when there are two asterisks (**) before a variable declaration:
但是,**在变量声明前有两个星号 ( )是什么意思:
char **aPointer = ...
Thanks,
谢谢,
Scott
斯科特
采纳答案by Jacob Relkin
It declares a pointer to a charpointer.
它声明了一个指向指针的char指针。
The usage of such a pointer would be to do such things like:
这种指针的用法是做这样的事情:
void setCharPointerToX(char ** character) {
*character = "x"; //using the dereference operator (*) to get the value that character points to (in this case a char pointer
}
char *y;
setCharPointerToX(&y); //using the address-of (&) operator here
printf("%s", y); //x
Here's another example:
这是另一个例子:
char *original = "awesomeness";
char **pointer_to_original = &original;
(*pointer_to_original) = "is awesome";
printf("%s", original); //is awesome
Use of **with arrays:
**with 数组的使用:
char** array = malloc(sizeof(*array) * 2); //2 elements
(*array) = "Hey"; //equivalent to array[0]
*(array + 1) = "There"; //array[1]
printf("%s", array[1]); //outputs There
The []operator on arrays does essentially pointer arithmetic on the front pointer, so, the way array[1]would be evaluated is as follows:
[]数组上的运算符本质上是对前指针进行指针运算,因此,计算方式array[1]如下:
array[1] == *(array + 1);
This is one of the reasons why array indices start from 0, because:
这是数组索引从 开始的原因之一0,因为:
array[0] == *(array + 0) == *(array);
回答by JeffFerguson
C and C++ allows the use of pointers that point to pointers (say that five times fast). Take a look at the following code:
C 和 C++ 允许使用指向指针的指针(比方说快五倍)。看看下面的代码:
char a;
char *b;
char **c;
a = 'Z';
b = &a; // read as "address of a"
c = &b; // read as "address of b"
The variable aholds a character. The variable bpoints to a location in memory that contains a character. The variable cpoints to a location in memory that contains a pointer that points to a location in memory that contains a character.
变量a保存一个字符。该变量b指向内存中包含字符的位置。该变量c指向内存中的一个位置,该位置包含一个指针,该指针指向内存中包含一个字符的位置。
Suppose that the variable astores its data at address 1000 (BEWARE: example memory locations are totally made up). Suppose that the variable bstores its data at address 2000, and that the variable cstores its data at address 3000. Given all of this, we have the following memory layout:
假设变量a将其数据存储在地址 1000(注意:示例内存位置是完全组成的)。假设变量b将其数据存储在地址 2000,而变量c将其数据存储在地址 3000。鉴于所有这些,我们有以下内存布局:
MEMORY LOCATION 1000 (variable a): 'Z'
MEMORY LOCATION 2000 (variable b): 1000 <--- points to memory location 1000
MEMORY LOCATION 3000 (variable c): 2000 <--- points to memory location 2000
回答by Tom
It means that aPointerpoints to a char pointer.
这意味着aPointer指向一个字符指针。
So
所以
aPointer: pointer to char pointer
*aPointer :pointer to char
**aPointer: char
An example of its usage is creating a dynamic array of c strings
其用法的一个示例是创建 c 字符串的动态数组
char **aPointer = (char**) malloc(num_strings);
char **aPointer = (char**) malloc(num_strings);
aPointer gives you a char, which can be used to represent a zero-terminated string.
aPointer 为您提供一个 char,它可用于表示以零结尾的字符串。
*aPointer = (char*)malloc( string_len + 1); //aPointer[0]
*(aPointer + 1) = (char*)malloc( string_len + 1); //aPointer[1]
回答by John Bode
It declares aPointeras a pointer to a pointer to char.
它声明aPointer为指向 char 指针的指针。
Declarations in C are centered around the types of expressions; the common name for it is "declaration mimics use". As a simple example, suppose we have a pointer to int named pand we want to access the integer value it's currently pointing to. We would dereferencethe pointer with the unary *operator, like so:
C 语言中的声明以表达式类型为中心;它的通用名称是“声明模拟使用”。作为一个简单的例子,假设我们有一个指向 int 的指针,p并且我们想要访问它当前指向的整数值。我们将使用一元运算符取消引用指针*,如下所示:
x = *p;
The type of the expression*pis int, so the declaration of the pointer variable pis
表达式的类型*p是int,所以指针变量的声明p是
int *p;
In this case, aPointeris a pointer to a pointer to char; if we want to get to the character value it's currently pointing to, we would have to dereference it twice:
在这种情况下,aPointer是一个指向 char 的指针的指针;如果我们想获得它当前指向的字符值,我们必须取消引用它两次:
c = **aPointer;
So, going by the logic above, the declaration of the pointer variable aPointeris
所以,按照上面的逻辑,指针变量的声明aPointer是
char **aPointer;
because the type of the expression**aPointeris char.
因为表达式的类型**aPointer是char.
Why would you ever have a pointer to a pointer? It shows up in several contexts:
为什么你会有一个指向指针的指针?它出现在几种情况下:
- You want a function to modify a pointer value; one example is the
strtollibrary function, whose prototype (as of C99) is
The second argument is a pointer to a pointer to char; when you calllong strtol(const char * restrict str, char ** restrict ptr, int base);strtol, you pass the address of a pointer to char as the second argument, and after the call it will point to the first character in the string that wasn't converted. - Remember that in most contexts, an expression of type "N-element array of T" is implicitly converted to type "pointer to T", and its value is the address of the first element of the array. If "T" is "pointer to char", then an expression of type "N-element array of pointer to char" will be converted to "pointer to pointer to char". For example:
void foo(char **arr) { size_t i = 0; for (i = 0; arr[i] != NULL; i++) printf("%s\n", arr[i]); } void bar(void) { char *ptrs[N] = {"foo", "bar", "bletch", NULL}; foo(ptrs); // ptrs decays from char *[N] to char ** } - You want to dynamically allocate a multi-dimensional array:
#define ROWS ... #define COLS ... ... char **arr = malloc(sizeof *arr * ROWS); if (arr) { size_t i; for (i = 0; i < ROWS; i++) { arr[i] = malloc(sizeof *arr[i] * COLS); if (arr[i]) { size_t j; for (j = 0; j < COLS; j++) { arr[i][j] = ...; } } } }
- 你想要一个函数来修改一个指针值;一个例子是
strtol库函数,它的原型(从 C99 开始)是
第二个参数是一个指向 char 指针的指针;当您调用 时long strtol(const char * restrict str, char ** restrict ptr, int base);strtol,您将指向 char 的指针的地址作为第二个参数传递,并且在调用之后它将指向字符串中未转换的第一个字符。 - 请记住,在大多数上下文中,“T 的 N 元素数组”类型的表达式被隐式转换为“指向 T 的指针”类型,其值是数组第一个元素的地址。如果“T”是“指向 char 的指针”,那么类型为“指向 char 的指针的 N 元素数组”的表达式将被转换为“指向指向 char 的指针的指针”。例如:
void foo(char **arr) { size_t i = 0; for (i = 0; arr[i] != NULL; i++) printf("%s\n", arr[i]); } void bar(void) { char *ptrs[N] = {"foo", "bar", "bletch", NULL}; foo(ptrs); // ptrs decays from char *[N] to char ** } - 你想动态分配一个多维数组:
#define ROWS ... #define COLS ... ... char **arr = malloc(sizeof *arr * ROWS); if (arr) { size_t i; for (i = 0; i < ROWS; i++) { arr[i] = malloc(sizeof *arr[i] * COLS); if (arr[i]) { size_t j; for (j = 0; j < COLS; j++) { arr[i][j] = ...; } } } }
回答by NPE
This is a pointer to a pointer to char.
这是一个指向 的指针char。

