*根据使用的上下文,其含义是否不同?

时间:2019-07-02 14:55:28

标签: c

我是C语言的新手,对*的两种不同用法感到困惑。我知道*的用法称为 dereferencing ,用于检索指针指向的值。

int num = 20;
int *ip;
ip = #

print("This is the pointer's address: %p\n", ip);     // bffd8b3c
print("This is the value of the pointer: %d\n", *ip); // 20

我想到的方式是*就像一个运算符,在将它应用于指针时,它在打印语句的上下文中给出值

在其他地方,我看到*以下列方式使用:

void someFunction(int **IP){

    int *anotherIP = NULL;
    *IP = anotherIP;

}

如果我在此处使用相同的思想,则* IP应该是IP指向的值。但这似乎不是用法。而是将本地指针分配给IP指向的指针。

更正:该函数正在将anotherIP分配给指向IP的指针(即*IP); IP(指向指针的指针)在传递给函数(**IP)时被两次取消引用。

我的问题是:*上下文的含义是否相关?如果是,通常应注意哪些上下文?如果没有,我如何理解上面的示例?

此外,在上面的函数中使用双星号的原理是什么?我看到它经常在函数中使用。

谢谢!

3 个答案:

答案 0 :(得分:1)

首先,在C语言中,变量的声明应类似于其访问权限。 表示指向int的指针的指针的实际值,即为int的值,因此您可以使用int value = **IP对其进行访问。

您经常在函数中看到双指针,因为它允许您为返回的值分配空间。

单个指针将按值传递给功能,如果在函数中对其进行更改,则调用者将看不到更改。

答案 1 :(得分:1)

声明中,一元*表示所声明的事物具有指针类型:

T *p;       // p has type "pointer to T"
T *p[N];    // p has type "array of pointer to T"
T (*p)[N];  // p has type "pointer to array of T"
T *p();     // p has type "function returning pointer to T"
T (*p)();   // p has type "pointer to function returning T"

下标[]和函数调用()的优先级高于一元*,因此,像*p[i]这样的表达式将被解析为*(p[i]);您正在取消引用p[i]的结果。如果p是指向某事物数组的指针,则必须编写(*p)[i]-您需要解除对p的引用,然后将下标插入结果。

您可以具有多个间接级别:

T **p;           // p has type "pointer to pointer to T"
T ***p;          // p has type "pointer to pointer to pointer to T"
T *(*p)[N];      // p has type "pointer to array of pointer to T"
T *(*(*p)())[N]; // p is a pointer to a function returning a pointer
                 // to an N-element array of pointer to T

表达式中,一元*运算符取消引用指针以访问所指向的对象,如您的示例。同样,您可以具有多个间接级别:

int x = 10;    
int *p = &x;    // p stores the address of x
int **pp = &p;  // pp stores the address of p

在这些声明之后,以下内容为真:

**pp == *p ==  x == 10 // all of these expressions have type int
 *pp ==  p == &x       // all of these expressions have type int *
  pp == &p             // all of these expressions have type int **
 &pp                   // this expression has type int ***

C声明语法是基于表达式的类型构建的。假设您有一个名为int的{​​{1}}指针,并且想访问该整数值。你会写一个像

这样的表达式
p

表达式 x = *p; 的类型为*p,因此声明表示为

int

如果您有一个名为int *p; 的指向int的指针数组,并且想访问第p个元素所指向的整数值,则可以编写

i

同样,表达式 x = *p[i]; 的类型为*p[i],因此声明写为

int

多个间接显示在两个主要位置:

您要一个函数写入指针类型的参数

请记住,C会按值传递所有函数参数,因此,如果要让函数写入参数,则必须传递指向该参数的指针:

int *p[N];

让我们将void foo( T *ptr ) { *ptr = new_value(); // writes a new value to the thing ptr points to } void bar( void ) { T value; foo ( &value ); // writes a new value to value } 替换为指针类型T

P *

如您所见,它的工作方式相同。我们要更新void foo( P **ptr ) { *ptr = new_value(); // writes a new value to the thing ptr points to } void bar( void ) { P *value; foo ( &value ); // writes a new value to value } 的内容,因此我们必须传递一个指向它的指针。是的,value已经具有一个指针类型,但是我们需要一个指向value self 的指针来进行更新。

请记住,如果左值表达式value的类型为x,则表达式T的类型为&x。同样,将T *替换为指针类型T,您将看到表达式P *的类型为&x

您要分配一个锯齿状的数组

有时您需要2D(或3D或更高版本)的类似数组的结构,但您不希望行的大小相同。这样做的通常方法如下:

P **

T **arr = malloc( N * sizeof *arr ); // allocate an array to hold N objects of type T * if ( arr ) { for ( size_t i = 0; i < N; i++ ) { arr[i] = malloc( M * sizeof *arr[i] ); // allocate an array to hold M objects of type T, where M can vary from row to row } } 指向arr的指针序列中的第一个。

答案 2 :(得分:0)

据我所知,C语言中的星号有3种“用法”。

有乘法:

int result = 3 * 3; /* result == 9 */

有定义:

int *pointer_to_result = &result; /* define a pointer to an int, and initialize it with the address of the result variable */

最后要取消引用:

int copy_of_result = *pointer_to_result /* copy_of_result == 9 */

看到的带有双星号的是a pointer to a pointer。阅读这些。他们很有趣。