它只是发生在我身上,我不知道如何初始化一个指针从非指针值的指针在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
我错过了什么,这两个陈述是唯一的方法吗?
它只是发生在我身上,我不知道如何初始化一个指针从非指针值的指针在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
我错过了什么,这两个陈述是唯一的方法吗?
如果你想有一个指针的指针,要指出必须某处内存所在的指针,所以我觉得不可能有一个“一步到位的解决方案”,因为你需要一个你可以指向的指针变量。
(注:这句话是不是意味着是一个语言试用使用一句话:-)“点”,尽可能多)当你做对以下
您无法获得临时指针。 &a
产生r值。它不允许有实际的地址。
这是100%正确的,但我接受了Philip的回答,因为它解释了为什么是这样的原因,而不是仅仅指出标准。 – 2010-09-30 05:31:52
你想要一个指针(称为PP
)到一个指针(称为P
)?
然后P
必须实际存在。这意味着你必须声明它。
当然,编译器会在&&a
上失败 - 因为你不能获取地址的地址。你可以取指针的地址 - 但你必须首先声明指针。
这样:
int a = 1;
int *P = &a;
int **PP = &P;
解析器在'&& a'上失败并不是因为你不能获取地址的地址,而是因为&&是一个在声明中此时无效的单个标记。 'int ** ppa = x &&a;'可能是一个适当类型的'x'和一个适当重载的'&&'(邪恶!)的有效初始化,但它不会是地址的地址。 – 2010-09-28 08:04:29
:
char a;
char* b = &a;
char** c = &b;
首先现在存在于堆栈上。它显然有一个内存地址(即它的堆栈位置),这是你分配给b的地址。 b现在也存在于栈中,然后你可以将它的内存地址传递给c。但是,您不能在没有中间堆栈的情况下获取值的地址,因为如果没有明确创建它,它就不存在。
其他很多都是正确的:你指向指针的指针必须指向某个东西。然而,在C99可以使用compound literals欺骗:
int a = 1;
int **ppa = &(int *){ &a };
复合文字只是基本未命名的对象,并具有相同的存储规则视为正常对象。 (但是你不能用static
关键字给函数作用域复合文字静态存储持续时间)。你甚至可以将其嵌套这样你就可以在前面的例子改写为单行:
int **ppa = &(int *) { &(int) { 1 } };
这很可能是未定义的行为,并可能在应用程序首次使用指针时崩溃。复合文字是一个临时文字,编译器可以重复使用这个空格,所以'* ppa'在第二行的执行过程中指向'&a',但可能指向其他任何东西。 – 2010-09-28 08:04:45
@David Rodriguez:不,你错了。复合文字将具有与'a'和'ppa'相同的存储持续时间:当在函数外面时是静态的,否则在关闭块的持续时间内是自动的。见C99 6.5.2.5(6)。 – schot 2010-09-28 08:09:33
你是完全正确的。我应该在跳进评论之前检查标准......如果您在任何时候修改了答案,评论和我将把-1变成+1,它现在不允许我改变它。无论如何,根据你想要用指针做什么,它和中间变量解决方案一样危险。 – 2010-09-28 08:22:32
C++ 03 [Section 5.3.1
]说
一元&操作的结果是一个指针,其操作数。操作数应该是左值或合格的ID。在第一种情况下,如果表达式的类型是“T”的结果的类型是“指针T.”
在&&a
,&
操作者不能被应用到的&a
因为结果的结果不是lvalue
。
又读this线程
的地址是一个数字。它只有一个地址,如果它保存在一个变量中,即一个指针。所以
int *i1 = &a;
是有道理的,但
int **i2 = &&a;
是没有意义的。然而,
int **i2 = &i1;
确实有意义。合理?
你的术语是错误的。运算符的地址*会产生一个指针,请参见[ISO03,5.3.1 expr.unary.op§2]。通常会调用指针*值*“地址”和指针*变量*“指针”,但严格来说,这是错误的。 – fredoverflow 2010-09-28 10:26:16
我使用的术语是常用的。标准意义上的指针的值是任何意义上的地址,而这在任何意义上都是一个数字。把我说的另一种方式,&不产生*变量,*因此它不会产生任何地址可以采取。 – EJP 2010-09-28 10:33:55
当您执行类似&&a;
这样的操作时,问题是您要求提供“地址a
”的地址。
这没有意义。我们可以得到a
的地址就好了,但是这并不能给我们一个我们可以接受的地址。它只是给了我们一个指针值。在该值存储在某个地方之前,我们不能接受它的地址。
如果您有诸如2+2
的代码,结果也没有地址。它只是价值4,但它还没有存储在任何地方,所以我们不能接受地址。一旦我们将它存储到一个int
变量中,我们就可以获取该变量的地址。
基本上,问题是值和变量之间的差异。值只是一个数字(或一个字符或其他数据)。变量是存储值的地方。一个变量有一个地址,但一个值没有。
在C++中 - 说,它是rvalues和左值之间的差异。一个右值本质上是一个临时值,它通常是从另一个操作返回的值(例如您的案例中的&
运算符),但它尚未存储在任何地方。
一旦你将它存储到一个变量,你会得到一个左值,左值有一个你可以采取的地址。
所以是的,你需要两个单独的陈述。首先你得到地址,然后你在某处存储该地址。然后你可以把这个“某处”的地址。
您的术语是错误的。运算符的地址*会产生一个指针,请参见[ISO03,5.3.1 expr.unary.op§2]。通常会调用指针*值*“地址”和指针*变量*“指针”,但严格来说,这是错误的。 – fredoverflow 2010-09-28 10:25:26
@Fred:够公平的。我怀疑我会因此而陷入困境。 ;)这会教我尝试重新定义C++语义:p – jalf 2010-09-28 10:28:28
修正了一下。希望我得到最具误导性的位。 – jalf 2010-09-28 10:30:12
为什么你认为在这种情况下你需要一个指针指针? – SingleNegationElimination 2010-09-28 07:55:25
[指针指向C指针的工作原理]可能的重复(http://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c) – 2010-09-28 07:56:56
@Jens Gustedt,this不是重复的。链接的问题总体上是关于指针的。这个问题是关于具体情况。 – 2010-09-28 08:05:49