我们接着上次没有讲完的指针继续讲哈(没看过的可以先看看深入理解指针1)
数组名的理解:
我们之前已经学过数组了,那么解释一下数组名,其实数组名就是首元素的地址。
我们举例说明:
我们发现数组名和数组⾸元素的地址打印出的结果⼀模⼀样,这就恰恰说明数组名就是首元素的地址。
但是,有两个例外:
1:sizeof(数组名):这里的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节
例:

结果40计算的是整个数组大小
2:&数组名:这里的数组名也表示整个数组,取出的是整个数组的地址
除这两个之外,数组名都是首元素的地址。
所以arr[i] 其实等价于*(arr+i)
一维数组传参的本质:
我们先举个例子:(在x86环境下:)
造成sz1 与 sz2结果不同的原因是什么呢?
因为数组名是数组⾸元素的地址,那么在数组传参的时候,传递的是数组名,也就是说本质上
数组传参传递的是数组⾸元素的地址。所以形参即使写成数组的形式,本质上也是一个指针变量。
同时,借助这个例子,我们发现:在函数内部是没办法求的数组元素个数的(这就提示我们,如果下一次要向函数里传入一个数组,常常还应该传入一个int 变量,这个变量传的是数组长度)
二级指针:
其实指针也有地址,取指针地址的指针,就叫二级指针;

指针数组:
指针数组是指存放指针的数组,数组的每个元素其实是指针类型;
例:
char* arr[5]:存放字符指针的数组
int* arr[6] :存放整型指针的数组
用指针数组模拟二维数组:

字符指针变量:
在指针的类型中我们知道有⼀种指针类型为字符指针 char* ,这个字符指针类型其实很特殊,
我们举个例子:

这里我们可能会想,这是把字符abcdefg放在pstr地址里了吗?
其实不是,本质上是把abcdefg这串字符串的首字符的地址放在了pstr中。
因此,使用%s打印字符串时,只需提供首字符的地址就行。
我们再举个有关字符指针十分经典的例子:

这是为什么呢?
这⾥str3和str4指向的是⼀个同⼀个常量字符串。
C/C++会把常量字符串存储到单独的⼀个内存区域,当几个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。
但是⽤相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。
我们再学习一个概念,叫:
数组指针变量:
跟其他指针变量相似,它也是一种指针,存放的是数组的地址,能够指向数组的指针变量。
例如:
int (*p)[10]
p先和*结合,说明p是⼀个指针变量,然后指针指向的是⼀个⼤⼩为10个整型的数组。所以p是
⼀个指针,指向⼀个数组,叫 数组指针。
注意:要注意区分int* p[10]与 int(*p)[10]的区别,如何才能不搞混呢?我是这样想的:

数组指针变量是⽤来存放数组地址的,那怎么获得数组的地址呢?就是我们之前学习的 &数组名
我们再讲一下⼆维数组传参的本质
二维数组传参的本质:
因为我们之前写向函数传二维数组的时候,一般是这样写的:
void test(int a[3][5], int r, int c)
我们知道,二维数组其实就是把几个一维数组再存放到一个数组中形成的数组,
⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀维数组的地址。
也就是说,
⼆维数组传参本质上也是传递了地址,传递的是第⼀行这个⼀维数组的地址

所以说:⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式。
ok,我们再讲讲函数指针变量
函数指针变量:
函数指针变量是一种指针,是⽤来存放函数地址的
其实函数也有地址,函数名就是函数的地址,当然也可以通过 &函数名的方式获得函数的地址。
我们直接举两个例子:
我们再讲一个东西:
typedef 关键字:
typedef 是⽤来类型重命名的,可以将复杂的类型,简单化,使代码更易读和管理。
其格式为:
typedef 原类型名 重命名后的新类型名
例如:
typedef unsigned int uint;
即把unsigned int 重命名为 uint
指针也可以进行这样的重命名,如:
将int* 重命名it
typedef int* it;
而函数指针和数组指针也是可以重命名的,只不过有稍微不同,具体方法为:
函数指针
例:
将int (*)(int,int) 重命名为p,则为:
typedef int(*p)(int,int);
这里的 p 就是定义函数指针的重命名,它指向的函数有两个int 类型的参数,返回值也是int型
那么重命名后该如何用呢?我们举例说明:

同样地,数组指针也是类似:
例如我们有数组指针类型 int(*)[5] ,需要重命名为 peaches,那可以这样写:
typedef int(*peaches)[5];
同理使用方法也大致相似:

函数指针数组:
把函数的地址存到⼀个数组中,那这个数组就叫函数指针数组,定义一个函数指针数组的一般形式为:
返回类型 (*数组名[数组大小]) (参数列表) 。
比如: int (*arr1[3])(int,int);
指的是名为arr1的函数指针数组,数组大小为3个指向函数的指针,这3个函数的形参都为int,int,而它们返回值都为int。
ok,指针的大部分内容都讲的差不多啦,(写的有点慢了,导致这篇发的有些晚ヘ( ´Д`)ノ)
感谢支持。