👑个人主页:啊Q闻
🎇收录专栏:《C语言》
🎉道阻且长,行则将至
前言
指针的学习是C语言中的一个重要部分,学会指针在很大程度上就是学会了C语言,学好指针也为我们后续的学习奠定了基础,这篇博客先分享一部分,后续博客还会有更多的指针知识
指针详解2主要是关于指针与数组的知识【C语言】指针详解2-优快云博客有需要的家人们可以去看看
一.初识指针
1.指针定义
计算机CPU处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放入内存中。那些内存空间是如何管理呢?
其实,内存管理就是把内存划分为一个个内存单元,每个内存单元的大小取一个字节,为了方便CPU查找,每个内存单元也有一个编号,在计算机中,我们把内存单元的编号称为地址,C语言中给地址取了个新名字叫指针。
2.内存中存储及相关符号
我们发现:
1.整型变量占用4个字节,每个字节都会占用一个地址 ,然而打印时后只打印第一个字节地址,但是当我们知道第一个字节时,就可以顺着地址访问到四个字节的数据。
2.我们通常用%p打印地址,用&取出地址,&称为取地址操作符。
3. * 为解引用操作符,它用于通过地址找到地址指向的对象
3.指针变量的大小
指针变量的大小取决于地址的大小,与指针变量的类型无关
32位平台下地址是32个比特位,即为4个字节。
64位平台下地址是64个比特位,即为8个字节。
4.指针变量类型的意义
指针变量的类型与其大小无关,那么指针变量的类型意义何在呢?
1.解引用权限
其实指针变量的类型决定了对指针解引用是有多大权限,也就是决定一次能操作几个字节。
如:
char*的指针解引用时候只能访问一个字节
int*的指针解引用时候可以访问四个字节
double*的指针解引用的时候可以访问八个字节
如图,char*解引用时只能改变一个字节
int*解引用时能改变四个字节:
2.访问距离
指针的类型决定了指针向前或者向后走一步的距离
5.特殊的指针void*
void*是指针类型中特殊的一种,它可以理解为无具体类型的指针(或者叫做泛指指针),这种指针可以用来接受任意类型地址。
但是,void*的指针不能直接进行指针的加减整数和解引用运算。
void*的用处在于:
正是因为void*为泛指指针,所以当我们写程序时不确定变量的类型的时候,可以用void*
6.const修饰指针
当指针被const修饰时,其便不可以被随意修改。
虽然const不可以修改这个限制变量,然而其可以绕过变量,去通过修改变量地址达到修改变量的目的
如下代码就是通过n的地址达到修改n的值的目的:
进一步探索:
const如果放在*左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针改变,但是指针变量的本身可以修改
const如果放在*右边,修饰的是指针变量本身,保证指针变量的内容不能被修改,但是其指向的内容可以修改
二.指针运算
1.指针运算的分类
指针运算分为:
1.指针加减整数 ,2.指针减指针
2.指针加减整数
数组中的内存是连续存放的,所以当我们知道首元素地址的时候就可以顺藤摸瓜找到后面所有元素。
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = &arr[0];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));//该处为指针加减整数
}
return 0;
}
详解:
(p+i)是在指针上加减,即是在地址上加减。因为p为int*型,所以其一次可以向后走4个字节
*(p+i)是对指针的解引用,找到地址所指向的值。
3.指针减指针
在两个指针指向同一个空间即类型相同时,指针减指针得到结果的绝对值是指针和指针之间的元素个数。
#include<stdio.h>
void MyStrlen(char* s)
{
char* p = s;
int ret = 0;
while (*p != 0)
{
p++;
}
ret = p - s;//1.该处为指针减指针
printf("%d\n", ret);
}
int main()
{
char arr[4] = "abc";
MyStrlen(arr);
return 0;
}
详解1:将首元素备一份在p中,然后用p去向后走,这样就保留了数组的首元素地址。p-s为指针减指针,此时的已经走完了最后一个元素。
三.指针使用不当
1.野指针概念
野指针就是指针指向的位置是不可知的,随机的,不正确的,没有明确限制的
2.野指针成因
1.指针未初始化
解决方法:
指针创造后,如果明确知道指针应该指向哪里,就直接赋值。如果不知道指针指向哪里,可以给指针置空(即赋值NULL)。
2.指针越界访问
解决方法:
申请了多少空间就是用多少空间,不要超出范围访问
3. 指针指向的空间释放
如以上代码所示:n的地址返回给p,其空间出了函数后就会被释放,被释放后的空间会被归还给系统,所以再通过该地址去访问时,就无法找到n的值了。
解决方法:
为了避免上述情况,我们不要返回局部变量的地址
4.此外
当指针变量不使用时,即使置空。要使用时候,要检查其有效性。
assert断言的头文件为assert.h
assert()断言 接收一个表达式作为参数,表达式为真,程序正常运行。表达式为假,会报错。
这只是指针的一部分,接下来的知识我们放在下一篇博客中分享。感谢阅读,如果对你有帮助的话,给个三连吧😘