4

我很难理解指针,尤其是函数指针,我希望有人能给我一个关于它们到底是什么以及如何在程序中使用它们的概要。C++ 中的代码块将特别受到赞赏。

谢谢你。

4

6 回答 6

10

理解间接的概念很重要。

在这里,我们通过值传递(请注意,创建和操作的是本地副本,而不是原始版本)通过increment(x)

按值传递

在这里,通过指针(内存地址)increment(&x)

通过指针

请注意,引用的工作方式类似于指针,除了语法类似于值副本 ( obj.member) 并且指针可以指向0(“空”指针),而引用必须指向非零内存地址。

另一方面,函数指针让您可以在运行时动态地更改代码的行为,方法是方便地传递和处理函数,就像传递变量一样。子通常是首选(尤其是STL),因为它们的语法更简洁,并且它们允许您将本地状态与函数实例相关联(阅读回调闭包,两者都是有用的计算机科学概念)。对于简单的函数指针/回调,由于其紧凑和就地语法,经常使用lambdas ( C++11中的新功能)。

于 2012-08-10T05:43:54.740 回答
3

指针指向该点,是一个整数值,具有该点的地址。指针可以指向其他指针。然后你可以以更间接的方式获得值。

引用运算符 (&): 您可以将指针等同于变量或指针的引用。

解引用运算符(*): 您可以获取指针所指向的单元格的值。

当通过非引用传递给函数时,数组会衰减为指针。

函数指针没有内联,使程序更具功能性。回调就是一个例子。


在此处输入图像描述


在此处输入图像描述


在此处输入图像描述


在此处输入图像描述


在此处输入图像描述

于 2012-08-10T05:24:49.223 回答
2

打个比方,把计算机中的内存想象成一张 Excel 表格。在 C/C++ 程序中为变量赋值的等价物是在 Excel 工作表上的单元格中写入一些内容。从变量中读取就像查看单元格的内容一样。

现在,如果您有一个内容为“B8”的单元格(例如 C3),您可以将该内容解释为对另一个单元格的引用。如果你以这种方式处理单元格 C3,C3 就会变成一个指针。(在 Excel 中,您实际上可以通过输入=B8C3 来实现此行为)。

在这种情况下,您基本上声明您感兴趣的值的单元格在 C3 中被引用。在 C++ 中,这可能类似于:

int  B8 =  42;
int* C3 = &B8;

您现在有两个占用内存的变量。现在,如果您想知道 C3 指向什么,您将使用

int my_value = *C3;

至于函数指针:这些变量就像普通指针一样,但它们指向的地址(单元格)不仅仅是一个值,而是一个你可以调用的函数。

于 2012-08-10T05:45:57.907 回答
1

在这里您可以找到函数指针的一些示例用法: http ://www.cprogramming.com/tutorial/function-pointers.html

于 2012-08-10T05:39:36.213 回答
1

为了理解指针,需要对硬件和内存布局有所了解。

计算机内存可以看作是一个带抽屉的橱柜。当您“取消引用”您在抽屉内查看的指针时,指针可以指向任意抽屉,即存储在“抽屉”中的值:


e.g. ten numbers stored after one another

short a[] = {9,2,3,4,5,6,7,8,1,-1] ; 

in memory the values that consist the array 'a' are stored sequentially

   +---+---+---+---+---+---+---+---+---+---+
a->| 9 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1 | -1|
   +---+---+---+---+---+---+---+---+---+---+

the 'a' array above is a pointer and is the start address where the
values are stored in memory.

short* ptr = 0; // a pointer not pointing to anything (NULL)

ptr = a + 5; // the pointer is now pointing to the 6th value in the array
// the + 5 is an offset on the starting address of a and since the type of
// a is short int array the compiler calculates the correct byte offset based
// on that type. in the above example 5 is 5 short ints since ptr is of type 
// short*

*ptr has the value 6 i.e. we are looking at what the ptr is pointing to.

每个“抽屉”的大小取决于存储的数据类型在上面的示例中存储了 10 个短整数,每个短整数占用 2 个字节,因此整个数组占用 20 个字节的内存(sizeof(a))

于 2012-08-10T05:56:19.480 回答
0

变量存储值。指针也存储值。唯一的区别是它们是内存地址。它们仍然是数字。这里没有什么复杂的。您可以将所有指针存储在 int 或 long 变量中:

  int p = 43567854;
  char *p1 = (char *) p;

但是将它们存储在指针变量中的好处是您可以描述在指针指向的地址处保存的变量类型。

指针的复杂之处在于您必须使用它们的神秘语法。语法很隐秘,因此输入起来很短。像:

  &p = return address of variable
  *p = return the value of first member of array that is stored at the address

通过使用上面的两个规则,我们可以编写这个神秘的代码:

  &(*++t)

翻译成人类语言的时间很长:将 t 的值增加 1。这现在指向值指针指向的数组的第二个成员。然后获取第二个成员(*)的值,然后获取该值的地址。如果我们打印这个指针,它将打印除第一个字符之外的整个字符串。

你应该做一个“指针语法备忘单.txt”,你很好。并打开“指针测试”项目来测试你不清楚的一切。

指针在某种程度上类似于正则表达式。

于 2019-05-15T22:25:10.263 回答