一,字符指针
顾名思义:字符指针指的是一种指针类型为字符指针 char*;
char*可以是一个字符也可以是一个字符串,前者很好理解,让我们看看后者;
eg:char*p="abcdef";//实际上是将首元素的地址给了p,也就是说*p存的是a的地址,不是存的全部abcdef的地址;(可以把abcdef想象成一个数组)
eg:printf(“%d”,“abcdef”【3】);打印的其实是字母d,这条语句的意思是以%d的格式打印下标为3的元素d
让我们看一道相关的的面试题:
答案:第一个是str1 str2 are not same 第二个是str3和str4 are same(大家可以暂停一下看看是为什么呢?可以复制代码块然后到编译器执行一下,这样也有利于帮助大家理解)
解析:当创建str1【】的时候,栈开启了一块空间,当创建str2【】的时候,又开辟了一块空间,这两块空间的地址是不一样的,所以打印的是not same;当创建str3的时候,前面const修饰*p,所以是一个常量字符串无法被修改,既然无法被修改,那就不需要开辟多块空间了,str3和str4指针变量都指向这块空间,所以是are same;
想必大家都应该明白了,让我们再来想一想,如果if是&str3==&str4呢,会打印出什么结果?
这时候,str3和str4都是指针变量,如果取地址的话,就是取出了指针变量的地址,这两者的地址当然是不相同了,所以会打印are not same
二,指针数组
那我们的指针数组如何使用呢?-------------可以用指针数组模拟一个二维数组
eg:下面的代码就是用数组指针模拟实现一个二维数组
让我们再来理解一下指针数组
我们在前面提到,字符数组可以找到字符串的首元素的地址,但是我们想要得到字符串,所以我们用%s的格式打印就可以得到每个数组的字符串了
三,数组指针
如果p+1,那就是跳过了以1个字节大小的5个元素,即跳过5个地址
如果p+1,那就是跳过了以4个字节为大小的10个元素,即跳过40个地址
数组指针的作用是什么呢?让我们举个例子看一下
首先,我们先回顾一下一维数组的打印:
让我们看一下数组指针的作用:
大家可以对比一下,发现上图右半部分的形参用的是数组指针的形式,当 *p解引用的时候,指向的是首元素的地址,这个首元素是第1行的一维数组的地址,*(p+i)其实就是跳过4个字节的5个元素,这时,p【i】【j】就是指的是每一行中的每个元素,
让我们看一下几个语句的含义:
让我们看一下第四个语句的含义(图解)):
四,一维数组传参
void test2(int **arr):也是可以的,是因为在主函数中,int*arr2【20】={0}其实是传的一级指针,如果想要得到一级指针的地址,用int**类型
那当一个函数的参数为一个一级指针的时候,函数能接受什么样的参数?
五,二维数组传参:
二维数组传参要么都是指针要么都是数组,数组是二维数组(列不可以没有),指针必须得是数组指针
那当一个函数的参数为一个二级指针的时候,函数能接受什么样的参数?
我们可以发现,test(&p);test(pp);test(arr);三种方式均可以传参
五,函数指针
让我们看一下例题:
例题1
例题2 :
解析:
好啦,我们的指针进阶第一部分就讲解到这里了,谢谢大家~