指针有什么意义?

时间:2009-05-12 01:47:42

标签: c++ pointers

当我可以声明变量时,C ++中的指针有什么意义?什么时候适合使用它们?

12 个答案:

答案 0 :(得分:29)

C& S最能理解指针。 C ++在变量传递给函数方面的差异。

是的,您可以传递整个变量或仅传递指针(行话分别是值或引用)。

但是,如果变量是20兆字节的字节,如果您决定将整个文件读入一个数组,该怎么办?通过它传递它将是愚蠢的:为什么你会复制20兆的这个操作,如果你最终修改它(即它是一个超出参数)你必须复制那20兆的BACK?

最好只是“指出”它。你说,“这是指向一大块记忆的指针”。而那个小小的间接节省了大量的时间。

一旦你理解了,其他一切基本相同。重新排列列表中的项目只是交换指针而不是复制每个项目,你不需要知道开始时有多大的事情等等。

答案 1 :(得分:16)

在处理编译时未知大小和形状的数据结构时,指针最有用(想想列表,树,图,数组,字符串......)。

修改

这些相关的答案也可能有所帮助(第二个链接中的最佳答案绝对值得一看):

In C++ I Cannot Grasp Pointers and Classes

What are the barriers to understanding pointers and what can be done to overcome them?

答案 2 :(得分:2)

指针也非常适合将可变参数传递给函数,以便调用者可以“看到更改”。您可能想知道,“但为什么不使用参考?”。我喜欢谷歌的论点:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments

答案 3 :(得分:1)

当我学习指针时,我有完全相同的问题,它们似乎并不重要,但随着你的进步,你会发现它们有时非常有用。

在编程情况下经常使用指针。例如,当您按名称引用数组时,例如 array[i] = 3; 编译器正在进行一些花哨的数学运算,最终将代码转换为

(数组的地址)+(sizeof(数组元素)* i)= 3;

它们还可以使树,链表和其他数据结构成为可能,您将在了解更多信息时找到它们。

答案 4 :(得分:1)

在最基本的级别,指针允许您关联不相交的内存块。一个简单的(人为的,可以肯定的)指针可以帮助你的例子将是一个需要1000000000000个整数数组的算法。如果我尝试了如下定义,这样的数组太大,无法放入我正在键入的机器的RAM中:

int bigMatrix[1000000000000]; // I can't allocate this much contiguous memory

但是,如果我创建一个指针数组,我可以将子数组保存在一个中等大小的磁盘阵列上。

int *bigMatrix[1000000]; // Each pointer refers to a sub-array 
                         // of 1000000 elements on disk

不可否认,如果/当用户需要时,我将不得不在这些子数组中编写代码页面,包括将数组符号隐藏在访问器方法后面。也就是说,指针允许我在需要时创建我需要的临时关联。

答案 5 :(得分:0)

有时你有一个函数需要返回一些不是设定数量的内存,比如从文件中读取。

bool ReadDataFromFile(char** contents);

您将声明一个char *内容并将该指针的地址传递给该函数。然后该函数将分配内存,并且您的指针将在返回时指向内容。

答案 6 :(得分:0)

除了效率和灵活性之外.C / C ++中的主要指针是硬件的工作方式,你不能在不使用指针的情况下使用设备驱动程序,内存管理器或高效缓存。

第一个C编译器的主要设计目标之一是成为一种“可移植的汇编语言”,并且能够用更高级别的语言完成传统汇编/机器代码所能做的任何事情。这意味着能够直接操作地址 - 这是指针。

然而,遵循KISS原则不要使用指针,除非它们确实使事情变得更简单。

答案 7 :(得分:0)

从架构的角度来看,指针是建立0 ... n关系的经济方式:

struct A {
  vector<const B *> *pBees;
  A() : pBees(nullptr) {}
  void notice_bee(const B *pB) { 
    if (!pBees)
      pBees = new vector<const B *>;
    pBees.push_back(pB)
  }
  ~A() { 
    delete pBees; // no need to test, delete nullptr is safe
  }
  size_t bees_noticed() { return pBees ? pBees->size : 0 }
};

如果绝大多数A对象永远不需要关注任何B对象,则没有理由为每个A对象都应该有一个零长度向量。在Gnu C ++ 4.0.1下,sizeof(vector)为12; sizeof(vector *)是4.

答案 8 :(得分:0)

假设您编写了一个文本编辑器。在这种情况下,您事先不知道文档的大小。您可能想要声明类似

的内容
  char Document[10000];

但是当然有一天你会想要在更大的文档上使用你的编辑器。所以这种尝试是徒劳的;你需要的是一种在运行时(而不是编译时)请求新内存的方法。

C ++的方法是使用new new,它返回一个指向新分配内存的指针:

  char* pDocument = new char[getSizeOfDocument()];

(请注意,此示例过于简单。在现实生活中,您肯定不会这样做,而是使用类似std :: string和std :: vector的内容,它们会在内部为您执行此分配。)​​

答案 9 :(得分:0)

听起来我还没有了解动态内存分配。在C ++中有两种分配内存的方法:静态和动态。您已熟悉静态分配(即 - 声明变量)。如果您在编写程序时确切知道需要多少变量(或者更确切地说是内存),那就太棒了。

但是如果你不这样做呢?例如,假设您正在阅读,其中包含您需要跟踪的一堆数字。为什么?我不知道,但那不是重点。

嗯,你可以从数组开始:

int array[100];

但如果文件中有超过100个数字怎么办?最终,您需要一个更灵活的解决方案:

int *array = new int[size];
// do stuff
delete [] array;

这为您提供了更大的灵活性,并允许您创建更多动态数据结构。

答案 10 :(得分:0)

指针存储一个内存地址,因此您可以在需要内存地址时使用它们。 这对于诸如内存管理之类的事情非常有用,可以了解数据的存储位置。我的教授告诉我们,对于确保数据在内存中连续定位(如c风格的字符串)而言,这对于高级程序来说是一件很棒的事。

希望这对你有所帮助!

-Zen,c ++的新手

答案 11 :(得分:-3)

来自Wikipedia

  

C ++引用与指针不同   几个基本方法:

     
      
  • 之后无法直接引用参考对象   它被定义;任何事件的发生   name直接指对象   引用。
  •   
  • 创建参考后,以后无法参考   另一个对象;我们说它不可能   重新插拔。通常这样做   指针。
  •   
  • 引用不能为null,而指针可以为;每个参考文献   对某些物体,尽管它可能或可能   无效。
  •   
  • 参考文献不能未初始化。因为这是不可能的   重新初始化参考,他们必须   尽快初始化   创建。特别是当地和   必须初始化全局变量   它们的定义和参考   这是类的数据成员   实例必须在。中初始化   该类的初始化列表   构造
  •   

由于存在上述限制,指针只是作为引用对象的轻量级容器而获得的,尤其是在您使用多态或动态的情况下。用于表示窗口的纯抽象类指针的动态数组就是一个例子。

由于我懒得想一个多态的例子,我会从cplusplus.com中提取一个:

// pointers to base class
#include <iostream>
using namespace std;

class CPolygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
  };

class CRectangle: public CPolygon {
  public:
    int area ()
      { return (width * height); }
  };

class CTriangle: public CPolygon {
  public:
    int area ()
      { return (width * height / 2); }
  };

int main () {
  CRectangle rect;
  CTriangle trgl;
  CPolygon * ppoly1 = &rect;
  CPolygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << rect.area() << endl;
  cout << trgl.area() << endl;
  return 0;
}

在上面的代码中,指针CPolygon *用于引用CRectangle对象和CTriangle对象。