1
int main(int argc, char * argv[]) {
  int       a = 10;
  int *    sp = &a;
  int * * dp1 = &sp;
  int * * dp2 = &&a;           // NG
  int * * dp3 = &(&a);         // NG
  int * * dp4 = &((int *) &a); // NG
}
$ cc test.c
test.c: In function ‘main’:
test.c:6:17: error: lvalue required as unary ‘&’ operand
   int * * dp3 = &(&a);         // NG
                 ^
test.c:7:17: error: lvalue required as unary ‘&’ operand
   int * * dp4 = &((int *) &a); // NG
                 ^
test.c:5:3: error: label ‘a’ used but not defined
   int * * dp2 = &&a;           // NG
   ^
4

4 回答 4

8

为什么我不能使用&&a

因为&给你一个变量的地址,而&a不是一个变量。

C 11 草案规定了以下内容:

6.5.3.2 地址和间接运算符

约束

1 一元 & 运算符的操作数应为函数指示符、[] 或一元 * 运算符的结果,或指定不是位域且未使用寄存器存储类声明的对象的左值说明符。

[...]

语义

3 一元 & 运算符产生其操作数的地址。[...]

为了解决这个“限制”,可以使用这样的复合文字引入临时存储(至少假设 C99):

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

作为旁注,请参阅以下错误消息:

test.c:5:3: error: label ‘a’ used but not defined
   int * * dp2 = &&a;           // NG
   ^

gcc(可能还有其他人)定义了对 C 标准的扩展,&&如果操作符标识标签,则允许在单个操作符上使用操作符。(更多信息在这里:https ://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html )

例子:

void * pv = &&lbl;

goto *pv;

/* some dead code  */

lbl:;

/* living code again here */
于 2015-06-18T09:51:43.243 回答
5

因为您只能获取变量的地址,而不是值的地址(由 &a 给出),而且 && 是布尔 AND,正如 @UnWind 所说。

于 2015-06-18T09:51:33.870 回答
3

在每个语句中,这部分:&a被视为数字值(因为它获取变量的地址)。

因此,对于前两个错误:

错误:需要左值作为一元“&” 操作数

第一个&被视为按位与运算符,因此它希望在它之前有一个值。(即2 & 3)。

对于最后一个错误:

错误:标签“a”已使用但未定义

是由于这两个&&原因将其a视为标签(请参阅alk's answer)。

想要实现的事情(获取地址的地址)是不可能的,因为无法获取“常量值”的地址,因为&a已经是一个值,而只是变量的地址。

于 2015-06-18T09:57:59.203 回答
2

&var给你你的变量的地址,所以我不知道你期望&&var的是什么,地址的地址?如果我错了,请纠正我。

于 2015-06-18T09:50:46.217 回答