简体   繁体   English

C指针问题

[英]C pointers Question

For : 用于:

int *a;

a is an address where an integer can be stored. a是可以存储整数的地址。 &a is an address where a is stored. &a是存储&a的地址。 Then, where is &a stored? 然后,其中&a存储? And, where is &(&a) stored? 并且, &(&a)存储在哪里? And, where is &(&(&a)) stored? 并且, &(&(&a))存储在哪里? Where does this storing of addresses stop? 地址存储在哪里停止?

If you don't explicitly write &a it will not be stored anywhere. 如果您没有明确写入&a ,它将不会存储在任何地方。 If you do write then the address will be computed and stored either in an unnamed variable (temporary) or a named varible you write. 如果你写了,那么地址将被计算并存储在一个未命名的变量(临时)或你编写的命名变量中。

For example: 例如:

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

&a is a constant. &a是常数。

&(&a) is illegal. &(&a)是非法的。

a is not "an address where an integer can be stored". a不是“可以存储整数的地址”。 a is a variable large enough to hold the address of an integer. a是一个足以容纳整数地址的变量。 The only "integer" you can store directly in a is the address of an integer, viewed as an integer itself: 您可以直接存储在a的唯一“整数”是整数的地址,以整数形式查看:

int *a;
int b;

a = &b;

printf("a is now %x\n", (unsigned int) a);

It is correct that a itself has an address, which is &a , but that address is not stored somewhere explicit, at runtime. 这是正确的, a本身有一个地址,这是&a ,但该地址没有存储的地方明确的,在运行时。

At a stretch, you might be able to store something that looks like the integer 0: 在一段时间内,您可能能够存储看起来像整数0的东西:

a = 0;

But this is just a shorthand syntax for "the NULL pointer", ie a pointer value guaranteed to not be the address of any actual object. 但这只是“NULL指针”的简写语法,即指针值保证不是任何实际对象的地址。

&a is the address of a. &a是a的地址。 It is a value, result of operator & applied to a, and is not "stored", and has no address, so &(&a) is invalid. 它是一个值,运算符的结果和应用于a,并且没有“存储”,并且没有地址,因此&(&a)无效。 It's like 2+3. 这就像2 + 3。

int *a is a variable the size of a pointer, just like int b would an automatic int variable. int *a是一个指针大小的变量,就像int b一样,是一个自动int变量。

If this declaration is in a function, that variable is automatic and stored on the [ stack ]( http://en.wikipedia.org/wiki/Stack_(data_structure)#Hardware_stacks) at runtime (a simple stack decrement allocates memory for it). 如果此声明在函数中,则该变量是自动的,并在运行时存储在[ stack ]( http://en.wikipedia.org/wiki/Stack_ ( data_structure)#Hardware_stacks)上(简单的堆栈减量为其分配内存) )。

If the declaration is global, then 'a' is simply mapped in executable's .DATA area. 如果声明是全局的,那么'a'只是映射到可执行文件的.DATA区域。

Any more & signs appended can 'create storage', because of the temporary variables you're using to hold'em ;) : 附加的任何&符号可以'创建存储',因为你用来hold'em的临时变量;):

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 '&'

The last line complains about the fact that & requires the operand to be a lvalue . 最后一行抱怨&要求操作数是lvalue That is, something assignable - like b and c above. 也就是说,可分配的东西 - 比如上面的bc (&a) as is a result of an expression which is not stored anywhere, therefore is not a lvalue . (&a)因为表达式没有存储在任何地方,因此不是lvalue

You can keep going forever: 你可以永远继续前进:

int value = 742;
int *a = &value;
void *b = &a;
void *c = &b;
void *d = &c;

You wouldn't put it on a single line without assigning it to anything - in that case it would be invalid. 如果没有将它分配给任何东西,你不会把它放在一行上 - 在这种情况下它将是无效的。

At the crux of your problem seems to be a lack of understanding of the physical nature of memory and pointers. 在你的问题的关键似乎是缺乏对内存和指针的物理性质的理解。 Not how the code works. 不是代码如何工作。 As Im sure you know, physical memory is comprised of a large group of adjacent cells. 我相信你知道,物理内存由一大群相邻的单元组成。 The addresses of these cells are fixed and hard-coded by the computer itself, not by software apps or the programming language that you use. 这些单元的地址由计算机本身修复和硬编码,而不是由软件应用程序或您使用的编程语言编写。 When you refer to &a, you are referring to the physical block of memory that is currently holding your value you've stored within the computers ram. 当您引用&a时,您指的是当前保存您的值的内存物理块,您存储在计算机RAM中。 "a" is simply a name that you've given the computer so that it knows exactly what block of memory to find the value that you've stored. “a”只是您给计算机的一个名称,因此它确切地知道要查找您存储的值的内存块。 I think that pretty much covers memory address. 我认为这几乎涵盖了内存地址。
Lets go over pointers now. 让我们来看看指针。 A pointer is yet another memory address, that is referred to by the computer. 指针是另一个存储器地址,由计算机引用。 It has whatever name that you give it. 它有你给它的任何名字。 In this case it should be called something else besides the same name that you gave your first value. 在这种情况下,除了您提供第一个值的同名之外,还应该调用其他内容。 Lets call it "b". 我们称之为“b”。 Based on how you declared it. 根据你的声明方式。 b's memory location is only capable of holding one type of data....another memory location.... so when I say: b= &a I'm saying that the memory address of 'b'(which is designed only to hold memory addresses), is to hold the memory address of 'a'. b的内存位置只能保存一种数据....另一个内存位置....所以当我说:b =&a我说的是'b'的内存地址(它的设计只是为了保持内存地址),是保存'a'的内存地址。 Meanwhile on the other side of town, the memory address of 'a' has an integer stored in it. 同时在城镇的另一边,“a”的存储器地址中存储有整数。

I hope that this didnt get confusing, I tried not to get all techno-babble on you here. 我希望这不会让人感到困惑,我试着不要在这里得到所有的技术喋喋不休。 If youre still confused. 如果你仍然困惑。 Post again, Ill explain with code next time. 再次发布,下次我会用代码解释。

-UBcse -UBcse

In C, a variable x may act as a value (on the right hand side of =, where it is called an rvalue ), or it may act as a container for values (on the left hand side of =, where it is called an lvalue ). 在C中,变量x可以作为一个值(在=的右边,它被称为rvalue ),或者它可以作为值的容器 (在=的左侧,在其中被称为一个左值 You may take the address of x , because you can take the address of any lvalue—this gives you a pointer to the container. 您可以获取x的地址,因为您可以获取任何左值的地址 - 这将为您提供指向容器的指针。 But because a pointer is an rvalue, not a container, you can never take &(&x) . 但是因为指针是右值而不是容器,所以你永远不能使用&(&x) In fact for any lvalue l , &l is legal but &(&l) is never legal. 事实上,对于任何左值l&l是合法的,但&(&l)从不合法。

a is a variable of type "address of int"; a是“address of int”类型的变量; &a is the address of variable a; &a是变量a的地址; &(&a) would be the address of the address of variable a, which makes no sense &(&a)将是变量a的地址,这没有意义

Not quite. 不完全的。 a is a variable in which an address of some integer may be stored. a是可以存储某个整数的地址的变量。 &a is the address of a , ie the address of the variable a , which may contain an address of some integer. &a是的地址a ,即,变量的地址a ,其可以含有一些整数的地址。

Very Important: until and unless an address of something is assigned to a , it is an uninitialized pointer. 非常重要:除非将某个地址分配给a ,否则它是一个未初始化的指针。 Trying to use whatever it points to will lead to unpredictable results, and will likely crash your program. 试图使用它指出的任何内容都会导致不可预测的结果,并可能导致程序崩溃。

You can have a pointer to a pointer. 你可以有一个指针指针。

Ex: 例如:

void foo(int **blah)
{
 int *a = *blah;

 ...
}

A pointer does take up memory. 指针确实会占用内存。 It's just a small container that holds the address of something. 它只是一个容纳某些东西地址的小容器。 It just can't take up "no space" because everything in the computer is represented somehow by numbers. 它只是不能占用“没有空间”,因为计算机中的所有内容都以数字表示。 It's just that as far as C/C++ is concenred, int *a is simply a pointer to an object and takes up no space. 只是就C / C ++而言,int * a只是一个指向对象的指针并且不占用任何空间。 That is to keep you from having to manage any sort of memory... it keeps the machine seperated from the code. 这是为了让你不必管理任何类型的内存......它使机器与代码分开。

int *a; int * a; is a pointer to an int called 'a'. 是一个指向名为'a'的int的指针。 &a; &一个; is the derefrence of int *a. 是int * a的derefrence。 it's pointing to itself. 它指向自己。 this is what you would use to point to the variable that you wanted to pass around from function to function. 这是你用来指向你想要在函数之间传递的变量的东西。 derefrence is just a fancy word for "getting the address back" &(&(&a)) is not a valid expression as previously stated. derefrence只是“获得地址”的一个奇特的词,&(&(&a))不是如前所述的有效表达。 you may make a pointer to a pointer to a pointer. 你可以指向一个指向指针的指针。 That may be what your thinking of. 这可能是你的想法。 In such a case you would derefrence the last pointer in question and the computer should understand what you're talking about. 在这种情况下,您可以解决最后一个指针,计算机应该了解您在说什么。

To answer the "where is 'a' stored" question; 回答“在哪里''存储'的问题; on the stack. 在堆栈上。

please, if i'm incorrect on anything, let me know. 拜托,如果我不对,请告诉我。

&a is a number which is an rvalue: you can store it somewhere if you want to in a variable you will have declared or allocated, of type int*. &a是一个rvalue的数字:如果你想要一个你将声明或分配的变量,你可以将它存储在某个地方,类型为int *。

To wit: 以机智:

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) is not legal syntax. &(&a)不是合法的语法。 If you want a pointer to a pointer to an int: 如果你想要一个指向int的指针:

int b = 39;
int *bptr = &b;
int **ptr2bptr = &bptr;

You have to build up the levels of indirection. 你必须建立间接的水平。

With the above you can then do this if you want: 有了上述内容,您可以根据需要执行以下操作:

printf("%d\n", *aptr);
printf("%d\n", *aptr2);
printf("%d\n", *bptr);
printf("%d\n", **ptr_to_bptr);

Producing output of: 产量:

42
42
39
39
int* a;

This line simply declares a pointer to an integer. 该行只是声明一个指向整数的指针。 That pointer has a memory location, which you can get the address of using &a. 该指针有一个内存位置,您可以获取使用&a的地址。 & is an operator that returns the address of whatever it is run on. &是一个运算符 ,它返回运行它的地址。 But if you do not assign this value anywhere, there is no further &-ing possible. 但是如果你没有在任何地方分配这个值,就没有进一步的可能性。

As to your question as to where &a is stored, most likely in a register. 至于你关于何处和a存储的问题,很可能是在寄存器中。 If you do not use the value, it will be immediately discarded. 如果您不使用该值,它将立即被丢弃。 (And registers do not have memory addresses, which is why you cannot do &(&a)) (并且寄存器没有内存地址,这就是为什么你不能做&(&a))

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

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