我正在使用 C,我有点生疏了。我知道它*
有三个用途:
- 声明一个指针。
- 取消引用指针。
- 乘法
**
但是,变量声明前有两个星号 ( ) 是什么意思:
char **aPointer = ...
谢谢,
斯科特
它声明了一个指向指针的char
指针。
这种指针的用法是做这样的事情:
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
这是另一个例子:
char *original = "awesomeness";
char **pointer_to_original = &original;
(*pointer_to_original) = "is awesome";
printf("%s", original); //is awesome
使用**
数组:
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
数组上的[]
运算符本质上是对前指针进行指针运算,因此,array[1]
评估方式如下:
array[1] == *(array + 1);
这是数组索引从 开始的原因之一0
,因为:
array[0] == *(array + 0) == *(array);
C 和 C++ 允许使用指向指针的指针(比如说快五倍)。看看下面的代码:
char a;
char *b;
char **c;
a = 'Z';
b = &a; // read as "address of a"
c = &b; // read as "address of b"
该变量a
包含一个字符。该变量b
指向内存中包含一个字符的位置。该变量c
指向内存中的一个位置,该位置包含一个指针,该指针指向内存中包含一个字符的位置。
假设变量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
它声明aPointer
为指向 char 指针的指针。
C 中的声明以表达式类型为中心;它的通用名称是“声明模仿使用”。举个简单的例子,假设我们有一个指向 int 的指针p
,我们想要访问它当前指向的整数值。我们将使用一元运算符取消引用指针*
,如下所示:
x = *p;
表达式 的类型*p
是int
,所以指针变量的声明p
是
int *p;
在这种情况下,aPointer
是一个指向 char 的指针;如果我们想获得它当前指向的字符值,我们必须取消引用它两次:
c = **aPointer;
所以,按照上面的逻辑,指针变量的声明aPointer
是
char **aPointer;
因为表达式 **aPointer
的类型是char
.
为什么你会有一个指向指针的指针?它出现在几种情况下:
strtol
库函数,它的原型(从 C99 开始)是
long strtol(const char * restrict str, char ** restrict ptr, int base);
第二个参数是一个指向 char 的指针;调用时strtol
,将指向 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] = ...;
}
}
}
}
这意味着aPointer
指向一个字符指针。
所以
aPointer: pointer to char pointer
*aPointer :pointer to char
**aPointer: char
其用法的一个示例是创建 c 字符串的动态数组
char **aPointer = (char**) malloc(num_strings);
aPointer 给你一个 char,它可以用来表示一个以零结尾的字符串。
*aPointer = (char*)malloc( string_len + 1); //aPointer[0]
*(aPointer + 1) = (char*)malloc( string_len + 1); //aPointer[1]
这是一个指向指针的指针char
。