代码改变世界

学习C++ -> 指针初步

2013-01-14 21:03  wid  阅读(4003)  评论(1编辑  收藏  举报

学习C++ -> 指针初步



一、指针
    1. 什么是指针?
        我们知道, 计算机的内存是由一个个独立的存储单元组成, 并且系统会对每一个存储单元分配一个唯一的号码, 称为这个存储单元的"地址"。分配号码给一个存储单元的目的是为了便于找到它, 从而进行进一步的操作, 比如是读取还是写入。
        
        在C++中, 如果要对某个存储单元进行访问(读取/写入), 有两种方式, 一是通过变量名找到存储地址再进行访问, 二是直接通过存储地址进行访问。
            1>. 通过变量名进行访问
                通过变量名进行访问就是我们通过编译器起一个名字, 程序在运行时, 系统为该程序建立一个变量名与内存单元地址之间的映射表, 通过名字即可找到该存储单元的地址并进行操作。例如:
                    char name ;        int value = 10 ;    float price ;
                等这些都属于通过变量名对内存单元中的值进行操作。
                
            2>. 通过地址直接访问
                显然, 通过地址直接进行访问要比经过一次 "中转" 速度更快, 既然要通过地址进行直接访问那么就必须要知道这个地址的值(编号)是多少, 并且要把这个地址值(编号)给保存起来, 这样才能方便后来随时直接访问这个地址。
                
                在这种方式中, "地址" 给他起了个新的名字, 叫指针, 而保存指针的变量称为指针变量。
                
                
    2. 认识指针
        同一般的变量, 每种变量都有自己的数据类型, 如 int a ; 说明这个变量是保存一个整数的。 指针亦是如此, 定义一个指针变量:
            int *pa ;
        int *pa ; 则表示变量pa是一个指针变量, pa应当保存类型为int的变量在内存中的地址。
        同理, 我们还可以定义其他类型的指针变量:

            char   *pa ;
            int    *pb ;
            float  *pc ;
            double *pd ;

            ...
        定义时, 其*号的位置可以靠左( int* pa; ), 居中( int * pa; )或靠右( int *pa; ), 具体使用哪种形式可根据个人习惯。
        一个语句中也可以同时定义多个指针变量, 方法为:

            int *pa, *pb, *pc ;

 
            
    3. 指针的初始化与赋值
        我们已经知道, 指针变量中所保存的内容为内存的地址, 要对指针变量进行初始化首先应该取到被指向的变量在内存中的地址。在C++中, 用 '&' 符号来获取变量的地址, 如:

        #include <iostream>

        int main()
        {
            int a = 10 ;
            std::cout<< &a ;    //输出变量a在内存中的地址

            return 0 ;
        }

 
        输出窗口显示:

        0x23ff4c
        Process returned 0 (0x0)   execution time : 0.031 s
        Press any key to continue.

 
        这个 0x23ff4c 就是以16进制输出的当前a变量在内存中的地址, 这个值与当前计算机内存的状态有关, 所以不同计算机输出的可能不同。
        
        指针可以在定义时对其进行初始化, 如:

            int a = 10 ;
            int *pa = &a ;


        也可以对指针变量进行赋值操作:

            int *pb ;
            int b = 10 ;
            pb = &b ;        //将b的地址赋值给指针变量pb

 
            
            
    4. 指针的初步使用
        知道了如何对指针类型进行定义、初始化以及如何赋值后就可以初步的去运用指针了, 首先看一个运用示例:

        #include <iostream>

        int main()
        {
            int a = 10 ;
            int *pa = &a ;      //定义指针变量pa并初始化地址为变量a在内存中所在的地址

            std::cout<< a << "\n" ;      //通过变量名访问a变量所在的地址
            std::cout<< *pa << "\n" ;    //运用*号访问指针变量pa中所保存的地址

            return 0 ;
        }


        输出:

        10
        10

        Process returned 0 (0x0)   execution time : 0.016 s
        Press any key to continue.

 
        可以看到, std::cout<< a << "\n" ;std::cout<< *pa << "\n" ; 输出的是相同的结果, 都是10。这是因为 a 与 *pa 实际上都是指向同一个存储地址, *号为间接访问符, 表示要访问指针变量中所存放的内存地址。
        
        再看一个示例, 运用指针改变变量的值:

        #include <iostream>

        int main()
        {
            int b = 10 ;
            int *pb = &b ;

            std::cout<<"改变前b变量中的值:"<<b<<"\n" ;
            *pb = 20 ;      //运用指针改变变量a所在的存储单元中的内容
            std::cout<<"改变后b变量中的值:"<<b<<"\n" ;

            return 0 ;
        }


        这里运用 *pb = 20 ; 来改变变量b的值, 其功能与 b = 20 ; 的作用相同, 实际他们所改变的都是同一段内存单元中的值。只要能够理解这点, 在掌握指针上会有很大的帮助。
        
        
    5. 指针运用时需要注意的一些问题
        1>. 左右两边类型要一致
            什么类型的指针变量存放什么类型的地址。
            
        2>. 避免"野"指针
            所谓的野指针即为没有被正确初始化或赋值的指针, 他会随机指向内存中的某个存储单元, 如果不慎通过这个指针对其内存中的值进行其他操作的话后果是不可预知的。 总之, 要保证指针指向的正确性, 在不用时要及时对其赋值为 NULL, 即将其指向的地址设为NULL, 也就是空指针。

            

这里所学习的内容为指针的一些最基础的知识, 或许在这里并没有体现出指针的如何强大, 但随着学习的深入使用指针的优势就会逐渐体现出来。


--------------------


wid, 2013.01.14


上一篇: 学习C++ -> 二维数组