简体   繁体   English

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

[英]Initialize pointer to pointer using multiple address operators in C or C++

It just occurred to me That I don't know how to initialize a pointer to pointer from a non pointer value with one statement in 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

Am I missing something, is the two statement the one and only way to do it? 我错过了什么,是两个声明唯一的方法吗?

You can't get pointer to a temporary. 你不能获得指向临时的指针。 &a results in a r-value. &a得到r值。 It is allowed not to have an actual address. 允许没有实际地址。

if you want a pointer to a pointer, the pointer that you want to point to must be located somewhere in memory, so I think there cannot be a "one step solution" because you need a pointer variable that you can point to. 如果你想要一个指向指针的指针,你想要指向的指针必须位于内存中的某个位置,所以我认为不能有“一步解决方案”,因为你需要一个可以指向的指针变量。

(Note: This sentence is not meant to be a linguistic trial to use "point" as often as possible in one sentence :-)) (注意:这句话并不是指在一句话中尽可能经常使用“点”的语言试验:-))

The many other are right: Your pointer to a pointer has to point to something. 其他许多都是正确的:指向指针的指针必须指向某个东西。 However, in C99 you can cheat by using compound literals : 但是,在C99中,您可以使用复合文字作弊:

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

Compound literals are just basically unnamed objects and have the same storage rules as normal objects. 复合文字只是基本上未命名的对象,并且具有与普通对象相同的存储规则。 (But you can't give a function scope compound literal static storage duration with the static keyword). (但是你不能用static关键字给函数范围复合文字静态存储持续时间)。 You can even nest them so you can rewrite the previous example to a single line: 您甚至可以嵌套它们,以便您可以将前一个示例重写为一行:

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

C++03 [ Section 5.3.1 ] says C ++ 03 [ Section 5.3.1 ]说

The result of the unary &operator is a pointer to its operand. 一元&运算符的结果是指向其操作数的指针。 The operand shall be an lvalue or a qualified-id. 操作数应为左值或限定ID。 In the first case, if the type of the expression is “T,” the type of the result is “pointer to T.” 在第一种情况下,如果表达式的类型是“T”,则结果的类型是“指向T的指针”。

In &&a , & operator cannot be applied to the result of &a because the result is not an lvalue . &&a&运算符不能应用于&a的结果,因为结果不是lvalue

Also read this thread 也读这个帖子

You want a pointer (call it PP ) to a pointer (call it P )? 你想要一个指针(称之为PP )指针(称之为P )?

Then P must actually exist. 那么P必须存在。 Which means you must declare it. 这意味着你必须声明它。

Of course the compiler will fail at &&a - because you can't take the address of an address. 当然编译器会在&&a失败 - 因为你不能获取地址的地址。 You can take the address of a pointer - but you'll have to declare the pointer first. 可以获取指针的地址 - 但你必须先声明指针。

Thus: 从而:

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

An address is a number. 地址是一个数字。 It only has an address of its own if it is held in a variable, ie a pointer. 如果它保存在变量(即指针)中,它只有一个自己的地址。 So 所以

int *i1 = &a;

makes sense, but 有道理,但是

int **i2 = &&a;

makes no sense. 没有意义。 However 然而

int **i2 = &i1;

does make sense. 确实有意义。 Make sense? 合理?

When you do the following: 执行以下操作时:

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

First of all a now exists on the stack. 首先,现在存在于堆栈中。 It obviously has a memory address (ie its stack position) this is what you assign to b. 它显然有一个内存地址(即它的堆栈位置),这是你分配给b的内容。 b now also exists on the stack and you can then pass its memory address to c. b现在也存在于堆栈中,然后您可以将其内存地址传递给c。 You cannot however take the address of the address of a value without the intermediate stack as it does not exist without explicitly creating it first. 但是,如果没有中间堆栈,则不能获取值的地址地址,因为如果没有先显式创建它,它就不存在。

The problem when you do something like &&a; 当你做像&&a;这样的问题时&&a; is that you're asking for "the address of the address of a ". 是,你问“的地址的地址a ”。

That doesn't make sense. 这没有意义。 We can get the address of a just fine, but that doesn't give us a variable we can take the address of. 我们可以得到a正常的地址,但这并没有给我们一个变量,我们可以采取的地址。 It just gives us a pointer value. 它只是给我们一个指针值。 Until that value is stored somewhere, we can't take its addres. 直到该值存储在某个地方,我们才能接受它的地址。

If you have code such as 2+2 , the result doesn't have an address either. 如果您有2+2等代码,则结果也没有地址。 It is just the value 4, but it hasn't yet been stored anywhere, so we can't take an address. 它只是值4,但它尚未存储在任何地方,因此我们无法获取地址。 Once we store it into an int variable, we can take the address of that variable. 一旦我们将它存储到int变量中,我们就可以获取该变量的地址。

Basically, the problem is the difference between values and variables. 基本上,问题是值和变量之间的差异。 A value is just a number (or a character, or some other data). 值只是一个数字(或一个字符,或一些其他数据)。 A variable is a place in memory where a value is stored. 变量是存储器中存储值的位置。 A variable has an address, but a value doesn't. 变量具有地址,但值不具有。

In C++-speak, it is the difference between rvalues and lvalues. 在C ++中 - 说,它是rvalues和lvalues之间的区别。 An rvalue is essentially a temporary, it's typically a value that was returned from another operation (such as the & operator in your case), but which hasn't yet been stored anywhere. 右值本质上是一个临时值,它通常是从另一个操作(例如您的情况下的&运算符)返回的值,但尚未存储在任何位置。

Once you store it into a variable, you get a lvalue, and lvalues have an address you can take. 将它存储到变量中后,您将得到一个左值,并且左值有一个您可以使用的地址。

So yes, you need the two separate statements. 所以是的,你需要两个单独的陈述。 First you take the address, and then you store that address somewhere. 首先,您获取地址,然后将该地址存储在某处。 And then you can take the address of this "somewhere". 然后你可以把这个“某个地方”的地址。

This might work: 这可能有效:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM