字符指针:
在之前我们的学习过程中,我们提到过怎么理解指针变量,举了一个int类型指针的例子,那我们可以通过这样的一个例子来写出字符指针
当然,我们的字符指针可以指向单个字符,也可以指向字符数组的。
后面的这个写法是把abcdef放到pc2里面去的吗?
其实不是,这个只是把首字符(a)的地址放在了pc2里面。
那他们可以进行解引用吗?
通过上诉的代码,我们可以得出,字符数粗是可以对其进行解引用修改的,但是常量字符串无法对其进行解引用修改。
下面我们看一个比较有意思的代码,他的结果是什么呢?
我们通过调试得出
为什么str3和str4是指向的同一块地址呢?,首先,我们知道常量字符串无法被修改,所以在内存中没有必要保存两份,他们公用一份就可以了。在C/C++中会把常量字符串存储到单独的一个内存区域,当几个指针指向同一个字符串时,他们实际会指向同一块内存。
数组指针:
在我们之前的学习中我们学到了指针数组,指针数组时一种数组,数组中存放的是指针(地址)。
那么数组指针是指针变量还是数组呢,答案是指针变量。
我们已经熟悉:
整型指针变量:int* p,存放的是整型变量的地址,能够指向整型数据的指针。
浮点型指针变量:float* p,存放浮点型变量的地址,能够指向浮点型数据的指针。
那么
数组指针变量:存放的应该是数组的地址,能够指向数组的指针变量。
那么下面这两个那个是数组指针变量呢?
p1是指针数组,p2才是数组指针变量。
我们要知道[]的优先级是高于*号的,所以p1先和[]结合,p1就是一个数组名,数组中的每个元素都是int*,所以p1是指针数组。
这里加上了一个p2在括号里面,先和*结合,说明p2是指针变量,指向的是整型数组,数组的每个元素都是整型。所以叫数组指针。
数组指针的初始化:
那我们知道了什么是数组指针,那它是怎么初始化的呢?
如果我们要存放数组的地址,就需要把他存放在数组指针中。
那么我们要怎么理解这个int(*p)[5] = &arr呢?
我们通过画图
二维数组传参的本质:
之前我们想要将二维数组传递给函数是这样写的
这里的实参是二维数组,形参也写成二维数组的形式。
我们可以这样理解一下二维数组,我们可以把二维数组的每一行都看成是一个一维数组。
根据数组名是首元素地址的规则,二维数组的数组名表示的就是第一行的地址,那么第一行的一维数组的类型就是int[5];第一行的地址写成数组指针类型就是int(*)[5],那么就意味着二维数组传参本质上也是传递了地址,传递的是第一行这个一位数组的地址。
那么我们转换成代码来实现一下
配合上画图
函数指针变量:
我们学习了整型指针,浮点型指针,数组指针,通过类比。我们可以得出下面的结论:
函数指针变量应该是用来存放函数地址的,将来通过地址调用这个函数。
那函数有没有地址呢
通过代码发现,函数是有地址的。
而且还发现函数名就是函数的地址。
那我们要把这个地址储存起来,就需要用到函数指针变量了。其实函数指针变量和数组指针变量的写法非常类似。
那怎么理解呢,我们还是画图
函数变量指针的使用:
代码如下:
函数指针数组:
数组是存放同一类型数据的存储空间,我们前面有学过指针数组
那么我们要把函数的地址存在一个数组中,这个数组就是函数指针数组,
这里parr1先和[]结合,说明parr1是数组,数组的内容是int(*)()类型的函数指针
代码如上。