使用C或C ++中的多个地址运算符初始化指针指针

时间:2010-09-28 07:45:07

标签: c++ c

我刚刚想到,我不知道如何使用C ++中的一个语句初始化指向非指针值的指针:

int a = 1;
int** ppa = &&a; //Does not compile
int** ppa = &(&a); //Does not compile
int* pa = &a;   //Works but is a
int** ppa = &pa; //Two step solution

我错过了什么,这两种说法是唯一的方法吗?

9 个答案:

答案 0 :(得分:14)

你无法获得指向临时的指针。 &a会产生r值。允许没有实际地址。

答案 1 :(得分:13)

如果你想要一个指向指针的指针,你想要指向的指针必须位于内存中的某个位置,所以我认为不可能有“一步解决方案”,因为你需要一个可以指向的指针变量

(注意:这句话并不是指在一句话中尽可能经常使用“点”的语言试验: - ))

答案 2 :(得分:7)

其他许多人都是对的:指向指针的指针必须指向某个东西。但是,在C99中,您可以使用compound literals

作弊
int a = 1;
int **ppa = &(int *){ &a };

复合文字只是基本上未命名的对象,并且具有与普通对象相同的存储规则。 (但是您不能使用static关键字给函数范围复合文字静态存储持续时间。您甚至可以嵌套它们,以便您可以将前一个示例重写为一行:

int **ppa =  &(int *) { &(int) { 1 } };

答案 3 :(得分:5)

C ++ 03 [Section 5.3.1]说

  

一元&运算符的结果是指向其操作数的指针。操作数应为左值或qualified-id。在第一种情况下,如果表达式的类型是“T”,则结果的类型是“指向T的指针。”

&&a中,&运算符无法应用于&a的结果,因为结果不是lvalue

另请阅读this帖子

答案 4 :(得分:2)

你想要一个指针(称之为PP)指针(称之为P)?

然后P必须存在。这意味着你必须声明它。

当然编译器会在&&a失败 - 因为你不能获取地址的地址。你可以获取指针的地址 - 但你必须先声明指针。

因此:

int a = 1;
int *P = &a;
int **PP = &P;

答案 5 :(得分:2)

地址是一个数字。如果它保存在变量即指针中,它只有一个自己的地址。所以

int *i1 = &a;

有道理,但

int **i2 = &&a;

毫无意义。然而

int **i2 = &i1;

确实有意义。有意义吗?

答案 6 :(得分:0)

执行以下操作时:

char a;
char* b = &a;
char** c = &b;

首先,现在存在于堆栈中。它显然有一个内存地址(即它的堆栈位置),这是你分配给b的内容。 b现在也存在于堆栈中,然后您可以将其内存地址传递给c。但是,如果没有中间堆栈,则不能获取值的地址地址,因为如果没有先显式创建它,它就不存在。

答案 7 :(得分:0)

当您执行&&a;之类的操作时遇到的问题是,您要求提供“a地址”。

这没有意义。我们可以得到a的地址就好了,但这并没有给我们一个变量,我们可以取地址。它只是给我们一个指针值。直到该值存储在某个地方,我们才能接受它的地址。

如果您有2+2等代码,则结果也没有地址。它只是值4,但它尚未存储在任何地方,因此我们无法获取地址。将它存储到int变量后,我们就可以获取该变量的地址。

基本上,问题是值和变量之间的差异。值只是一个数字(或一个字符,或一些其他数据)。变量是存储器中存储值的位置。变量有一个地址,但值没有。

在C ++中 - 说,它是rvalues和lvalues之间的区别。右值本质上是一个临时值,它通常是从另一个操作(例如您的&运算符)返回的值,但尚未存储在任何位置。

将它存储到变量中后,您会得到一个左值,并且左值有一个您可以使用的地址。

所以是的,你需要两个单独的陈述。首先,您获取地址,然后将该地址存储在某处。然后你可以把这个“某个地方”的地址。

答案 8 :(得分:-1)

这可能有效:

int ** ppa =&(int *){& a};