C *是否根据其使用的上下文有不同的含义?
我是C新手,对*的两种不同用法感到困惑。我知道*的用法称为解引用,用于检索指针指向的值C *是否根据其使用的上下文有不同的含义?,c,C,我是C新手,对*的两种不同用法感到困惑。我知道*的用法称为解引用,用于检索指针指向的值 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 我的想法是,*就像一个操作符,当它应用于指针时,在print语句的上下文中给出值
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
我的想法是,*就像一个操作符,当它应用于指针时,在print语句的上下文中给出值
在其他地方,我看到*以以下方式使用:
void someFunction(int **IP){
int *anotherIP = NULL;
*IP = anotherIP;
}
如果我在这里使用相同的思想,*IP应该是IP指向的值。但这似乎不是用法。相反,它将本地指针分配给IP指向的指针
更正:函数正在为指向IP的指针分配另一个IP(即*IP
);IP(指向指针的指针)在传递到函数中时被取消引用两次(**IP
)
我的问题是:*的含义是否取决于上下文?如果是,我在常用情况下应该注意哪些上下文?如果没有,我如何理解上面的例子
此外,在上述函数中使用双星号的基本原理是什么?我经常在函数中看到这种用法
谢谢 首先,在C语言中,变量的声明应该与它的访问类似。 表示指向int的指针的实际值,它是int值,因此您可以使用
int-value=**IP
访问它
您经常在函数中看到双指针,因为它允许您为返回的值分配空间
一个指针将通过值传递给funktion,如果在函数中更改它,调用者将看不到更改 据我所知,星号在C语言中有三种“用法” 这里有乘法:
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 */
您看到的双星号是。仔细阅读这些。它们非常有趣。在声明中,一元*
表示声明的对象具有指针类型:
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
在表达式中,一元*
运算符取消对指针的引用以访问指向的对象,如您的示例所示。同样,您可以有多个级别的间接寻址:
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声明语法是基于表达式类型构建的。假设您有一个指向名为p
的int
的指针,并且希望访问该整数值。你会写一个这样的表达
x = *p;
表达式*p
的类型是int
,因此声明写为
int *p;
int *p[N];
如果您有一个名为p
的指向int
的指针数组,并且希望访问第i
元素所指向的整数值,那么您可以编写
x = *p[i];
同样,表达式*p[i]
的类型是int
,因此声明写为
int *p;
int *p[N];
多个间接寻址显示在两个主要位置:
您希望函数写入指针类型的参数
请记住,C按值传递所有函数参数,因此如果希望函数写入参数,则必须传递指向该参数的指针:
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
本身的指针来更新它
请记住,如果左值表达式x
的类型为T
,则表达式&x
的类型为T*
。同样,将T
替换为指针类型P*
,您将看到表达式&x
具有类型P**
您想分配一个锯齿状数组
有时,您需要一个2D(或3D,或更高)的类似阵列的结构,但不希望行的大小相同。通常的做法如下:
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
}
}
T**arr=malloc(N*sizeof*arr);//分配一个数组以容纳N个T类型的对象*
如果(arr)
{
对于(大小i=0;i
arr
指向指向T
的指针序列中的第一个 是的,当它用于乘法时,它有两种含义。当用作类型的一部分时,它使该类型成为指向基类型的指针。当与值一起使用时,它将取消对指针的引用。@ThomasJager感谢您的回复。您提到的两个含义如何适用于函数中的*IP示例?我不知道它是如何定义类型或取消引用的。IP
是指向int
的指针。因此,*IP
是指向int
的指针,就像另一个IP
一样。而**IP
是*IP
指向的int
。因此,说“它是将一个本地指针分配给**IP指向的指针”是不正确的。我发现,通过将int**IP
这样的声明视为**IP
被声明为int
来调和这两种“含义”是有用的(也就是说,如果你两次遵从IP
,你会得到一个int
),这意味着*IP
指向t