指针的一些知识

来源:互联网 发布:怡海软件技术有限公司 编辑:程序博客网 时间:2024/05/17 04:32

    指针类型

    从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. int *ptr; //指针的类型是int *    
  2. char *ptr; //指针的类型是char *    
  3. int **ptr; //指针的类型是 int **    
  4. int (*ptr)[3]; //指针的类型是 int(*)[3]    
  5. int *(*ptr)[4]; //指针的类型是 int *(*)[4]  

   指针所指向的类型

   当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. int *ptr; //指针所指向的类型是int    
  2. char *ptr; //指针所指向的的类型是char    
  3. int **ptr; //指针所指向的的类型是 int *    
  4. int (*ptr)[3]; //指针所指向的的类型是 int()[3]    
  5. int *(*ptr)[4]; //指针所指向的的类型是 int *()[4]   

 地址相关运算--“*”和“&”

“*”在地址运算中叫做指针运算符,表示指针指向的变量的值,是一元操作符,例如,如果p是一个int型的指针,则*p表示p指向的int型数据的值。“&”在地址运算中叫做取地址运算符,也是一个一元操作符,用来获取一个对象的地址,例如,有一个变量i,&i就表示变量i的存储单元地址。“*”出现在声明语句中被声明的变量名之前时,表示声明的是指针,例如,int
*p;。“*”出现在声明语句的初值表达式中或者执行语句中时,表示指针指向的对象的内容,例如,int i=*p; cout<<*p;。“&”出现在声明语句中被声明的变量名之前时,表示声明的是引用,例如,int &rf;。“&”出现在声明语句的初值表达式中或者执行语句中时,表示取对象的地址

指针的赋值

 当我们声明了一个指针之后,这个指针变量中没有存储任何确定的地址值,而是一个随机整数。也就是它指向的地址是不确定的,有可能它指向了系统的重要数据,这时候我们如果修改了它指向地址的值可能会引起想象不到的系统问题。所以指针声明以后要先赋值才可以引用。

给指针赋值可以有下面两种方法:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. int a[5];         // 声明一个整型数组  
  2. int *p1=a;     // 声明指针p1,并用数组首地址a来初始化p1  
  3. int *p2;         // 声明指针p2  
  4. p2=a;           // 将数组首地址a赋值给指针p2  

数组名就是数组的首地址,所以可以用数组名来赋值给指针。

     赋给指针变量的值必须是地址常量(比如数组名)或地址变量,但一定不能是非0整数。给指针赋值为0时表示该指针是一个空指针,它不指向任何地址,比如,int *p=0;。为什么会把指针声明为空指针呢?我们在声明一个指针时没有给它赋值,这时它是一个随机的值,在给它赋确定的地址值之前如果我们使用了它,就可能会访问到重要的内存地址并破坏此地址的数据,造成严重后果,所以我们在软件开发中一般先将指针设为空指针。

举个例子:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. int main(void)  
  3. {  
  4.     using namespace std;  
  5.     int *p; //声明int型指针p  
  6.     int i=6; //声明int型数i,赋值为6  
  7.     p=&i; //取i的地址赋给p  
  8.   
  9.     cout<<"Value: i="<<i;//输出int型数的值  
  10.     cout<<", *p="<<*p<<endl;  
  11.   
  12.     cout<<"Addresses: &i= "<<&i;//输出i的地址  
  13.     cout<<", p: p= "<<p<<endl;//输出p的值  
  14.   
  15.     *p=*p+1;  
  16.     cout<<"Now i= "<<i<<endl;   
  17.   
  18.     return 0;  
  19. }  

输出的结果为

    注意:int *p=&i,是初始化指针p,将其值定义为&i,并不是初始化*p,另外给指针赋值时,并不能直接在那放个整数,例如 int*p;p=0xB8000000;这个左边的p是一个指向int的指针,不一定是int型,可以把它赋给地址,但是右边是一个整数,并不能代表其为一个地址,,最好的办法就是强制类型转换p=(int *) 0xB8000000;

    我们可以声明指向常量的指针,这时候指针本身的值可以改变,也就是指针可以指向其他对象,但是我们不能通过指针改变它指向的值。例如:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. const char *name="Tom"//指向常量的指针  
  2. char s[]="Lili";  
  3. name=s;                               //正确,name本身的值可以改变  
  4. *name=’a’;                           //编译时指出错误,不能通过name修改指向的对象  
我们还可以声明指针常量,这时候指针本身的值不能改变,例如:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. int a=1;  
  2. int b=2;  
  3. int *const p=&a;    // 声明指针常量p  
  4.  p=&b;               // 错误,不能改变指针常量p的值  

         我们进行指针赋值时可以将某个指针的值赋给相同类型的另一个指针。但是有一种特殊类型的指针,可以用任意类型对象的地址为之赋值,这就是void类型指针。我们在使用void类型的指针访问数据时需要进行强制类型转换。举个例子:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:FangSong_GB2312;"void *p;  
  2.  int *p1;  
  3.  int a;  
  4.  void main()  
  5.   {  
  6.        p=&a;         // void类型的指针p指向整型变量a  
  7.        p1=(int*)p;   // 用强制类型转换的方式将void指针p的指针赋给int型指针p1  
  8.    }</span>  

1 0