学习指针要明白指针是什么,指针就是地址,也可以说是一个编号
一.指针的使用
1.指针变量
前面学习的变量,有存放整数的小数的,而指针变量是存放地址的
通过&(取地址操作符)来存放地址
———————————————————————————————————————————
生活中你想找一个人,你可以直接找这个人,或者问他家去找他。
那指针就是你知道人家地址,但是如何去找这个人呢?
2. 解引用操作(*)
(1)解引用操作符访问地址值
计算机中通过解引用操作符来寻找地址中的值,那如何使用呢?
如果解引用可以取到地址中的值
printf打印出来的结果就是10
这是整形的解引用操作
a的类型是int
p的类型是int *(p存放a的地址)
*p的类型是int
整形,浮点型和字符型解引用类似,只是符号改变了
注意:解引用操作是对于指针变量的
———————————————————————————————————————————
(2)解引用改变地址值
如果解引用操作符只能访问地址的值,其实使用地址就有点多此一举了,
如果我想使用整形int,我直接使用int,再给一个变量,直接打印就好了
就看这个,我想使用a,打印a的值,正常我们就直接使用
用地址反而更麻烦了
———————————————————————————————————————————
再看下面如何改变地址值
原来使用直接a=20就可以了,这不仅需要找a的地址,还需要*p=20
所以引用指针有什么好处呢?
现在只能看出来很麻烦
确实这样麻烦,但是后面学习你会发现它的好处,适合于它的地方
3.指针变量大小
算指针变量的大小前大家需要了解一个关键字sizeof
(1)sizeof
测字节大小的,最后值为字节个数(无符号整形)
先看一下如何使用吧
在vs中int在内存中占4个字节
各种类型的字节数为下面
sizeof括号里面不进行计算!!!!!
sizeof括号里面不真实计算!!!
(2)指针变量的大小
上一篇讲到,内存,内存单位和地址(内存单元的编号)
x86环境下(32位平台) 内存单元为2^32个 编号2^32个转化字节就是4个
x64环境下(64位平台) 内存单元为2^64个 编号2^64个转化字节就是8个
指针变量指向的地址,地址的大小由平台决定
指针变量大小都相同,那指针变量大小有什么意义?
(3)指针变量的意义
指针变量的大小是相同的,但是指针变量指向的对象是不同的(指针存放地址类型不一样)
也就是说指针解引用之后的大小或者类型是不同的。所以导致产生不同的指针变量。
好处
使用指针变量的好处就是可以只用小的空间可以访问大的空间,因为指针变量的大小是根据平台的改变的
坏处
使用简单的整形加减使用指针比较麻烦
二.野指针
什么是野指针呢?
大家比较了解整形,我用整形来和大家解释
整形a如果我现在使用它他会报错,说使用未初始化的整形。(访问的整形是随机的)
(1)野指针成因
a.指针未初始化(也就是访问的地址是随机的)
b.指针越界访问(依旧是指针访问的地址不属于操作系统)
这个数组最多可以访问下标位4的数,最后访问下标为6,产生了越界访问。
(2)如何避免指针的越界访问
也就是指针初始化和避免指针越界。
使指针访问的地址有效。
三.const修饰的指针
(1)const修饰的*之前
这两种都可以表示const修饰*前,不可以使用解引用操作,也就是不能使用解引用来改变a的值
但是可以改变p的所指向的地址。
(2)const修饰的*之后
const修饰*之后,不可以改变指向的地址但是可以改变指向地址的值
(3)const修饰*两边的
既不可以改变指向的地址又不可以改变指向地址的值。
四.传值调用和传值调用
(1)传值调用
我们曾经学过整形的传值调用
但是传值调用的形参的改变不影响实参
也就是在函数add中a和b的改变不影响主函数中a和b的值
(2)传址调用
我曾经讲过数组传参,其实数组传参就是传址
传址调用也就是把实参地址传递形参,形参值改变,也就是实参指向的地址的值发生了改变,
所以传址调用可以改变原来地址所指向的值,而传值调用不可以改变主函数的值
而且传址调用不想改变原来地址的值我们还可以用const修饰,所以建议大家用传址调用。