C语言指针相关知识(初阶)

目录

指针是什么

指针变量的大小

指针和指针类型

指针类型的意义

野指针

指针运算

指针+-整数

指针-指针

指针的关系运算

指针和数组

二级指针

二级指针定义

指针数组

指针数组的定义


指针是什么

如下图所示(右侧编号为内存地址):

	int a = 10;//a占四个字节
	int* pa = &a;//拿到的是a的四个字节中第一个字节的地址
	             //将a的地址存放在pa变量中,pa是一个指针变量

指针变量的大小


指针和指针类型

指针类型的意义

1.指针类型决定了:指针解引用的权限有多大(如下例)

	int a = 0x11223344;
	int* pa = &a;
	*pa = 0;

上述代码中,原先a地址的值在内存中显示为:

执行后面两句代码后,内存中四个字节的值被改变了:

而在下述定义char指针类型的代码中:

只改变了一个字节的地址

2.指针类型决定了:指针每走一步的步长(如下例)

	int arr[10] = {0};
	int* pa = arr;
	char* pc = arr;
	printf("%p\n",pa);
	printf("%p\n", pa+1);

	printf("%p\n", pc);
	printf("%p\n", pc+1);

同样加一,但是int类型和char类型指针的步长不同


野指针

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的) ,造成原因为:

1.指针未初始化

	int* p;//p是一个局部的指针变量,未初始化默认为随机值
	*p = 20;//非法访问内存

2.指针越界访问

	int arr[10] = { 0 };//数组大小为10
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 10; i++) {//循环11次
		*p = i;
		p++;           //第11次越界,产生非法访问
	}

3.指针指向的空间释放

int* test() {
	int a = 10;
	return &a;
}
int main() {
	int* p = test();//局部变量a申请的内存空间已经销毁
	*p = 10;        //此时指针p再把10存入a的内存空间中,为非法访问内存
	return 0;
}

如何规避野指针:

1.指针初始化(不知初始化为何地址时,初始化为NULL)

2.小心越界指针

3.指针指向空间释放即放置NULL

4.指针使用之前检查有效性(if p!= NULL)


指针运算

指针+-整数

 

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int* pend = arr + 9;
	while (p<=pend)        //指针的关系运算(地址大小在比较)
	{
		printf("%d\n", *p);//依次打印1 2 3 4 5 6 7 8 9 10
		p++;             //指针+-整数
	}

指针-指针

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	printf("%d\n", &arr[9] - &arr[0]);//结果为9
	//指针减去指针得到的是两个指针之间元素的个数

指针的关系运算

	#define N_VALUES 5
	float values[N_VALUES];
	float* vp;
	for (vp = &values[N_VALUES]; vp >&values[0];) {//关系运算
		*--vp = 0;//数组所有元素置为0
	}

上方这段代码与下方图片中的代码执行结果是相同的:

但是,下方这段代码是存在一些问题的:


指针和数组

数组名是数组首元素的地址:

	int arr[10] = { 0 };
	printf("%p\n", arr);//数组名是数组首元素的地址
	printf("%p\n", &arr[0]);
	//打印结果都为00EFF920

通过指针访问数组:

	int arr[10] = { 0 };
	int* p = arr;
	int i = 0;
	for (int i = 0; i < 10; i++) {
		printf("%d", *(p + i) = i);
		//成功打印数组各元素
	}


二级指针

二级指针定义

int a = 10;
	int* pa = &a;//pa是指针变量,一级指针

	//ppa是一个二级指针变量
	int** ppa = &pa;//pa也是个变量,&pa取出pa在内存中起始地址

	//a的值为10,地址为0x0012ff40
	//pa的值为0x0012ff40,地址为0x0012ff48
	//pa的值为0x0012ff48,地址为0x0012ff52

如何通过上述代码通过ppa找到a?

	 *ppa == pa
     *pa == a
     * *ppa == a

存在三级、四级等指针,但一般很少使用


指针数组

指针数组的定义

	//指针数组 - 数组
	int arr[10];//整型数组 - 存放整型量
	char ch[5];//字符数组 - 存放的是字符
	//指针数组 - 存放指针的数组
	int* parr[5];
    char* parr[5];

以上为C语言中指针初阶知识的相关内容,感谢您花费宝贵的时间阅读本文章!

之后博主会撰写关于指针高阶相关内容的博客。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值