指针是学习C\C++的一个重难点,同时也是这个语言的关键知识点。如果不能够对指针有着深刻的理解,会对学习C\C++有着极大的阻碍。
普通变量和指针变量的区别
  普通变量和指针变量都同为变量。对于一个变量来说,都具有值和地址两个属性。假设一个普通变量a = 5,其值为5,&a为变量a在内存占有的地址。此时定义一个指针变量,并将a的地址赋值给该指针变量,int *p = &a,此时p指向a的地址空间,即p的值为a的地址,*p为p指向a的地址空间的内容,此时*p = 5。而&p为指针p所在内存空间的地址,需要注意的是,虽然p指向a,但两者在同一内存所占有的地址并不相同。
可见如下代码:
1 //定义普通变量a和指针变量p
2 int main(){
3     int a = 5;
4     int* p = &a;
5     printf("a = %d,&a = %d\n",a,&a);
6     printf("p = %d,*p = %d,&p = %d\n",p,*p,&p);
7 
8     return 0;
9 }
运算结果如下:
C/C++基础知识——对指针的理解

多级指针
可先看如下代码:
 1     int a = 10;
 2     int* p = &a;    //一级指针
 3     printf("a = %d, &a = %d\n", a, &a);        //a的值,a的地址
 4     printf("p = %d\n", p);        //p等价于&a
 5     printf("*p = %d\n", *p);    //*p等价于a
 6         
 7     int** q = &p;    //二级指针
 8     printf("q = %d\n", q);        //q是指针q的地址
 9     printf("*q = %d\n", *q);    //*q等价于p
10     printf("**q = %d\n", **q);    //**q等价于*p等价于a
11 
12     int*** t = &q;    //三级指针
13     printf("t = %d\n", t);        //t是指针t的指针
14     printf("*t = %d\n", *t);    //*t等价于q
15     printf("**t = %d\n", **t);    //**t等价于*q等价于p
16     printf("***t = %d\n", ***t);    //***t等价于**q等价于*p等价于a
运算结果如下:
C/C++基础知识——对指针的理解

  看到这,想必对于任何一名C语言初学者来说,都会感到十分的疑惑——仅仅只是对“*”这么一个符号的增增减减,却能够得到不一样的结果。那么在不使用计算机的情况下,我们到底该怎么区分一级指针、二级指针甚至是多级指针呢?在这里我们就得引入一个非常重要的概念——内存。
内存
  内存是计算机组成中,用来暂存程序和数据,辅助CPU运算的一个重要的部分,可以说内存是CPU与硬盘沟通的桥梁。它能够暂存CPU的运算数据,也可以暂存与硬盘等外部设备交换的数据。在下图中,我们可以很清楚的看到,内存在整个计算机系统中起到的关键性的作用(主存储器指内存)。
C/C++基础知识——对指针的理解

  申明任何一个变量,都会在已分配的内存中,开辟出一块空间,根据不同的变量类型,开辟出的空间大小和形式是不一样的,比如说int型的变量,会在内存中开辟出一个4个字节的空间,char型的变量,会在内存中开辟出一个1个字节的空间;而对于申明一个整型数组,如int a[10],则会在内存中开辟出一块4*10个字节且连续的空间。对于指针变量,它会指向变量对应的地址,那么这个地址到底该如何规定,这就得引入另一个概念——内存地址
内存地址
  计算机会对内存的每一个字节分配一个32位或64位的编号,(这与32位或者64位处理器相关),这些内存编号我们称之为内存地址。对于初学者,我们可以将内存抽象成一个很大的一维字符数组,每个单元都有其唯一的ID,这个ID就可以理解为内存地址。可见下图。
C/C++基础知识——对指针的理解

  下面回归到多级指针,在了解到上述知识后,可对多级指针有了一个大致的理解。我们将申明的多个变量抽象到下图中。
C/C++基础知识——对指针的理解

  指针变量t的值是它在内存的相对地址,*t 等价于q,**t 等价于p,***t 等价于a,同理,指针变量q的值是它在内存的相对地址,*q 等价于p,**q等价于a。通过这种方式,我们可以很清晰明了地理解多级指针。

发表回复