关于 C 语言指针类型的总结
前言
我个人将目前在 C 语言中所遇到的指针归类为 8 种,至于为何写第九点,是因为我个人认为第九点极容易与第五点混淆,故总结如下:
1.普通指针
普通指针即最常见的如:int * 、 char*等
甚至于也可将一个数组如 arr[5]的数组名 arr 看作是指针类型(因为指针本质上就是地址,而 arr 是该数组首元素的地址)
但是值得注意的是 sizeof (arr) 与 &arr 两种情况所代表的是整个数组的地址,首元素地址和整个数组地址在值上虽然相同,但在各自+1、-1 操作所跨越的空间极为悬殊,前者+1 只跳过一个元素,后者+1 则是跳过整个数组。
2.野指针
野指针概念:指针指向的位置不可知(随机的、不正确的、没有明确限制的)
以下介绍几种野指针情况
①指针未初始化
②指针越界访问
③指针指向的空间释放
#include <stdio.h> int* test() { int n = 100; return &n; } int main() { int*p = test(); printf("%d\n", *p); return 0; }
出函数的时候变量 n 申请的空间会归还给操作系统存在 p 中的地址没有指向的空间
3.无符号型指针(泛型指针)
无符号型指针即 void * 型
void*可以用来接收任何类型的地址,这是其优点,但需要注意的是
void*类型的指针不能直接进行指针的+-整数的运算。
注:一般 void*指针使用在函数参数部分,使得一个函数可以处理多种类型的数据,以实现泛型编 程的效果。
#include <stdio.h> int main() { int a = 10; void* pa = &a; void* pc = &a; *pa = 10; *pc = 0; return 0; }
这里我们可以看到, void* 类型的指针可以接收不同类型的地址,但是无法直接进行指针运算。
4.二级指针
二级指针概念:存放一级指针地址的指针(本质上还是地址)
至于是跳过 4 个还是 8 个字节取决于当前是几位的操作系统。
5.数组指针
数组指针概念:存放的是数组的地址,是能够指向数组的指针变量。
上图 p2 就是数组指针变量,详细分析可见第 8 点。
数组指针的初始化:int(*p)[10] = &arr;
6.函数指针
函数指针概念:函数指针变量是⽤来存放函数地址的
函数名就是函数的地址,当然也可以通过 &函数名获得函数的地址,两者等价。**
7.结构体指针
struct Test { int Num; char *pcName; short sDate; char cha[2]; short sBa[4]; }*p = (struct Test*)0x100000;
如图:P 就是结构体指针变量(指向结构体)
注:p+1 跳过的是一个结构体的大小。
8.文件指针
FILE pf; // 文件指针变量**
定义 pf 是⼀个指向 FILE 类型数据的指针变量。可以使 pf 指向某个文件的文件信息区(是⼀个结构体变 量)。通过该文件信息区中的信息就能够访问该文件。
即通过文件指针变量能够间接找到与它关联的文件。
至于 FILE 类型数据解释如下:
每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名 FILE.
不同的 C 编译器的 FILE 类型包含的内容不完全相同,但是大同小异。 每当打开⼀个文件的时候,系统会根据文件的情况自动创建⼀个 FILE 结构的变量,并填充其中的信息。
⼀般都是通过⼀个 FILE 的指针来维护这个 FILE 结构的变量,这样使用起来更加方便。
9.指针数组(是数组而非指针)
对于指针数组的理解可以参考整型数组和字符型数组
如下图
*在这里有必要将指针数组与数组指针对比一下*
分析:p1 优先与[10]结合,p1 是数组名,即 1 式是指针数组。
p2 优先与*结合,表明 p2 是指针变量,即 2 式是数组指针。
文章转载自:白藏crab
评论