C指针问题

时间:2009-07-10 14:25:04

标签: c pointers

对于:

int *a;

a是可以存储整数的地址。 &a是存储a的地址。 然后,&a存储在哪里? 而且,&(&a)存储在哪里? 而且,&(&(&a))存储在哪里? 地址存储何处停止?

14 个答案:

答案 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。也就是说,可分配的内容 - 例如上面的bc(&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是一个变量,其中可以存储某个整数的地址。 &aa的地址,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))