`
zhaohaolin
  • 浏览: 1019821 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

C++中关于指针入门的最好的文章

 
阅读更多

什么是指针?

    其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针是一个指示器,它告诉程序在内存的哪块区域可以找到数据。这是一个非常重要的概念,有很多程序和算法都是围绕指针而设计的,如链表。

    开始学习

    如何定义一个指针呢?就像你定义一个其它变量一样,只不过你要在指针名字前加上一个星号。我们来看一个例子:下面这个程序定义了两个指针,它们都是指向整型数据。

    int* pNumberOne;

    int* pNumberTwo;

    你注意到在两个变量名前的“p”前缀了吗?这是程序员通常在定义指针时的

    一个习惯,以提高便程序的阅读性,表示这是个指针。现在让我们来初始化这两个指针:

    pNumberOne = &some_number;pNumberTwo = &some_other_number;

    &号读作“什么的地址”,它表示返回的是变量在内存中的地址而不是变量本身的值。在这个例子中,pNumberOne 等于some_number的地址,所以现在pNumberOne指向some_number. 如果现在我们在程序中要用到some_number,我们就可以使用pNumberOne.

    我们来学习一个例子:

    在这个例子中你将学到很多,如果你对指针的概念一点都不了解,我建议你多看几遍这个例子,指针是个很复杂的东西,但你会很快掌握它的。

    这个例子用以增强你对上面所介绍内容的了解。它是用C编写的(注:原英文版是用C写的代码,译者重新用C++ 改写写了所有代码,并在DEV C++ 和VC++中编译通过!)

 #include <iostream.h>
  
  void main()
  {
  // 声明变量:
  
  int nNumber;
  int *pPointer;
  
  // 现在给它们赋值:
  
  nNumber = 15;
  pPointer = &nNumber;
  
  //打印出变量nNumber的值:
  
  cout<<"nNumber is equal to :"<< nNumber<<endl;
  
  // 现在通过指针改变nNumber的值:
  
  *pPointer = 25;
  
  //证明nNumber已经被上面的程序改变
  
  //重新打印出nNumber的值:
  
  cout<<"nNumber is equal to :"<<nNumber<<endl;
  }

    通读一下这个程序,编译并运行它,务必明白它是怎样工作的。如果你完成了,准备好,开始下一小节。

    陷井!

    试一下,你能找出下面这段程序的错误吗?

 #include <iostream.h>
  
  int *pPointer;
  
  void SomeFunction();
  
  {
  int nNumber;
  nNumber = 25;
  
  //让指针指向nNumber:
  
  pPointer = &nNumber;
  }
  
  void main()
  {
  SomeFunction(); //为pPointer赋值
  
  //为什么这里失败了?为什么没有得到25
  
  cout<<"Value of *pPointer: "<<*pPointer<<endl;
  }

    这段程序先调用了SomeFunction函数,创建了个叫nNumber的变量,接着让指针pPointer指向了它。可是问题出在哪儿呢?当函数结束后,nNumber被删掉了,

    因为这一个局部变量。局部变量在定义它的函数执行完后都会被系统自动删掉。也就是说当SomeFunction 函数返回主函数main()时,这个变量已经被删掉,但pPointer还指着变量曾经用过的但现在已不属于这个程序的区域。如果你还不明白,你可以再读 读这个程序,注意它的局部变量和全局变量,这些概念都非常重要。

    但这个问题怎么解决呢?答案是动态分配技术。注意这在C和C++中是不同的。由于大多数程序员都是用C++,所以我用到的是C++中常用的称谓。

    动态分配

    动态分配是指针的关键技术。它是用来在不必定义变量的情况下分配内存和让指针去指向它们。尽管这么说可能会让你迷惑,其实它真的很简单。下面的代码就是一个为一个整型数据分配内存的例子:

    int *pNumber;

    pNumber = new int;

    第一行声明一个指针pNumber.第二行为一个整型数据分配一个内存空间,并让pNumber指向这个新内存空间。下面是一个新例,这一次是用double双精型:

    double *pDouble;pDouble = new double;

    这种格式是一个规则,这样写你是不会错的。

    但动态分配又和前面的例子有什么不同呢?就是在函数返回或执行完毕时,你分配的这块内存区域是不会被删除的所以我们现在可以用动态分配重写上面的程序:

 

 #include <iostream.h>
  
  int *pPointer;
  
  void SomeFunction()
  {
  
  // 让指针指向一个新的整型
  
  pPointer = new int;
  *pPointer = 25;
  }
  
  void main()
  {
  SomeFunction(); // 为pPointer赋值
  
  cout<<"Value of *pPointer: "<<*pPointer<<endl;
  }

    通读这个程序,编译并运行它,务必理解它是怎样工作的。当SomeFunction调用时,它分配了一个内存,并让pPointer指向它。这一次,当函 数返回时,新的内存区域被保留下来,所以pPointer始终指着有用的信息,这是因为了动态分配。但是你再仔细读读上面这个程序,虽然它得到了正确结 果,可仍有一个严重的错误。

    分配了内存,别忘了回收

    太复杂了,怎么会还有严重的错误!其实要改正并不难。问题是:你动态地分配了一个内存空间,可它绝不会被自动删除。也就是说,这块内存空间会一直存在,直 到你告诉电脑你已经使用完了。可结果是,你并没有告诉电脑你已不再需要这块内存空间了,所以它会继续占据着内存空间造成浪费,甚至你的程序运行完毕,其它 程序运行时它还存在。当这样的问题积累到一定程度,最终将导致系统崩溃。所以这是很重要的,在你用完它以后,请释放它的空间,如:

    delete pPointer;

    这样就差不多了,你不得不小心。在这你终止了一个有效的指针(一个确实指向某个内存的指针)。下面的程序,它不会浪费任何的内存:

    #include <iostream.h>

    调用时,它分配了一个内存,并让pPointer指向它。这一次,当函数返回时,新的内存区域被保留下来,所以pPointer始终指着有用的信息,这是因为了动态分配。但是你再仔细读读上面这个程序,虽然它得到了正确结果,可仍有一个严重的错误。

    分配了内存,别忘了回收

    太复杂了,怎么会还有严重的错误!其实要改正并不难。问题是:你动态地分配了一个内存空间,可它绝不会被自动删除。也就是说,这块内存空间会一直存在,直 到你告诉电脑你已经使用完了。可结果是,你并没有告诉电脑你已不再需要这块内存空间了,所以它会继续占据着内存空间造成浪费,甚至你的程序运行完毕,其它 程序运行时它还存在。当这样的问题积累到一定程度,最终将导致系统崩溃。所以这是很重要的,在你用完它以后,请释放它的空间,如:delete pPointer;

    这样就差不多了,你不得不小心。在这你终止了一个有效的指针(一个确实指向某个内存的指针)。

    下面的程序,它不会浪费任何的内存:

 #include <iostream.h>
  
  int *pPointer;
  
  void SomeFunction()
  {
  
  // 让指针指向一个新的整型
  
  pPointer = new int;
  *pPointer = 25;
  }
  
  void main()
  {
  SomeFunction(); //为pPointer赋值
  
  cout<<"Value of *pPointer: "<<*pPointer<<endl;
  
  delete pPointer;
  }

    只有一行与前一个程序不同,但就是这最后一行十分地重要。如果你不删除它,你就会制造一起“内存漏洞”,而让内存逐渐地泄漏。(译者:假如在程序中调用了两次SomeFunction,你又该如何修改这个程序呢?请读者自己思考)

    传递指针到函数

    传递指针到函数是非常有用的,也很容易掌握。如果我们写一个程序,让一个数加上5,看一看这个程序完整吗:

 #include <iostream.h>
  
  void AddFive(int Number)
  {
  Number = Number + 5;
  }
  
  void main()
  {
  int nMyNumber = 18;
  
  cout<<"My original number is "<<nMyNumber<<endl;
  AddFive(nMyNumber);
  cout<<"My new number is "<<nMyNumber<<endl;
  
  //得到了结果23吗?问题出在哪儿?
  
  }

    问题出在函数AddFive里用到的Number是变量nMyNumber的一个副本而传递给函数,而不是变量本身。因此, " Number = Number + 5" 这一行是把变量的副本加了5,而原始的变量在主函数main()里依然没变。试着运行这个程序,自己去体会一下。要解决这个问题,我们就要传递一个指针到 函数,所以我们要修改一下函数让它能接受指针:把'void AddFive(int Number)' 改成 'void AddFive(int*Number)' 。下面就是改过的程序,注意函数调用时要用&号,以表示传递的是指针:

  #include <iostream.h>
  void AddFive(int* Number)
  {
  *Number = *Number + 5;
  }
  
  void main()
  {
  int nMyNumber = 18;
  
  cout
分享到:
评论

相关推荐

    C++入门(C++入门教程)

    ### C++ 入门知识点详解 #### 一、C++ 学习的重要性及误区 C++作为一门强大的编程语言,在软件开发领域占有举足轻重的地位。然而,由于其复杂性和深度,对于初学者来说,很容易走入一些学习的误区。 **误区一:...

    C++入门及提升精品文章总汇

    本文将基于"C++入门及提升精品文章总汇"这一资源,针对其中涉及的C++指针知识进行详细阐述。 1. **指针基础**: - 指针是一个变量,它存储的是另一个变量的地址,而不是其值。了解指针类型、声明和初始化是学习...

    C++入门经典(第3版)+源代码

    Ivor Horton还著有Beginning Visual C++6、Beginning C Programming和Beginning Java2 等多部入门级好书。 李予敏,男,计算机科学及应用专业博士,某研究院高级研究员,拥有丰富的C、C++编程经验,在核心期刊、...

    c++入门详解适合新手

    本篇文章将详细解析C++入门的学习路径,同时结合孙鑫老师的视频教学资源,帮助新手快速上手。 1. **C++概述**: C++是由Bjarne Stroustrup在C语言的基础上发展起来的,它引入了类、对象、模板等面向对象编程的概念...

    C++入门实用知识库分享

    C++入门实用知识库分享 本资源共包含24篇文章,涵盖了C++编程语言的基础知识和高级概念。从类型转换、复制构造函数、友元函数到运算符重载、this指针、析构函数、构造函数、面向对象和类等方面,全面地介绍了C++...

    C++/CLI教程

    7. 指针和引用(Pointers and References):在C++/CLI中,指针和引用的使用与传统C++有所不同。例如,托管代码中使用指针时需要考虑垃圾回收的影响,而引用则是一个保留字,用于访问托管对象。 8. 包含规则(Rules...

    Microsoft_Visual_Studio_C++_2010入门教程(修订版).pdf

    ### Microsoft Visual Studio C++ 2010 入门教程(修订版) —— 关键知识点解析 #### 前言 《Microsoft Visual Studio C++ 2010 入门教程(修订版)》是一份针对初学者的实用指南,旨在帮助读者快速掌握Visual C++ ...

    C++入门学习——模板示例代码

    本篇文章将深入探讨C++模板的基本概念、类型和函数模板,以及模板特化和元编程等高级主题。 首先,我们要理解C++中的模板分为两种:类型模板和函数模板。类型模板主要用于定义泛型类,而函数模板则用于创建泛型函数...

    MIT 麻省理工 c++ 6.096 lecture5

    在本篇文章中,我们将深入探讨MIT OpenCourseWare提供的《C++ 入门》(6.096 Introduction to C++)课程中的第5讲内容。这一讲主要聚焦于指针的概念、使用以及它们在C++编程语言中的重要性。为了更好地理解这些知识...

    Visual C++ 2005入门经典--源代码及课后练习答案

    该资料是《Visual C++ 2005入门经典》的源代码及课后练习答案 对应的书籍资料见: Visual C++ 2005入门经典 基本信息 原书名: Ivor Horton's Beginning Visual C++ 2005 原出版社: Wiley 作者: (美)Ivor Horton...

    C++基础入门:语法和数据类型.docx

    本专栏文章中,我们将介绍C++的基本语法和数据类型,帮助您快速入门并开始编写自己的C++程序。 1. C++的基本语法和结构 C++程序由一系列语句组成,每个语句以分号结束。C++程序的基本结构包括头文件、函数和变量...

    C&C++.rar_C++_C/C++精华文章_c

    这篇文章可能深入讨论了C++中的特定语言特性,比如模板、异常处理、STL(标准模板库)、智能指针等,帮助读者理解C++中的高级概念。 4. **鼠标屏幕取词 原理.txt**: 讨论了如何利用C++实现屏幕抓取和文本识别...

    introduction to C++

    Tom Anderson所撰写的《C++快速入门》是一篇精炼的文章,旨在为读者提供一个简单且易于学习的C++子集介绍。本文将基于该文章的部分内容,深入探讨C++的核心概念及其应用场景。 #### C++的特点 作者引用了一句匿名...

    C++初学者PPT,老师也可以下载

    在C++中,可以通过虚函数实现多态,使得基类指针或引用可以调用派生类的重写方法。 四、实例分析 以下的SortPara和SortFile类展示了面向对象的封装和继承概念: ```cpp class SortPara { protected: int[] ...

    超强推荐C/C++基础教程{100部},

    本压缩包中的"C、C++基础教程{100部}.txt"很可能是教程的索引或者链接列表,里面可能包含了100个不同的学习资源,包括文章、视频教程、实战项目等。使用这个资源,学习者可以根据自己的进度和需求选择合适的学习材料...

    A Quick Introduction To C++

    作者假设读者已经对C语言中的基本概念有所了解,比如函数(即C++中的过程)、for循环以及指针等。这些概念可以通过阅读《C程序设计语言》这本书来获得,该书由Brian Kernighan和Dennis Ritchie编写,是学习C语言的...

Global site tag (gtag.js) - Google Analytics