目录
一:什么是指针
1、c语言指针其实是一个整形变量,与其它数据不同的是,它的作用是用来存储其它变量的地址。指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(pointsto)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。
2、因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。
3、再打个比方:有个人让你去麦当劳帮我买个雪糕,那么麦当劳是这个变量a,但是那个人现在把麦当劳所在的地址写在纸上给你,那么这张纸就可以看做一个指向麦当劳的指针。
其中pa称为指针变量,int * 称为指针类型,。
二:指针的大小是多少,指针的类型有什么用
这里可以看出,不管是什么类型的指针,他的大小都是4个字节。
那么为什么是四个字节呢,既然大小都一样,为什么还要给他类型呢?
1.为什么指针的大小是4个字节。
可以理解为电脑的内存是由地址线来决定的,32位机器有32根地址线,64位机器有64根地址线。
当地址线通电之后,会产生0 / 1的电信号,32根地址线就产生了00000000000000000000000000000000到
1111111111111111111111111111111111111的地址,
指针既然存放的是地址,那么他也就应该有32个比特位,也就是4个字节;
64位的就是64个比特位,就是8个字节。
2.为什么还要给指针类型。
我们创建一个整型变量a,初始化为16进制的0x11223344;
然后把a的地址存入整型指针变量pa;
再通过解引用找到a的地址将a改为0;
同理我们再来看一下char *的效果:
这里可以看见char*只改变了一个字节的值。
我们让char * 和int * 分别向后移动一位,可以看出int * 移动了4位, char * 只移动了1位,所以指
针类型的不同会导致指针+1后移动的字节也不同。
所以我们可以得出一些结论,其实指针类型是有意义的。
- 指针类型决定了指针进行解引用操作的时候,一次性访问几个字节
- char*访问一个字节
- int*访问4个字节
- float*访问4个字节(float类型会把4个字节的数据改为浮点型数据)
- int * 指针+1跳过4个字节
- char * 指针+1跳过1个字节
三:野指针
1.野指针的概念
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。
2.产生的原因
①:指针未初始化。 例:
通俗来说可以这样理解。某天晚上喝多了,想找个地方睡觉,找了个酒店房间什么招呼也没打,就
说这个房间是我的,我要在这睡,很明显是一种非法行为。
②:指针越界访问。 例:
从上面可以看出,越界访问后多出来了一个值。
③:指针指向的空间释放。 例:
3.如何规避野指针
①:给指针初始化。
②:控制好指针的访问范围,小心指针越界。
③指针指向空间释放,及时置NULL(空指针)。
④:避免返回局部变量的的地址。
⑤:指针使用时检查有效性。
四:指针运算。
1.指针加减整数。
就是说指针指向的类型是什么,+ N就是跳过N * 这个类型的字节大小,同理 - - 一样。
2.指针 - 指针
要注意,指针 - 指针前提是这两个指针要指向同一块空间,比如说你的一个指针指向arr1,另一个
指向arr2这样就不行。
数组arr一一共五个元素,+ 5 就指向了数组后面的地址,我们并没有访问,所以不是野指针。
3.指针的关系运算。
标准规定:C语言标准规定:允许指向数组元素的指针和指向数组最后一个元素后面的那个内存位置
的指针进行比较,但是不允许与指向第一个元素之前的那个内存地址进行比较。
五:指针和数组
指针是用来存放地址的。
数组是同一类型元素的合集,他的数组名表示首元素地址,并且数组中元素的地址都是连续的。
那么我们可以把首元素的地址存到指针里面,然后通过首元素地址找到数组的所有元素。
pa表示首元素地址,加i就是跳过i个整型字节,*(pa+i)与arr[i]是一个意思。
六:二级指针
二级指针是什么?
指向指针的指针,称为二级指针,用于存放二级指针的变量称为二级指针变量.
比如:
这里pa是一级指针变量,类型是int *;
ppa存放的是一级指针pa的地址,所以ppa是二级指针变量。
七:指针数组
顾名思义,指针数组就是数组元素全是指针的集合。那么怎么表示呢
这是一个实例,是为了容易了解数组指针是什么,下面我们用数组指针来模拟一个二维数组。
如上图:
创建了四个数组,把数组名放入指针数组arr5(数组名表示数组首元素地址)
再用两层循环将每个数组中的元素打印出来。
其中*(arr5[i] + j) 等价与arr5 [i] [j]。
还可以写成: