关于变量、指针、别名(引用)和指针的指针

C/C++中的指针和别名这个东西确实是够恶心的。今天蛋疼的就写一下这些东西的区别,变量永远是最简单的没有什么技术含量,那么另外一个比较简单的就是别名了,其实个人感觉这个东西完全可以看作是一个人的“小名”,只是对同一个变量多了一个称呼而已,指向的数据和地址是和原变量完全一致的,并且用&进行取地址操作的得到的地址和原变量的地址是完全一致的(因而在对指针进行赋值的时候如果直接对指针地址操作则需要对变量或者别名使用&进行取地址运算,如果要直接赋值则需要使用*p=进行赋值)。最复杂的就是指针了,同样个人认为指针到头来就是一个地址,这样可能会比较好理解一些。例如*pointer,那么带有*(解引用操作符)的时候则是表示的数值,如果没有*则表示的是地址。也就是说可以将pointer看成一个内存地址在这个地址中保存的是另外一个数据的地址,当存在*的时候表示取该地址存取的内容,否则则是取这个变量保存的地址。指针的指针则就更加复杂了,例如**p,那么可以看作指针保存的数据是另外的一个指针,解引用操作一次将会得到一个*p,这仍然是个指针,当进行二次解引用操作的时候(**p)才能读到p中保存的数据信息。这么说可能比较难理解,那么看个实例就明白了。效果如下图:



程序的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
 
using namespace std;
 
int main()
{
    int ivalA=10;   //普通变量
    int ivalB=20;   //普通变量
    int *ppiA=NULL; //指针
    int *ppiB=NULL; //指针
    int **ppi=NULL; //指针的指针
    int &nameA=ivalA;   //别名
    int &nameB=ivalB;   //别名
    ppiA=&ivalA;    //指针赋值
    ppiB=&ivalB;    //指针赋值
    ppi=&ppiA;      //指针的指针赋值
    cout< <"变量、别名、指针和指针的指针的关系:"<<endl;
    cout<<"=================================   "<<endl;
    cout<<"名称       "<<"数值       "<<"地址     "<<"地址的地址"<<endl;
    cout<<"------------------------------------------------------"<<endl;
    cout<<"ivalA:      "<<ivalA<<"     "<<&ivalA<<endl;
    cout<<"ivalB:      "<<ivalB<<"     "<<&ivalB<<endl;
    cout<<"&nameA:     "<<nameA<<"     "<<&nameA<<endl;
    cout<<"&nameB:     "<<nameB<<"     "<<&nameB<<endl;
    cout<<"*ppiA       "<<*ppiA<<"     "<<ppiA<<"    "<<&ppiA<<endl;//输出的最后一个数据为指针自身的地址
    cout<<"*ppiB       "<<*ppiB<<"     "<<ppiB<<"    "<<&ppiB<<endl;//输出的最后一个数据为指针自身的地址
    cout<<"**ppi       "<<**ppi<<"     "<<ppi<<"    "<<*ppi<<endl;
    //ppi中保存的地址是*ppi(ppiA)的地址,*ppi(ppiA)中保存的地址是保存的数据的最终地址。
    //因而打印出来的数值*ppi和ppiA保存的数据的地址是一样的,事实上两者指向的是同一个地址。
    cout<<"---------------------别名操作-------------------------"<<endl;
    nameA=nameB;    //使用别名进行赋值
    cout<<"ivalA:      "<<ivalA<<"     "<<&ivalA<<endl;
    cout<<"ivalB:      "<<ivalB<<"     "<<&ivalB<<endl;
    cout<<"&nameA:     "<<nameA<<"     "<<&nameA<<endl;
    cout<<"&nameB:     "<<nameB<<"     "<<&nameB<<endl;
    cout<<"*ppiA       "<<*ppiA<<"     "<<ppiA<<"    "<<&ppiA<<endl;//输出的最后一个数据为指针自身的地址
    cout<<"*ppiB       "<<*ppiB<<"     "<<ppiB<<"    "<<&ppiB<<endl;//输出的最后一个数据为指针自身的地址
    cout<<"**ppi       "<<**ppi<<"     "<<ppi<<"    "<<*ppi<<endl;
    cout<<"---------------------指针操作   ---------------------"<<endl;
    ivalA = 10;     //恢复变量的初始值
    ivalB = 20;
    ppiA=ppiB;      //使用指针进行赋值
    cout<<"ivalA:      "<<ivalA<<"     "<<&ivalA<<endl;
    cout<<"ivalB:      "<<ivalB<<"     "<<&ivalB<<endl;
    cout<<"&nameA:     "<<nameA<<"     "<<&nameA<<endl;
    cout<<"&nameB:     "<<nameB<<"     "<<&nameB<<endl;
    cout<<"*ppiA       "<<*ppiA<<"     "<<ppiA<<"    "<<&ppiA<<endl;//输出的最后一个数据为指针自身的地址
    cout<<"*ppiB       "<<*ppiB<<"     "<<ppiB<<"    "<<&ppiB<<endl;//输出的最后一个数据为指针自身的地址
    cout<<"**ppi       "<<**ppi<<"     "<<ppi<<"    "<<*ppi<<endl;
    cout<<"------------------------------------------------------"<<endl;
    cout<<"指针操作:数值不变,地址变;别名操作:地址不变,数值变。"<<endl;
    //通过这里可以验证上面的关于地址的猜测,在这里虽然没有对**ppi进行修改,但是由于指向的地址
    //和ppiA是一样的,因而数值也随之发生了变化。
    return 0;
}

原创文章,转载请注明: 转载自 obaby@mars

本文标题: 《关于变量、指针、别名(引用)和指针的指针》

本文链接地址: http://www.h4ck.org.cn/2010/11/pointer/

You may also like

3条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注