复习指针(15)
- 针对自己的复习资料
- 以后应该会修改,精进
文章目录
<1>二级指针
- 通俗的来说,就是存储(一级)指针变量的地址
- 以图来理解
<2>指针数组
- 本质就是存储指针的数组,可以进行类比,列如字符数组 是存放字符的数组
- 以图来理解
- arr1,arr2,arr3都是其数组首个元素的地址
注意:上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的
<3>字符指针变量
- 看段代码来深入理解一下
a.看看第一个if语句,为什么这样
1.在这里str1,str2<前面的是数组名>(一般都是这样,除sizeof)是指其数组首元素的地址(h的地址)
2.我们在创建char数组,str1[]与str2[]时,是向计算机申请2个空间,所以他们的地址不同,但是其内容都是字符串"hello world"
b.看到第二个if语句
1.首先我们先看const,它的修饰导致str3,4的指向(hello world)不能被改变,就是*str不能改变
2.字符指针只会就接收一个字符,就是h,也就是h的地址
3.str3,4赋的值是常量字符,我们在创建常量字符后,是可以反复使用的,不需要再申请空间,那么其地址就相同
注意:图片上的字,内容是不能用==比较的,要用strcmp函数
<4>数组指针变量
- 本质:就是指针,数组来修饰
- 指向数组的指针;存放的是数组的地址
- (*p)中个()是不能去的,会搞大乌龙!!!,含义变了,如int *p[10],p为数组名,int *为他的返回类型
- 以图来看
a.
1.指针的大小与int,char,数组等类型无关,只与系统有关,如64位系统就是8个字节
2.指针的解引用or步长的大小是不同,如int类站4个字节,于是p+1是走了4个字节
3.int (*)[10]是指针数组类型
含义:[10]这个指针指向是长度为10的数组,int 指数组元素类型是int 注意区分指针数组,区别在这(*)
b.
这张图是以指针的方式打印一个数组的内容
- (*p)就是* &arr
- (*p)[i]等价为arr[i] 又等价为*(arr+i),最后的等价其实计算机中c语言的规则,计算机再运行时会自动处理成这样的形式
所以 数组的本质回归到了指针
- *p找到数组,[i]就是下标访问
这是另一种方法达同样的效果
- &arr是数组的地址,但实际上int (*p)[10]取的只是其首元素的地址,这与数组各个元素的地址是连续存放有关,也与
解引用的语法规则有关
注意:基地址 + 偏移量 = 目标地址
<5>二维数组指针
- test(arr,3,5)中的arr传的其实是首元素地址,那么形参也可以写成数组指针
二维数组其实是一维数组的数组;二维数组的每个元素其实是一维数组
- 意思就是有个数组名为arr[0],arr[0] [i],这个i就是偏移量(将arr[0]转化为Arr[i]更好理解;)
- 就有点像三个一维数组
<6>函数指针变量
- 就是指针
- 存放的是函数的地址,指向的是函数
- (*p)中个()是不能去的,会搞大乌龙!!!,含义变了,如int *p[int x,int y],p为函数名,int *为他的返回类型
a.
- 类比数组指针的写法,相似!int (*p)[5],所以前面一样[]-->(里面参数的类型)
- p先和*结合,说明p是一个指针变量,然后指针指向的是一个大小为10个整型的数组,所以
p是一个指针,指向一个数组,叫数组指针
b.
(int ,int)与(int x,int y)没区别
c.
- 以后要得到函数的地址,&Add与Add都可以
d.
- 两者都可以的,c语言的语法规则
- pf是函数指针 在调用的时候自动被编译器当成*pf(函数本身)
- 所以函数的本质也可以是指针
e.
只仅仅解释这个函数
- 先看void (*)()这不就是函数指针类型吗
- 然后(类型) + 0,是不是将0转化其类型,如int类型的0(那就是就是 0 ) -->double类型( 那就是 (double) 0 强制转换 )
将0看着地址的感觉,就像int (*p)() = &arr, p是函数指针变量,p等价于&arr;就像int p = 8, p是整型变量,p等价于8
- 再然后,我们先化简,p==( void(*)() ) 0------> (*p)()
- 这不就是调用吗,(*p)()
那么0就是代表一个函数地址,*是去访问,然后这个函数不需要参数
- signal( int , void(*)(int) ),signal是函数名,这里是声名函数,因为没有实际的传参
- 一样简化,void (*p) (int), p是函数指针类型,那么signal的返回类型 是函数指针类型
- 看着很别扭 这样写一下(常规视角看的话): void (*)(int) signal( int , void(*)(int) )
- 就是定义
关键字typedef
- 是用来类型重命名的,可以将复杂的类型转成简单的自我命名的类型
- 函数指针和数组指针的命名稍微有点区别
将 void(*)(int) 类型重命名为 pfun_t ,就可以这样写
放在main外
然后效果
pfun_t signal(int, pfun_s)
#知识复习#
查看18道真题和解析