C语言问题集——指针篇(2)

上期传送门: C语言问题集——Chaper 2(指针篇)(1)_TIED_Space-CSDN博客

1、指针的解引用:

先看一段代码:

#include <stdio.h>
int main()
{
	int n = 0x11223344;
	char* pc = (char*)&n;
	int* pi = &n;
	*pc = 0; 
	*pi = 0; 
	return 0;
}

n是一个整形,16进制的表示形式,这是n在内存中的存储,&n本应用一个整形指针来接收,在这里强制类型转换为char* 赋给字符指针pc,然后再将&n赋给一个整形指针pi,通过对这两个指针解引用来观察。

可以看到,当*pc等于0执行后,n在内存中只有一个字节的内容变成了0,所以说字符型指针一次只能改变一个字节的内容。每次的访问权限只有一个字节。

而当*pi等于0执行后,n在内存中的值都变成了0,所以可见整形指针每次可以访问4个字节的内容。每次的访问权限有4个字节。

总结:指针的类型决定了,对指针解引用的时候有多大的权限。

2、野指针

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

<1>、指针变量未初始化便使用。

代码如下:

#include <stdio.h>
int main()
{
	int* p;//局部变量指针未初始化,默认为随机值
	*p = 20;
	return 0;
}

在这里,p就是一个野指针,它没有初始化,默认为随机值,所以它访问的地址是不可知的,所以为了避免这种情况,使用指针变量时要给其初始化,可以是一个变量的地址,或者置为空指针,即

int* p = NULL;像这样将这个指针变量保护起来,当使用时再拿出来用即可,但是不能赋值为0,因为指针变量p存的是地址,赋值为0时,会默认0是内存空间中的一个地址,但是0这个地址可能并不是用户可以访问的,往往是留给计算机操作系统的内存空间的一部分,所以置为NULL是最合理的。

<2>、指针越界访问

代码如下:

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

 首先,int* p = arr的含义是p指针指向arr数组的第一个整形元素,数组一共只有10个元素,但是for循环却在最后使指针指向的范围超出了数组arr的范围,造成非法访问,此时的p指针就是野指针。

所以在遍历数组时一定要进行数组是否越界的检查。

3、指针运算

<1>指针加减整数

代码如下: 

#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}

指针加减整数就是从当前地址处向后或向前跳几个字节,如给int*型的指针加一就是向后跳4个字节。减一就是向前跳4个字节。

<2>指针减指针

指针减指针的绝对值得到的是两个指针之间元素的个数。

代码如下:

 arr指向数组中首元素,arr+3指向数组中第4个元素,所以p1和p2之间差了3个元素,所以两者相减的绝对值为3。

<3>指针的关系运算

代码如下:

#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}

要注意的一个点是:

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

4、指针与数组

<1>数组名代表的是数组首元素的地址

注意有两种情况除外:

1、sizeof(数组名)

2、&数组名

sizeof(数组名)是求的数组中所有元素在内存中所占的字节数

&数组名取到的是整个数组的地址,而且在接收时,需要用一个数组指针来接收,在此处我们不讨论,以后会有。

另外,arr[i]和*(arr+i)的写法是等价的。

代码如下:

 5、二级指针

我们知道存放一个变量地址的变量叫指针,那么存放一个指针变量地址的变量呢?

 整型变量的地址存进整型指针pa中,而指针pa的地址存进一个二级指针变量ppa中,当对二级指针解引用时,要解引用两次才能拿到原本放进去的值,第一次解引用是拿到了存进去的一级指针pa,再次解引用才是通过指针pa拿到了变量a的值。

6、指针数组

指针数组是数组,该数组的每个元素是指针

代码如下:

#include<stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = 30;
	int* pa = &a;
	int* pb = &b;
	int* pc = &c;
	int* arr[3] = { pa,pb,pc };

	return 0;
}

其中的arr数组就是一个整型指针数组,每个元素是整型指针。

水平有限,欢迎指正。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值