我刚刚想到,我不知道如何使用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
我错过了什么,这两种说法是唯一的方法吗?
答案 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};