指针全面复习

来到了我认为c语言中最乱的地方了:指针,很多人都有说指针就是c语言的灵魂,没有指针c语言基本没有存在的意义,事实也确实如此,废话少说开始理清指针把。

首先我们要区分好俩个概念,第一个是“指针和“指针变量”。指针是一个地址,而指针变量是一个存储地址的一个变量。Eg:变量i的指针是1000,但是不能说变量i的指针变量是1000。

其实我们说指针指针,其实指针是一种类型,只不过它是派生的不能单独存在,也就是说实际上存在的是“指向int的指针类型”‘…。所以有了指针类型就延申出刚刚我们所说的指针(指针类型的值),指针变量(指针类型的变量)

那我们先讲述什么是指针变量:

  1. 定义:类型名*变量名;(类型名与*之间的括号是一定要存在的,不然在同时定义其它变量的时候不然分别指针与其他变量)

可能有朋友要说了,既然是存储地址为何要有类型名的存在呢?我能说的是这个类型名是必不可少的,因为不同类型的指针变量的存储方式和所占用的字节数是不同的,并且

后面我们要学习计算指针变量移动的时候内存地址所移动的大小。

2,指针所触及的运算符:&是地址运算符:对变量使用&运算符,可以获取该变量的地址,这个地址称为指向该变量的指针(是指针哦,不是指针变量!!!再复述一下),*是间接运算符:对指针使用*运算符,可以表示该指针指向的变量(就是直接对变量进行操作了)。

3.指针的初始化:这里特别的重要,并且一定要分清楚,首先,指针变量只有在初始化的时候引用*才是进行指向的改变,如果出了初始化的时候出现了*就是要看作是那个变量的数值了!!!

4.引用指针变量:(1).给指针变量赋值,p=&a;(这里就不是初始化,所以对其改变指向的时候不能有*)。(2)引用指针变量指向的变量,假设有了这个表达式“p=&a”,所以我们在最后想要直接引用到变量值就要有*:printf(“%o”,*p);

5.在这里插入指针为什么出现了,首先我们学过了函数在返回值的时候只能返回一个,但是世界上问题如此之多,不可能都是刚好都是只返回一个数值,因此引入指针进行直接对实参的操作(这里也就是传地址操作,我们之前所学的就是传值操作,传值操作是单方向的必须要有返回值来返回数值,后面再细说)。

所以我们将指针变量作为函数参数进行操作,我们先来看一个程序。

就像上面代码所示,我们间接的对主函数的参数进行了操作,这就是传地址操作,但是使用还得多做题,因为这里只是简单的情况,遇到复杂的可能会乱,也没事过段时间我那些整理出来。

其次,我们在传递指针变量之后,倘若我们在函数内是通过改变指针指向的话,是不会影响到原指针的指向的,我们上面是之间通过改变数值,会同时影响俩边,但是改变指向做不到。

(后面细说)

接下来我们就要将指针与数组之间的关系(这里真的会特别乱,但是这里有总结能帮你梳理别担心)

  1. 通过指针引用数组,首先所谓的数组元素的指针就是数组元素的地址,那我们得知道我们所说的数组名能指代数组的首位数组元素是什么情况,其实这个东西就是一个语法糖,其实(定义了一个数组a【】)int *p=a;与int *p=&a【0】是等价的不好混淆。那我们要怎么调动指针所指向数组中的哪个元素呢,便出现了再引用数组元素时指针的运算。

  1. 在引用数组元素时指针的运算:当我们指针已经指向了一个数组元素时,我们我可以对指针进行加减运算,a+1,a-1,a++,a—…,但是俩个指针之间的相减只有在同一个数组中才有作用。应该还记得前面我们所说的为什么要对指针变量进行类型名的赋予吧,就是在这里使用,我们每前进一个数组的位置,地址的值就有加一个类型的字节数,也就是int 加4,char加1…。

  1. 通过指针引用数组元素这里大家就很多时候看到一个题怎么数组和指针乱用,都不知道为什么这个能看出数组,哪个又是指针的,总结一句话(除了初始化数组和size of的计算,一律当中数组来看)因此就有这种形式:a【i】=*(a+i),其实和前面一样都是语法糖,但是要记住,如果只是数组名就是数组的初始地址。

  1. 用数组名作为函数参数

简单来说这一部分就是想说数组作为函数形参的时候就是一个指针,并且数组不管以什么形式作为形参都是指向首元素地址的(eg:a【10000】就算这样写,系统也只会认为是首元素地址),并且重要的是*(a+i)是等价a【i】(其实基本只要不是初始化,sizeof,和作为函数形参的特殊情况都直接看成指针就好)。

那么指针可以引用一维数组那又为何不能引用多维数组呢,毕竟多维数组不也就是数组的数组嘛,所以我们来说指针与多维数组的关系。

通过指针引用多维数组

如果忘记了二维数组的定义以及怎么看成数组的数组的方式就翻翻前面数组复习的博文。

首先我们先定义一个二维数组看看形式:int a【2】【3】={{1,2,3}{3,4,5}},这里就是看作定义成了俩个有三个参数的一维数组,那我们普通的以为数组可以将其看为指针,那数组的数组又有何不行呢,a【i】=*(a+i)这是一维数组看成指针的方式,那么数组的数组呢,其实也一样你把他看成俩个数组的组合就可以,*a【i】【j】=*(a【i】+j),先将外面那层看成指针后,再看内层所以*(*(a+i)+j)就是数组的数组的看法还是那

  1. 句话<只要不是初始化,sizeof,作为函数形参的特殊情况(虽然也是看成指针,但是只能指向首元素),一律将数组看成指针>

  1. 计算a【i】【j】的相对a【0】【0】位置:计算公式是i*m+j,(一个int n*m大小的的数组,3*4)eg :a【2】【3】的相对位置是2*4+3=11的偏移量,然后乘上数组类型名也算出偏移的字节数,也是就11*4=44,所以如果刚开始数组的指向是a【0】【0】就可以直接&a【0】【0】+11就算a【2】【3】的地址了。如果起初是在a【1】【1】就变成(i-1)*m+(j-1)

讲了那么久也终于要进入指针与字符数组的关系。

指针与字符数组的关系

  1. 字符串的引用方式:

其实理解了前面的这里就很简单啦,也一样字符数组也看成指针,但是需要注意的是一个字符指针如果存放的是一个字符串是指向第一个元素的(毕竟基类型还是char不是字符串所以依旧得看成是一个字符,除非在输出的时候使用的%s可以输出整条字符串),我们依旧可以通过进行加减来选择哪个字符。

  1. 字符指针作为函数参数

有这样的对应关系,写程序的时候就是这样使用的

实参 形参 实参 形参

字符数组名 字符数组名 字符指针变量 字符指针变量

字符数组名 字符指针变量 字符指针变量 字符数组名

  1. 使用字符指针变量和字符数组的比较

(1).可以对字符指针变量赋值,但是不能对数组名赋值。

(2).指针变量的值是可以改变的,而字符数组名代表了一个固定的值(数组首元素的地址,就是说数组没法通过像指针一样用加减来改变指向的值)不能改变。

(3).字符数组中个元素的值是可以改变的(可以对它们赋值),但字符指针变量指向的字符串常量中的内容是不可以被替代的(不能对他们赋值)eg:char a【】=“house”

Char *b=“house”;a【2】=‘r’,b【2】=‘r’;(所以指针b的赋值是不合法的,只有字符数组能这样修改)

现在我们来到指针与函数之间的关系

指向函数的指针

  1. 定义 类型名(*指针变量名)(函数参数表列);

  1. 用法,其实就是通过你所定义的函数指针它可以指向函数类型为你所定义的类型名且有你所定义的参数表列的个数的函数就是用于指向函数的。

  1. 指向函数的指针作为函数参数:就是指向函数的指针变量的一个重要用途是吧函数的入口地址作为参数传递到其他函数

现在讲最后的指针数组和多重指针

  1. 什么是指针数组,就是一个存放指针的数组一般的形式为 类型名*数组名【数组长度】

  1. 什么是多重指针,就是指针的指针就是存放一个指针变量的指针变量,一般形式二重指针**a

我们总结一下指针有的形式,不要搞混

int hoge; hoge是int

int hoge [10][3] hoge是int的数组的数组

int hoge[10] hoge是interesting的数组

int *hoge[10] hoge是指向interesting的指针的数组

double (*hoge)[3] hoge是指向double数组的指针

int func (int a) func是返回int的函数

int (*func-p)(int a) func-p是指向返回int的函数的指针

后面这些比较少见讲解比较少,但是做题还是有很多的,等之后我们通过做题来深入了解他们,现在我们先知道它的一些相关概念即可。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值