发布时间:2024-10-10 10:01
指针比较难!相较于其他知识,指针理解起来会更难!作者也是花了很多时间来理解指针,肝这篇文章也花了很久。话不多说我们一起进入指针的学习吧。
目录
1.初识指针
2.指针大小
3.指针类型
3.1 指针的加法
3.2 指针的解引用
4.野指针
野指针很重要!很多时候我们指针的错误都来自野指针。
4.1 指针未初始化
4.2 指针越界访问
4.3 指针指向的空间释放
4.4 如何规避野指针
5.指针运算
5.1 指针与整数的运算
5.2 指针减去指针
这里也可以用指针减去指针的方式来求字符串的长度,有兴趣的小伙伴可以试一试。
5.3 指针的关系运算
6.指针和数组
7.二级指针
8. 指针数组
通俗的讲:指针就是内存中一个地址。具体说下来,指针是内存中一个最小单元的编号。
但是平时我们口中所说的指针可不是地址,而是指针变量。这是一个变量,用来存放地址的变量。
这里的0xFFFFFFFF就是一个指针,指针就是地址。
我们可以通过&(取地址操作符)取出变量的内存地址,然后把这个地址存放到一个变量。中。这个变量就是指针变量。
我们在内存中开辟一片空间,叫做a变量。然后我们取出变量a的地址,存放到p中去。
p 的类型是 int* 。p就被成为指针变量。
指针的大小在 32 位平台是 4 个字节,在 64 位平台是 8 个字节。
这里具体来说比较复杂,大家可以自己去了解。总结下来就是:
指针的大小在 32 位平台是 4 个字节,在 64 位平台是 8 个字节。
char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。
但是打印出来貌似没有什么区别。这中间的区别是什么呢?
我们先初始化一个变量,再对其取地址,取出来的地址分别存到int和char类型中。再对其加上1。这代表跳过该地址到下一个地址去。
这个结果就十分显而易见了:char类型的指针+1是到相邻的地址,而int类型的指针+1则到4个字节外。
指针的类型决定了指针向前或者向后走一步有多大(距离)。
指针的类型决定了对指针解引用的时候能操作几个字节。
int* -->4个字节
char* -->>1个字节
野指针很重要!很多时候我们指针的错误都来自野指针。
#include
int main() { int *p;//局部变量指针未初始化,默认为随机值 *p = 20; return 0; } 可以看到这里是报错了的,说明这是指针未初始化。
在这里指针指向的范围超出了arr的范围,p就是野指针,越界访问了。
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置 NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性
指针加减注意指针的类型。
指针减去指针计算的其实是两个地址中间元素的个数。
只能是同一指针类型,在同一空间里(如同一个数组内)才能计算。
这里也可以用指针减去指针的方式来求字符串的长度,有兴趣的小伙伴可以试一试。
for(vp = &values[N_VALUES]; vp > &values[0];) { *--vp = 0; }
代码简化:
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--) { *vp = 0; }
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
C语言:数组(及冒泡排序)_m0_62319039的博客-CSDN博客_冒泡排序(数组)c语言
作者写过一篇关于数组的基础介绍。结论:数组名表示的是数组首元素的地址 。
p+i 其实计算的是数组 arr 下标为 i 的地址。这里可能比较难理解,理解的时候把p后面的+和数字当成一个整体,和前面是一样的意思。
指针变量也是一个变量,也有地址。指针存放的是别的变量的地址,那么存放指针的地址的变量就叫做二级指针。以此类推还有三级指针。
其实就是一个套娃的过程,一般二级指针再往上用的就比较少了。
指针数组其实很好理解,就是存放指针的数组。
int* arr[10] = {&a,&b,&c};
其他地方是没有初始化的空间。
至此,今天的内容就结束了。但是指针属于比较难理解的部分,有很多数组的内容和指针是紧密相连的。两者相互掺杂起来会比较难。 大家可以去找一些指针和数组的题目做一做,感受一下。共勉!