C语言指针(下)

前言:

上文我们已经学习了指针的基本概念内存单元地址的产生,以及指针和指针的类型。这时我们对指针已经有了一个初步的了解,接下来我们将继续深入的学习指针用法。

一. 野指针

 (一)概念:

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

int main()
{
	int* p;
	//p没有初始化就意味着没有明确的指向
	//一个局部变量不初始化的话,放的是随机值;
    //会初始化为一部内容,一般是0xcccccccc这样的值
    //这时它就会把0xcccccccc当作是它的地址
    //但这个地址所指向的空间不是它的
    //也就是说它使用的地址是一个非法的地址
	*p = 10;//非法访问内存了,这里的p就是野指针
	return 0;
}

(二)野指针成因

1. 指针未初始化(就是上面那种)  
2. 指针越界访问
int main()
{
	int arr[10] = { 0 };
	int* p = arr;
	for (int i = 0; i <= 10; i++)
	{
		*p = i;
		p++;
	}//指针指到前面10个地址的时候还不是野指针
     //指针指到第10个地址后面的地址时就是野指针
	return 0;
}
3. 指针指向的空间释放 
int* test()
{
	int a = 0;
	return &a;
    //a会在这里取好一个地址然后返回去
    //这时*p的地址就是a所取的这个地址
}
    //但是一旦出了test()函数的时候,
    //a就会立即销毁这个地址,
    //也就是将地址还给了操作系统,
    //这时这个空间已经不属于a和p了,
    //但是p依然保存着这个地址,
    //所以p还能找到这个空间,
    //当p再往下执行的时候就是野指针。
int main()
{
	int* p = test();
	return 0;
}

(三)如何尽量避免野指针的出现

1.指针初始化

2.小心指针越界

3.避免返回局部变量

4.指针使用之前有效性的检查 

 二. 指针与数组

int main()
{
	int arr[10] = { 0 };
	//arr是首元素的地址
	int* p = arr;
	//通过指针来访问地址
	return 0;
}

三. 指针的运用

1. 指针+-整数

//例:给数组初始化
//法一:
#define n 5
int main()
{
	float arr[n];
	float* a;
	for (a = &arr[0]; a < &arr[n];)
	{
		*a++ = 1;
	}
	return 0;
}
//法二:
#define n 10
int main()
{
	int arr[n] = { 0 };
	int* p = arr;
	for (int i = 0; i < n; i++)
	{
		*p = 1;
		p++;
	}
	return 0;
}

补充:*a++ 与(*a)++的区别是:前者是给地址++;后者是给指针所指向的对象进行++,比如*a所指向的对象是0,那么(*a)++执行一次后*a所指向的对象就变为1了。

2. 指针-指针

C语言指针(下)_第1张图片

 指针-指针得到绝对值的是指针和指针之间元素的个数,如下图

C语言指针(下)_第2张图片

但不是所有的指针都能相减,只有指向同一块空间的两个指针相减才有意义。例如下面这种。

C语言指针(下)_第3张图片  

四. 二级指针

 二级指针是用来存放一级指针变量的地址

int main()
{
	int a = 10;
	int* pa = &a;//pa是一个一级指针变量
	int** pi = &pa;//pi是一个二级指针变量
	**pi = 20;
	return 0;
}

五. 指针数组

存放指针的数组其实指针数组,如下图。

C语言指针(下)_第4张图片

使用指针数组模拟二维数组:

C语言指针(下)_第5张图片

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