指针的深入了解2

1.const修饰指针

在这之前我们还学过static修饰变量,那我们用const来修饰一下变量会有什么样的效果呢?
我们来看看:

指针的深入了解2_第1张图片

我们可以看到编译器报错告诉我们a变成了一个不可修改的值,我们在变量前加上了const进行限制,但是我们就不能改变a的值了吗?其实不然,我们刚刚学过指针,我们试试用指针能不能将其修改。

演示如下:

int main()
{
	const int a = 10;
	int* pt = &a;
	*pt = 2;
	printf("%d", a);
	return 0;
}

 我们来运行一下看看是不是改变了a的值。结果为:

指针的深入了解2_第2张图片

虽然我们利用指针这个知识绕过a变量进行赋值的操作成功赋值 ,但是我们用const修饰变量就是让其固定,不想被修改,那我们可以怎样让指针也不能修改我们的a的值,其实我们也可以用const修饰指针这样就不能更改变量了。

演示如下:

指针的深入了解2_第3张图片

此时我们用const修饰指针变量pt使其也成为一个不可修改的值,这样就不能通过指针变量来修改a了。但是const有几种修饰指针的情况,第一种就是上述的情况虽然我们限制*pt的值,但是我们可以改变pt的值,例如:

指针的深入了解2_第4张图片

 此时就没有报错,说明此时的pt并没有被限制,被限制的知识*pt。还有一种情况我们将const放在int 后如int const*pt,此时限制的也是*pt那我们怎么限制pt呢?

其实我们只需要在pt的前面加上const即可。

演示如下:

指针的深入了解2_第5张图片

此时编译器再次报错。说明我们成功将pt的值进行了限制,如果我们想让*pt和pt都被限制只需要使用 两个const即可。例如const int *const pt即可。

指针的深入了解2_第6张图片

 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;
}

上述代码我们用指针的来完成打印数组的每一个元素。能不能完成我们的任务呢?

指针的深入了解2_第7张图片

 我们通过指针的加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;
}

其实一维数组的传参就是首元素的地址。

我们来运行一下能不能完成我们的任务:

指针的深入了解2_第8张图片

 3.野指针

概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

1.野指针成因
1.未初始化
#include 
int main()
{
int *p; //局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
2.指针越界访问
#include 
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 
int* test()
{
int n = 100;
return &n;
}
int main()
{
int*p = test();
printf("%d\n", *p);
return 0;
}
2.如何避免野指针
1.指针初始化

如果明确知道指针指向哪⾥就直接赋值地址,如果不知道指针应该指向哪里,可以给指针赋值NULLNULL 是C语言中定义的一个标识符常量,值是0,0也是地址,这个地址是无法使用的,读写该地址会报错。

2. 小心指针越界

一个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是越界访问。

3. 指针变量不再使用时,及时置NULL,指针使用之前检查有效性

当指针变量指向一块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的一个规则就是:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL。
我们可以把野指针想象成野狗,野狗放任不管是非常危险的,所以我们可以找一棵树把野狗拴起来,就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓前来,就是把野指针暂时管理起来。
不过野狗即使拴起来我们也要绕着走,不能去挑逗野狗,有点危险;对于指针也是,在使用之前,我们也要判断是否为NULL,看看是不是被拴起来起来的野狗,如果是不能直接使用,如果不是我们再去使用。

指针的深入了解2_第9张图片 谢谢

你可能感兴趣的:(c语言,开发语言)