指针初步说明小结(C++学习笔记)

来源:互联网 发布:知恒这个名字咋样 编辑:程序博客网 时间:2024/05/16 11:44

一.什么是指针

1,“指针”和存储“值的变量名”的关联:

计算机在存储数据时必须跟踪的3种基本属性:
  • 信息存储在何处;
  • 存储的值是多少;
  • 存储的信息是什么类型。
    声明种使用的类型描述了信息的类型和通过符号来表示其值的变量名。例如,假设实验室首席助理Igor使用了下面的语句:

    int braincount;braincount = 5;

    其中int 是其类型,而braincount 表示是其变量名。
    这些语句在告诉程序,它正在存储整数。并使用名称braincount 来表示该整数的值(这里为5)。

这是其中的一种策略:定义一个简单变量。声明语句指出了值的类型和符号名,还让程序为值分配内存,并在内部跟踪该内存单元
值是指定的量,而地址是派生量。

实际上,程序找到一块能够存储整数的内存,将该内存单元标记为braincount, 并将5复制到该 内存单元中;然后,您可以在程序种使用braincount 来访问该内存单元。(注:该内存单元已经在标记为braincount 是由语句int braincount 来实现。)
这些语句没有告诉您,这个值将存储在内存的什么位置(注:但是这种就是我们所要说的指针,指针来存储地址的一种变量),但程序确实记录了这种信息。实际上,可以使用&运算符来检索braincount 的内存地址。

同时,以上就是另外一种策略,以指针为基础,指针是一个变量,其存储的是值的地址,而不是值本身。
地址视为指定的量,而将值视为派生量。

2,指针策略(C++内存管理编程理念的核心)

指针和C++基本原理

面对对象编程(OOP)传统性编程的区别在于,OOP强调的是在运行阶段进行决策(注:指的是程序正在运行时,比如是在度假时,选择参观哪些景点取决于天气和当时的心情),而不是编译阶段(注:指的是编译器将程序组合起来时,比如在不管什么条件下,都坚持预先设定的日程安排)。
运行阶段决策提供了灵活性可以根据当时的情况进行调整。
例如,考虑为数组分配内存的情况。传统的方法时声明一个数组。要在C++中声明数组,必须指定数组的长度。因此,数组的长度在程序编译时就设定好;这是编译阶段决策。*您可能认为,在80%的情况下,一个包含20个元素的数组足够了,但程序有时需要处理200个元素。为了安全起见,使用一个包含200个元素的数组。这样,程序在大多数情况下都浪费了内存。OOP将这样的决策推迟到运行阶段进行,使程序更灵活。在程序运行后,可以这次告诉它只需要20个元素,而还可以告诉它需要200个元素。

使用数组声明来创建数组时,将采用静态联编,即数组的长度在编译时设置:
int tacos[10]; //static binding,size fixed at compile time
使用new[] 运算符创建数组时,将采用动态联编(动态数组),即将在运行时为数组分配空间,其长度也将在运行时设置。使用完着这种数组后,应使用delete[] 释放其占用的内存:

  int size;  cin>>size;  int* pz = new int [size];   //dynamic binding,size set at run time  ...  delete[] pz;   //free memory when finished

注:使用未命名的内存来存储数值,当不需要时则可以释放,动态编程;而若使用已命名的数组,则当不需要时已经占这内存了,所以无法释放已命名的数组。

总之,使用OOP时,您可能在运行阶段确定数组的长度。为使用这种方法,语言必须允许在程序运行时创建数组。如上例子,C++采用的方法时,使用关键字new 请求正确数量的内存以及使用指针来跟踪新分配的内存的位置。

使用常规变量时,值是指定的量,而地址是派生量。而指针策略,在处理存储数据中,将地址视为指定的量,而将值视为派生量。

二.指针的应用

1.指针是一种特殊的变量

一种特殊类型的变量—–用于存储值的地址。由此可见,指针名表示的是地址。

首先,定义一个指针pe ,再定义一个变量jumbo
第二,使用地址运算符& ,对变量jumbo 取地址,即&jumbo,由此可见,& 是一个对变量取地址的符号;
第三,使用* 运算符,又被称为间接值(indirect velue)或解除引用(dereferencing)运算符,对地址取变量,即*pe
第四,由此可见,jumbo=*pe &jumbo=pe

2.指针的声明和初始化

指针的声明
  • 首先,指针声明必须指定指针指向的数据的类型
  • 计算机需要跟踪指针指向的值的类型。例如,chardouble 使用的字节数不同,它们存储值时使用的内部格式也不同。
  • 例:int* p_updates; int* 是一种类型—指向int 的指针。同时也就是说p_updates
    是一个指向int类型的指针变量,用来存储变量的值的地址。
指针的初始化
int higgens = 5;int* pt = &higgens;    //对指针pt进行声明的同时被赋予变量名higgens的地址,而不是值5(假设值5没有在被higgens存储的情况下)的地址。
  • pt 的一个int* 的指针,从而,被初始化的是指针。
  • pt = &higgens 在这里将higgens 变量的地址赋予指针pt

指针的危险
在C++中,计算机将指针用来分配存储地址的内存,但是不会用来分配存储指针所直接指向的数据的内存。
引用块内容

  long* fellow;    //create a pointer-to-long  *fellow = 223323;    /place a value in never-never land

由上可知,我们不知道将223323 存储在哪个地址,同时,fellow 未被初始化,所以不知道地址是什么?
由此,一定要在指针使用解除引用运算符(*)之前,将指针初始化为一个确定的,适当的地址。

当然,其实计算机通常将地址当作整数来处理。
如果出现以下例子:

    int* pt;    pt = 0xB8000000;  //type mismatch

0xB8000000 赋值给指针pt,但是在此处,我们无法得知0xB8000000,是一个整形还是一个地址,系统会将当做整形来处理,所以需要用到强制类型转换将数字转换为适当的地址类型(int*)

    int* pt;    pt = (int*)0xB8000000;  //type now match