指针

1.野指针

野指针是指针指向的位置是不可知的(随机的,不正确的,没有限制的)。

原因:

(1)指针未初始化

#include <stdio.h>
int main() {
int a; // 局部变量不初始化,默认是随机值
int* p; // 局部指针变量不初始化,默认也是随机值
*p = 100;
printf("%d", *p);
return 0;
}

(2)指针越界访问

#include <stdio.h>
int main() {
	int arr[5] = { 0 };
	int* p = arr;
	for (int i = 0; i < 8; i++) {
		// 当指针指向的范围超出数组arr的范围时,p就是野指针。
		p++;
	}
	return 0;
}

(3)指针指向的空间释放

int* test() {
int arr[10] = { 0 };
return arr;
}
int main() {
int* p = test();
printf("%d\n", *(p+1));
}

如何规避?

① 指针初始化, int* p = NULL

② 小心指针越界

③ 指针指向空间释放,及时置空

④ 指针使用之前检查有效性

2.指针的计算

(1)指针+-整数

#include <stdio.h>
int main() {
	int arr[5] = { 10,12,18,92,64 };
	int* p = arr;
	int size = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < size; i++) {
		/*printf("%d\n",*(arr+i));*/
		printf("%-4d", *p);
		p = p + 1;// p++
	}
}

(2)指针-指针

#include <stdio.h>
int main() {
	int arr[5] = { 13,34,21,38,49 };
	int res = &arr[4] - &arr[0];
	printf("%d\n", res);
	return 0;
}

(3)指针的关系运算

#include <stdio.h>
int main() {
	float values[5] = { -1 };
	float* vp;
	for (vp = &values[5]; vp > &values[0];) {
		*--vp = 0;
	}
	return 0;
}

标准规定: 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一 个元素之前的那个内存位置的指针进行比较。

3.指针和数组

#include <stdio.h>
int main() {
	int arr[] = { 1,2,3,4,5,6,7 };
	int* p = arr; // p存放的是数组首元素的地址
	int size = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < size; i++) {
		printf("&arr[%d]=%p <-----> p+%d = %p\n", i, &arr[i], i, p + i);
	}
}

p+i 其实就是数组arr下标为i的地址,因此可以通过指针来访问数组。

!!例外:

&数组名中,数组名不是首元素的地址,数组名表示整个数组,&数组名,取出的是整个数组的地址。

sizeof(数组名) 数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小。

4.二级指针

#include <stdio.h>
int main() {
	int a = 10;
	printf("&a=%p\n", &a);
	int* pa = &a;
	printf("&pa=%p\n", &pa);
	int** ppa = &pa; // 二级指针
	printf("&ppa=%p\n", &ppa);
	return 0;
}

对于二级指针的运算有:

*ppa通过对ppa地址进行解引用,找到pa的值

**ppa先通过*ppa找到pa,然后对pa进行解引用操作:*pa,找到a。

5.指针数组

指针数组是存放指针的数组

#include <stdio.h>
int main() {
	int a = 1;
	int b = 2;
	int c = 3;
	int* pa = &a;
	int* pb = &b;
	int* pc = &c;
	int* arr[3] = { pa,pb,pc }; // 指针数组
	// 遍历指针数组
	for (int i = 0; i < 3; i++) {
		printf("%p:%d\n", arr[i], *arr[i]);
	}
	return 0;
}

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值