对于:
int *a;
a
是可以存储整数的地址。
&a
是存储a的地址。
然后,&a
存储在哪里?
而且,&(&a)
存储在哪里?
而且,&(&(&a))
存储在哪里?
地址存储何处停止?
答案 0 :(得分:7)
如果您没有明确地写&a
,它将不会存储在任何地方。如果你写了,那么地址将被计算并存储在一个未命名的变量(临时)或你写的命名变量中。
例如:
functionCall( &a ); // address will be in a temporary variable used for passing the parameter
int** b = &a; // address will be stored in variable b
otherFunctionCall( &&a ); // illegal, since &a is an expression operator & can't be applied to it
答案 1 :(得分:4)
&a
是常数。
&(&a)
是非法的。
答案 2 :(得分:4)
a
不是“可以存储整数的地址”。 a
是一个足以容纳整数地址的变量。您可以直接存储在a
中的唯一“整数”是整数的地址,以整数形式查看:
int *a;
int b;
a = &b;
printf("a is now %x\n", (unsigned int) a);
a
本身有一个地址&a
是正确的,但该地址在运行时没有显式存储。
在一段时间内,您可能能够存储看起来像整数0的东西:
a = 0;
但这只是“NULL指针”的简写语法,即指针值保证不是任何实际对象的地址。
答案 3 :(得分:3)
& a是a的地址。这是运营商和运营商的价值观。应用于a,而不是“存储”,并且没有地址,因此&(& a)无效。这就像2 + 3。
答案 4 :(得分:2)
int *a
是指针大小的变量,就像int b
自动int变量一样。
如果此声明在函数中,则该变量是自动的,并在运行时将存储在[stack
](http://en.wikipedia.org/wiki/Stack_(data_structure)#Hardware_stacks) 上(简单的堆栈减量为其分配内存) )。
如果声明是全局的,那么'a'只是映射到可执行文件的.DATA
区域。
更多&附加的符号可以“创建存储”,因为你用来保存的临时变量;):
b = &a; //the address in the executable's .DATA or on the stack (if `a` auto)
c = &b; //the address of `b` on the stack, independent of `a` or `&a`
d = &c; //the address of `c` on the stack, independent of `a` or `&a`
z = &(&a); //error: invalid lvalue in unary '&'
最后一行抱怨&
要求操作数为lvalue
。也就是说,可分配的内容 - 例如上面的b
和c
。 (&a)
因为表达式没有存储在任何地方,因此不是lvalue
。
答案 5 :(得分:1)
你可以永远继续前进:
int value = 742;
int *a = &value;
void *b = &a;
void *c = &b;
void *d = &c;
如果没有将它分配给任何东西,你就不会把它放在一行上 - 在这种情况下它会无效。
答案 6 :(得分:1)
问题的症结似乎是缺乏对内存和指针的物理本质的理解。不是代码如何工作。我相信你知道,物理内存由一大群相邻的单元组成。这些单元的地址由计算机本身修复和硬编码,而不是由软件应用程序或您使用的编程语言编写。当您引用& a时,您指的是当前存储您的值的内存物理块,您存储在计算机RAM中。 “a”只是您给计算机的一个名称,因此它确切地知道要查找您存储的值的内存块。我认为这几乎涵盖了内存地址 让我们来看看指针。指针是另一个存储器地址,由计算机引用。它有你给它的任何名字。在这种情况下,除了您提供第一个值的同名之外,还应该调用其他内容。我们称之为“b”。根据你的声明方式。 b的内存位置只能容纳一种类型的数据....另一个内存位置....所以当我说:b =& a我说的是'b'的内存地址(这只是设计的)保持内存地址),是保存'a'的内存地址。同时在城镇的另一边,“a”的存储器地址中存储有整数。
我希望这并不会让人感到困惑,我试着不要在这里得到所有的技术喋喋不休。如果你仍然困惑。再次发布,下次我会用代码解释。
-UBcse
答案 7 :(得分:1)
在C中,变量x
可以作为一个值(在=的右侧,它被称为 rvalue ),或者它可以充当容器表示值(在=的左侧,称为左值)。您可以使用x
的地址,因为您可以获取任何左值的地址 - 这会为您提供指向容器的指针。但是因为指针是右值而不是容器,所以永远不能取&(&x)
。事实上,对于任何左值l
,&l
都是合法的,但&(&l)
从不合法。
答案 8 :(得分:0)
a是“address of int”类型的变量; & a是变量a的地址; &(& a)将是变量a的地址,这没有任何意义
答案 9 :(得分:0)
不完全。 a
是一个变量,其中可以存储某个整数的地址。 &a
是a
的地址,i。即变量a
的地址,可能包含某个整数的地址。
非常重要:除非将某个地址分配给a
,否则它是一个未初始化的指针。试图使用它指出的任何内容都会导致不可预测的结果,并可能导致程序崩溃。
答案 10 :(得分:0)
你可以有一个指向指针的指针。
例如:
void foo(int **blah)
{
int *a = *blah;
...
}
指针占用内存。它只是一个容纳某些东西地址的小容器。它只是不能占用“没有空间”,因为计算机中的所有内容都以数字表示。只是就C / C ++而言,int * a只是一个指向对象的指针并且不占用任何空间。这是为了让你不必管理任何类型的内存......它使机器与代码分开。
答案 11 :(得分:0)
int * a;是一个指向名为'a'的int的指针。 &安培;一个;是int * a的derefrence。它指向自己。这是你用来指向你想要在函数之间传递的变量的东西。 derefrence只是“让地址回归”的一个奇特的词 &(&(& a))不是如前所述的有效表达。你可以指向一个指向指针的指针。这可能是你的想法。在这种情况下,您可以解决最后一个指针,计算机应该了解您在说什么。
回答“在哪里''存储'的问题;在堆栈上。
如果我对任何事情都不正确,请告诉我。
答案 12 :(得分:0)
& a是一个rvalue的数字:如果你想在一个你已经声明或分配的变量中,你可以将它存储在某个地方,类型为int *。
即便:
int a = 42;
&a; /* this does not store the address of a because you've not assigned the value to a variable */
int **aptr = &a; /* aptr is on the stack */
int **aptr2 = (int*)malloc(sizeof(int*));
aptr2 = &a; /* aptr2 is in the heap */
&(& a)不是合法语法。 如果你想要一个指向int的指针:
int b = 39;
int *bptr = &b;
int **ptr2bptr = &bptr;
你必须建立间接的水平。
如果您愿意,可以执行以上操作:
printf("%d\n", *aptr);
printf("%d\n", *aptr2);
printf("%d\n", *bptr);
printf("%d\n", **ptr_to_bptr);
制作输出:
42
42
39
39
答案 13 :(得分:0)
int* a;
这一行只是声明一个指向整数的指针。该指针有一个内存位置,您可以获取使用& a的地址。 &安培;是一个运算符,它返回运行它的地址。但是如果你没有在任何地方分配这个值,就没有进一步的& -ing可能。
关于你在哪里存储& a的问题,很可能是在寄存器中。如果您不使用该值,它将立即被丢弃。 (并且寄存器没有内存地址,这就是为什么你不能做&(& a))