当前位置:编程学习 > C/C++ >>

认识指针

指针的定义是一种保存变量地址的变量。这篇文章主要是清楚“指针保存变量地址”这个认知。
 
首先认识两个符号:*是间接寻址或间接引用运算符。 &用来取一个对象的地址。
 
常见指针用法如下:
 
[cpp]  
int *p;        
int x = 1;                  
p = &x;  
printf("p = %x, &x = %x\n", p, &x);  
printf("*p = %d, x = %d\n", *p, x);  
对指针内部布局有一个认识:
首先明确几个概念:
 
指针变量本身起始地址未知,指针变量里存储的是内存地址。不管指针变量里存的是任何数据,都被当做地址来处理。
 
*前面的数据类型,只是说明指针所指向的内存里存储的数据类型。但在指针增值时,用处颇大。
 
不管什么样的指针类型,其大小都为4byte。(当然,这个与操作系统位数等有关)
 
认识一下,指针操作的每一步。
 
声明后,未进行任何操作:
 
[cpp]  
 int *p;  
 printf("&p = %x,p = %x, *p = %d\n", &p, p, *p);  
// &p = 0022ff44,p = 768d9e34, *p = -7494423  
 //此时,p是一个野指针,其值是系统任意赋的。p和*p都是没有实际意义的。  
 
指针赋值为空:
[cpp]  
        p = (int *)NULL; //NULL的值为0   
        printf("&p = %x,p = %x\n", &p, p);  
        // &p = 22ff44,p = 0 , *p没有意义   
这里,因为系统分配给每个程序一定的内存空间,程序不可访问未分配给自己的内存。
P指向一个有意义的数值:
 
[cpp]  
int a = 2;  
p = &a;  
*p = NULL;   
printf("p = %x,&a = %x, *p = %d, a = %d\n", p, &a, *p, a);  
// p = 0022ff40, &a = 0022ff40, *p = 0, a = 0           
  
*p = 8;  
printf("p = %x,&a = %x, *p = %d, a = %d\n", p, &a, *p, a);   
// p = 0022ff40, &a = 0022ff40, *p = 8, a = 8  
将数据存储到指定的内存地址(略显暴力):
[cpp]  
<span style="white-space:pre">  </span>//int a = 1;  
        //printf("&a = %x\n", &a);  
        p = (int *)0x22ff40;   //p指向地址 0x22ff40  
        *((int *)2293568) = 10;  //在该内存上填值   
        printf("p = %x, *P = %d\n", p, *p);  
        // p = 22ff40, *p = 10  
这里先打印出a的地址,为0x22ff40,表明这个地址可用,再赋值给指针p。
 
 
特殊情况下:
[cpp]  
<span style="white-space:pre">  </span>p = (int *)&p;  
        printf("&p = %d, p = %d, *P = %d\n", &p, p, *p);  
        *p = 0x22ff40;  
        printf("&p = %d, p = %d, *P = %d\n", &p, p, *p);          
        *p = 0;  
        printf("&p = %d, p = %d, *P = %d\n", &p, p, *p);     
        /* 
        &p = 2293572, p = 2293572, *P = 2293572 
        &p = 2293572, p = 2293568, *p = 16      //改变*p的值,实际改变的是p保存的地址值 
        &p = 2293572, p = 229356, *p = 0        //p的值已定,再改变*p,则改的就是指向的值,此时*p = 0.  
        */  
malloc和free的注意事项:
 
[cpp]  
   p = (int *)malloc(sizeof(int) * 5);   
   if(p == NULL)  //需要检查p是否为空,因为系统可能无法分配那么多内存给你哦!   
       return;  
   *p = 123;  
   printf("&p = %p, p = %x, *P = %d\n", &p, p, *p);  
   free(p);  
   printf("&p = %p, p = %x, *P = %d\n", &p, p, *p);  
//   *p = 222;  
//   printf("&p = %p, p = %x, *P = %d\n", &p, p, *p);  
//  &p = 0022ff44, p = 251010, *P = 222  
//  操作违法,报错。free之后再对其进行修改,虽打印出结果,但最后还是报错。   
  p = NULL;   //free之后一定要将p置为空,然后才能使用,否则会出现野指针。   
  printf("&p = %p, p = %x\n", &p, p);       
                  
   /* 
   &p = 0022ff44, p = 251010, *P = 123 
   &p = 0022ff44, p = 251010, *P = 2439224 
   &p = 0022ff44, p = 0 
   free之后,p的值还没有改变,只是斩断了p与之前malloc开辟的那段内存之间的关系, 
   即那段内存已经不是属于p的了,系统可能已经把该块内存分配给别的程序了,p不能擅自更改。 
   以上结果知,仍可以通过p访问内存,但不能修改(修改后报错),而且访问的值可能已经改变了 
   (第二次打印结果*P = 2439224)。  
    
   free之后一定要将p置为空,然后才能使用,否则会出现野指针。 
   指针p的类型以及它所指的内存的容量事先都是知道的,所以语句free(p)能正确地释放内存. 
   如果p是 NULL指针,那么free对p无论操作多少次都不会出问题。 
   如果p不是NULL指针,那么free对p连续操作两次就会导致程序运行错误。         
   */  
 
通过以上内容,应该能对指针变量的本质有个清楚的认识。
 
 
 
 
 
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,