C++声明和初始化指针

  计算机需要跟踪指针指向的值的类型。例如,char的地址与double的地址看上去没什么两样,但char和double使用的字节数是不同的,它们存储值的使用的内部格式也不同。因此,指针声明必须指定指针指向的数据的类型。

  例如,前一个示例包含这样的声明:int * p_updates;

  这表明,*p_updates的类型为int。由于*运算符被用于指针,因此p_updates变量本身必须是指针。我们说p_updates指向int类型,我们还是说p_updates的类型是指向int的指针,或int*。可以这样说,p_updates是指针(地址),而*p_updates是int,而不是指针。

  *运算符两边的空格是可选的。传统上C程序员使用这种格式:int *ptr;

  这强调*ptr是一个int类型的值。而很多C++ 程序员使用这种格式:int* ptr;

  这强调的是:int*是一种类型——指向int的指针。在哪里添加空格对于编译器来讲没有任何区别,甚至可以这样做:

  int*ptr;

  但要知道的是,下面声明城建一个指针(p1)和一个int变量(p2):

  int * p1, p2;

  对于每个指针变量名,都需要使用一个*。

  注意:在C++中,int*是一种符合类型,是指向int的指针。

  可以用同样的句法来声明指向其他类型的指针:

  double * tax_ptr;

  char * str;

  由于已将tax_ptr声明为一个指向double的指针,因此编译器知道*tax_ptr是一个double类型的值。也就是说,它知道*tax_ptr是一个以浮点格式存储的值,这个值(在大多是系统上)占据8个字节。指针变量不仅仅是指针,而且是指向特定类型的指针。tax_ptr的类型是指向double的指针(或double *类型),str是指向char的指针类型(或char*)。尽管它们都是指针,确实不同类型的指针。和数组一样,指针都是基于其他类型的。

  虽然tax_ptr和str指向两种长度不同的数据类型,但这两个变量本身的长度通常是相同的。也就是说,char的地址与double的地址长度相同,这就好比1016可能是超市的街道地址,而1024可以是小村庄的街道地址一样。地址的长度或值既不能指示关于变量的长度或类型的任何信息,也不能指示该地址上有什么建筑物。一般来说,地址需要2个还是4个字节,取决于计算机系统(有些系统可能需要更大的地址,系统可以针对不同的类型使用不同长度的地址)。

  可以在声明语句中初始化指针。在这种情况下,被初始化的是指针,而不是它指向的值。也就是说,下面的语句将pt(而不是*pt)的值设置为&higgens;

  int higgens = 5;

  int * pt = &higgens;

  

//程序清单4.6 演示如何将指针初始化为一个地址。
#include <iostream>
int main()
{
using namespace std;
int higgens = 5;
int* pt = &higgens;

cout << "Value of higgens = " << higgens
<< "; Address of higgens = " << &higgens << endl;
cout << " Value of pt = " << *pt
<< "; Value of pt = " << pt << endl;
return 0;
}

下面是该程序的输出:

Value of higgens = 5; Address of higgens = 0076FB20
Value of pt = 5; Value of pt = 0076FB20

   从中可知,程序将pt(而不是*pt)初始化为higgens的地址。在系统上,显示的地址可能不同,显示的格式也可能不同。

指针的危险

  危险更易发生在那些使用指针不仔细的人身上。极其重要的一点是:在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。为数据提供空间是一个独立的步骤,忽略这一步无疑时自找麻烦,如下所示:

  long * fellow;  //create a pointer-to-long

  *fellow = 223323;   //place a value in never-never land

  fellow确实是一个指针,但它指向哪里呢?上述代码没有将地址赋给fellow。那么223323将被放到哪里呢?我们不知道。由于fellow没有被初始化,它可能有任何值。不管值是什么,程序都将它解释为存储223323的地址。如果fellow的值碰巧为1200,计算机将把数据放在地址1200上,即使这恰巧是程序1200的地址。fellow指向的地方很可能并不时所要存储223323的地方。这种错误可能会导致一些最隐匿、最难以跟踪的bug。

  警告:一i的那个要再对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的,适当的地址。这是关于使用指针的金科玉律。

 

指针和数字

  指针不是整形,虽然计算机通常把地址当作证书来处理。从概念上看,指针与整数时截然不同的类型。整数时可以执行加、减、除等运算的数字,而指针描述的是位置,将两个地址相乘没有任何意义。从可以对整数和指针执行的操作上看,它们也是彼此不同的。因此,不能简单地将整数赋给指针:

  int * pt;

  pt = 0xB8000000;

     在这里,左边是指向int的指针,因此可以赋之以地址,但右边是一个整数。您可能知道,0xB8000000是老式计算机系统中视频内存组合段偏移地址,但条语句并没有告诉程序,这个数字就是一个地址。在C99标准发布之前,C语言允许这样赋值。但C++在类型一致方面的要求更严格,编译器将显示一条错误的信息,通告类型不匹配。腰间个数字值作为地址来使用,应通过强制类型转换将数字转换为适当的地址类型:

  int * pt;

  pt =  (int *) 0xB8000000;

  这样,赋值语句的两边都是整数的地址,因此这样赋值有效。注意,pt 是 int 值的地址并不意味着 pt 本身的类型是int。例如,在有些平台中,int类型是2个字节值,而地址是个4字节值。

 

posted @ 2022-01-23 22:09  渔阳俊俊  阅读(411)  评论(0编辑  收藏  举报