9

我刚开始学习C,所以请善待。从我到目前为止所读到的关于指针的内容中:

int * test1; //this is a pointer which is basically an address to the process 
             //memory and usually has the size of 2 bytes (not necessarily, I know)
float test2; //this is an actual value and usually has the size of 4 bytes,
             //being of float type
test2 = 3.0; //this assigns 3 to `test2`

现在,我不完全理解的是:

*test1 = 3; //does this assign 3 at the address 
            //specified by `pointerValue`?
test1 = 3;  //this says that the pointer is basically pointing 
            //at the 3rd byte in process memory, 
            //which is somehow useless, since anything could be there
&test1; //this I really don't get, 
        //is it the pointer to the pointer? 
        //Meaning, the address at which the pointer address is kept?
        //Is it of any use?

相似地:

*test2; //does this has any sense?
&test2; //is this the address at which the 'test2' value is found? 
        //If so, it's a pointer, which means that you can have pointers pointing 
        //both to the heap address space and stack address space. 
        //I ask because I've always been confused by people who speak about 
        //pointers only in the heap context.
4

3 回答 3

3

好问题。

你的第一个块是正确的。指针是保存某些数据地址的变量。该指针的类型告诉代码如何解释该指针所持有的地址的内容。

构造:

*test1 = 3

称为指针的延迟。这意味着,您可以访问指针指向的地址并像普通变量一样对其进行读写。笔记:

int *test;
/*
 *    test is a pointer to an int - (int *)
 *   *test behaves like an int - (int)
 *
 * So you can thing of (*test) as a pesudo-variable which has the type 'int' 
 */

以上只是我使用的助记器。

您很少为指针分配数值......也许如果您正在为具有一些“众所周知”内存地址的特定环境进行开发,但在您的水平上,我不会担心太多那。

使用

*test2

最终会导致错误。你会试图尊重不是指针的东西,所以你可能会遇到某种系统错误,因为谁知道它指向哪里。

&test1并且&test2确实是指向test1和的指针test2

指向指针的指针非常有用,搜索指向指针的指针将引导您找到一些比我更好的资源。

于 2012-12-12T22:44:26.320 回答
1

看起来你的第一部分是正确的。

*一个偶然的想法:关于该标志的放置位置有各种约定。我更喜欢我的变量名,就像int *test1其他人喜欢int* test1. 我不确定让它漂浮在中间有多普遍。

另一个偶然的想法:test2 = 3.0将浮点数 3 分配给test2. 使用 可以达到相同的目的test2=3,在这种情况下,3 会从整数隐式转换为浮点数。您选择的约定在清晰度方面可能更安全,但并非绝对必要。

非偶然事件

*test1=3确实将 3 分配给test.

test1=3是一条有意义的线,但我认为它毫无意义。我们不知道内存位置 3 是什么,是否可以安全地触摸它,或者即使我们被允许触摸它。

这就是为什么使用类似的东西很方便

int var=3;
int *pointy=&var;
*pointy=4;
//Now var==4.

该命令&var返回 的内存位置var并将其存储在其中,pointy以便我们以后可以使用*pointy.

但我也可以这样做:

int var[]={1,2,3};
int *pointy=&var;
int *offset=2;
*(pointy+offset)=4;
//Now var[2]==4.

这就是你可能合法地看到类似的东西test1=3:指针可以像数字一样被添加和减去,所以你可以像这样存储偏移量。

&test1是指向指针的指针,但这对我来说听起来有点令人困惑。它实际上test1是存储值的内存地址。并且test1恰好将另一个变量的地址作为其值存储。一旦您开始以这种方式考虑指针(内存中的地址,存储在那里的值),它们就会变得更容易使用......或者至少我是这么认为的。

我不知道*test2本身是否具有“意义”。原则上,它可能有一个用途,我们可以想象该*命令将把 的值test2放在内存中的某个位置,并将返回它找到的值。但是由于您定义test2为浮点数,因此很难预测我们最终会在内存中的哪个位置,设置test2=3不会将我们移动到任何东西的第三个位置(查看 IEEE754 规范以了解原因)。但如果编译器允许这样的事情,我会感到惊讶。

让我们看另一个简单的例子:

int var=3;
int pointy1=&var;
int pointy2=&pointy1;
*pointy1=4;  //Now var==4
**pointy2=5; //Now var==5

所以你看到你可以像这样将指针链接在一起,你想要多少就行。如果您有一个指针数组,其中填充了您从动态内存创建的许多结构的地址,并且这些结构包含指向动态分配的事物本身的指针,则可能会出现这种情况。当需要使用指向指针的指针时,您可能会知道。现在,不要太担心它们。

于 2012-12-12T23:09:42.437 回答
1

首先让我们添加一些混淆:“指针”这个词既可以指代具有指针类型的变量(或对象),也可以指代具有指针类型的表达式。在大多数情况下,当人们谈论“指针”时,他们指的是指针变量。

指针可以(必须)指向一个事物(标准术语中的“对象”)。它只能指向正确的事物;指向 int 的指针不应该指向浮点对象。指针也可以为 NULL;在那种情况下,没有什么可以指出的。

指针类型也是类型,指针对象也是对象。所以可以构造一个指向指针的指针:指向指针的指针只是存储指针对象的地址。

指针不能是什么:

  • 它不能指向一个值:p = &4;是不可能的。4 是一个文字值,它不存储在对象中,因此没有地址。
  • 表达式也是如此:p = &(1+4);不可能,因为表达式“1+4”没有位置。
  • 返回值p = &sin(pi);也是不可能的;返回值不是对象,因此没有地址。
  • 标记为“寄存器”(现在几乎不同)的变量不能有地址。
  • 您不能获取位域的地址,主要是因为它们可能小于字符(或具有更精细的粒度),因此不同的位掩码可能具有相同的地址。

上述骨架有一些“例外”(空指针、强制转换、指向数组对象之外的一个元素),但为清楚起见,这些应该被视为改进/修正,恕我直言。

于 2012-12-12T23:52:05.140 回答