【问题标题】:Intuitively explaining pointers and their significance?直观地解释指针及其意义?
【发布时间】:2012-08-07 09:46:54
【问题描述】:

我很难理解指针,尤其是函数指针,我希望有人能告诉我它们到底是什么以及它们应该如何在程序中使用。特别感谢 C++ 中的代码块。

谢谢。

【问题讨论】:

  • 你在用什么 C++ 书?
  • 在人们遇到的所有指针问题中,函数指针通常不是最难的。
  • 函数指针作为一个整体在 C++ 中大多已过时。它们已被函数对象、lambda 和通用例程所取代。几乎总有比传递函数指针更好的方法。
  • 绝对 C++。 Greg,人们在研究指针时通常会出现什么问题?
  • @BobJohn:有些人很容易理解,有些人需要付出更多的努力才能理解。我想这只是间接的概念与 C 和 C++ 中有时令人困惑的符号相结合。

标签: c++ c pointers function-pointers indirection


【解决方案1】:

了解indirection 的概念很重要。

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    取消引用运算符 (*): 你可能会得到指针指向的单元格的值。

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

    函数指针没有内联,使程序更实用。回调就是一个例子。






    【讨论】:

    • 我们可能需要一个单独的、艺术性的分数来进行问答。 :)
    • 任何系统。 16 位系统、8 位系统、32 位系统。
    【解决方案3】:

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

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

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

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

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

    int my_value = *C3;
    

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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


        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 个 short int,每个 short int 占用 2 个字节 所以整个数组占用20字节内存(sizeof(a))

        【讨论】:

          【解决方案6】:

          变量存储值。 指针也存储值。唯一的区别是它们是内存地址。它们仍然是数字。 这里没有什么复杂的。 您可以将所有指针存储在 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”,你很好。 并打开“指针测试”项目来测试您不清楚的所有内容。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-10-03
            • 2016-09-30
            • 2013-07-04
            • 1970-01-01
            • 2011-11-13
            • 2016-05-17
            • 1970-01-01
            相关资源
            最近更新 更多