1.const修饰指针
在这之前我们还学过static修饰变量,那我们用const来修饰一下变量会有什么样的效果呢?
我们来看看:
我们可以看到编译器报错告诉我们a变成了一个不可修改的值,我们在变量前加上了const进行限制,但是我们就不能改变a的值了吗?其实不然,我们刚刚学过指针,我们试试用指针能不能将其修改。
演示如下:
int main()
{const int a = 10;int* pt = &a;*pt = 2;printf("%d", a);return 0;
}
我们来运行一下看看是不是改变了a的值。结果为:
虽然我们利用指针这个知识绕过a变量进行赋值的操作成功赋值 ,但是我们用const修饰变量就是让其固定,不想被修改,那我们可以怎样让指针也不能修改我们的a的值,其实我们也可以用const修饰指针这样就不能更改变量了。
演示如下:
此时我们用const修饰指针变量pt使其也成为一个不可修改的值,这样就不能通过指针变量来修改a了。但是const有几种修饰指针的情况,第一种就是上述的情况虽然我们限制*pt的值,但是我们可以改变pt的值,例如:
此时就没有报错,说明此时的pt并没有被限制,被限制的知识*pt。还有一种情况我们将const放在int 后如int const*pt,此时限制的也是*pt那我们怎么限制pt呢?
其实我们只需要在pt的前面加上const即可。
演示如下:
此时编译器再次报错。说明我们成功将pt的值进行了限制,如果我们想让*pt和pt都被限制只需要使用 两个const即可。例如const int *const pt即可。
2.指针的运算
1.指针的加减
1.指针加,我们来看一串代码
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10, };size_t sz = sizeof(arr) / sizeof(arr[0]);int* pt = &arr[0];for (int i = 0; i < sz; i++){printf("%d ", *(pt + i));}return 0;
}
上述代码我们用指针的来完成打印数组的每一个元素。能不能完成我们的任务呢?
我们通过指针的加i,每次都跳过一个整型。达到找到arr的每一个元素。
2.指针的减,我们也来看一串代码:
int main()
{int arr[] = { 1,2,3,4 };//我们将它的数子倒着打印出来int* pt = &arr[0];pt = pt + 3;for (int i = 0; i < 4; i++){printf("%d ", *(pt - i));}return 0;
}
我们利用指针的减i来找到元素的地址,并进行解引用操作。
2.指针减指针
我们之前学过strlen库函数我们今天来写一个自己的strlen函数:
演示如下:
int my_strlen( char *pt)
{char* pu = pt;while (*pt!='\0'){pt++;}return pt - pu;
}
int main()
{char arr[] = "abcdef";int ret=my_strlen(arr);printf("%d", ret);return 0;
}
其实一维数组的传参就是首元素的地址。
我们来运行一下能不能完成我们的任务:
3.野指针
概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
1.野指针成因
1.未初始化
#include <stdio.h>
int main()
{
int *p; //局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
2.指针越界访问
#include <stdio.h>
int main()
{int arr[10] = {0};int *p = &arr[0];int i = 0;for(i=0; i<=11; i++)
{//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;
}return 0;
}
3. 指针指向的空间释放
#include <stdio.h>
int* test()
{
int n = 100;
return &n;
}
int main()
{
int*p = test();
printf("%d\n", *p);
return 0;
}
2.如何避免野指针
1.指针初始化
如果明确知道指针指向哪⾥就直接赋值地址,如果不知道指针应该指向哪里,可以给指针赋值NULL。NULL 是C语言中定义的一个标识符常量,值是0,0也是地址,这个地址是无法使用的,读写该地址会报错。
2. 小心指针越界
一个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是越界访问。
3. 指针变量不再使用时,及时置NULL,指针使用之前检查有效性
当指针变量指向一块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的一个规则就是:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL。
我们可以把野指针想象成野狗,野狗放任不管是非常危险的,所以我们可以找一棵树把野狗拴起来,就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓前来,就是把野指针暂时管理起来。
不过野狗即使拴起来我们也要绕着走,不能去挑逗野狗,有点危险;对于指针也是,在使用之前,我们也要判断是否为NULL,看看是不是被拴起来起来的野狗,如果是不能直接使用,如果不是我们再去使用。