指针的初阶

目录

1.指针是什么?

2.指针的类型和解引用

3.野指针

4.指针的运算

5. 指针和数组

6. 二级指针


这篇文章是对指针进行一个初步的认识,往下了解吧!

1.指针是什么?

1. 指针是内存中一个最小单元的编号,也就是地址
2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

总结:指针就是地址,口语中说的指针通常指的是指针变量。

2.指针的类型和解引用

2.1 指针的类型

我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?

答案肯定是有的

例如:

int a = 10;
 p = &a;

将&a(a的地址)保存到p中,我们知道p就是一个指针变量

p的类型应该就为int*;

char  *pc = NULL;
int  *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

所有我们能得出:指针的定义方式是: type + * 。

char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。

2.2  指针的解引用

例一:

    int a = 100;
    int* p = &a;
    printf("a=%d\n", a);
    printf("a=%d\n", *p);

例二:

#include <stdio.h>
//演示实例
int main()
{
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);//0073FA44
printf("%p\n", pc);//0073FA44
printf("%p\n", pc+1);//0073FA45
printf("%p\n", pi);//0073FA44
printf("%p\n", pi+1);//0073FA48

return 0
}

首先pc和pi取得是n首元素的地址 所以他们是相同的

由于pc是char*类型 而pi是int*类型 他们地址加1的情况会不同

char*指针跳过一个字节,而int*跳过4个字节

总结:
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

3.野指针

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

错误用法:

3.1 指针未初始化

int main()
{
	int* p;
	*p = 20;
}

首先这种写法就是不可取的,编译的时候会报错,因为*p未初始化

如何改正呢?

#include <stdio.h>
int main()
{
	int* p=NULL;
	*p = 20;
}

这样就不会报错,NULL相当于0对于指针变量;

3.2 指针越界访问

虽然可以运行,但明显arr数组里有10个元素,却要访问了11个元素,访问不到第11个元素,所以会产生随机值,这也是野指针。

这里可以看见 当下标为10的时候已经超出arr数组的范围了,还给它赋值为-1,已经非法或越界访问了,所以直接报错;

3.3 规避野指针

那么改如何避免这些情况呢?

1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性

4.指针的运算

4.1 指针+-整数

这其实就是一个很好的例子 

首先 p+0 指向的是第一个元素的地址 在对解引用 *(p+0) 就可以拿到0

如何 p+1指向的是第二个元素的地址 在对解引用 *(p+1) 就可以拿到1...

4.2 指针-指针

实例:用指针-指针的方法模拟实现strlen函数 

//strlen函数求字符串长度

strlen模拟实现:

5. 指针和数组

指针是指针 指针变量是一组变量 指针存放的是地址 指针的大小是4/8个字节

数组是数组 可以存放一组数 数组的大小由它的类型来决定

数组的数组名是首元素的地址 地址可以访问到指针变量中

一般情况下,数组名是首元素的地址,只有在这俩种情况下 表示的数组的地址

1.sizeof(arr)   

2.&arr

&arr是取出整个数组的地址 &arr[0]是首元素的地址

这样看虽然他们的地址相同 但意义不一样

这样就可以看出差别很大 首先&arr是取出整个数组的地址 所以+1跳过的4*10个字节空间

而&arr[0]+1则跳过的4个字节的空间

数组和指针结合使用

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

这样更容易能看出通过指针变量就能找到数组中的元素

6. 二级指针

#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;//p是指针变量,它是一级指针,存放a的地址
	int* * pp = &p;//pp是指针变量,它是二级指针  存放一级指针p的地址

}

对于二级指针的运算有:
*p 通过对a中的地址进行解引用,这样找到的是 a , *p 其实访问的就是 a

pp 先通过 pp 找到 p,先解引用*pp找到p ,然后对 p 进行解引用操作: *p ,那找到的是 a .

小结:这一次是对指针的初步认识,指针的内容还有一大块需要我们去开掘,小编之后还会继续完善指针的内容,大家一起努力吧!

猜你喜欢

转载自blog.csdn.net/chaodddddd/article/details/132748289