当我可以声明变量时,C ++中的指针有什么意义?什么时候适合使用它们?
答案 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 = ▭
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
对象。