指针是C语言编程灵魂,但是也不要神话它,掌握住指针的实质很重要。
1、指针地址空间
指针:指针变量 用来存储内存地址编号。
地址:内存会按照字节进行编号,一个字节就有一个编号。
一般地址表示用十六进制 ,查看地址用%p
空间:指针本身的空间 和 指针指向的空间
cpp
int a;
int * p;
p = &a;
指针指向谁就保存谁的地址,保存谁的地址就指向谁。
2、指针定义
指针是变量,也要遵循先定义在使用的原则,定义和变量的定义类似。
格式:
指向对象的数据类型 * 指针名;
指针对象的数据类型:学过的数据类型都可以,具体看需求
*:代表指针的标记
指针名: 自定义 p q t k head tail h
例子:
定义一个指针指向int型的变量: int * p;
定义一个指针指向char型空间: char * q;
定以一个指针指向 int [3]的空间:int (*q)[3];
3、指针赋值
指针使用前必须有明确的指向,也就是要有合法的地址值。
什么类型的指针存储什么类型的地址,但是对于指针变量来说存储的是地址值即可,因此也可以将地址强转赋值给不同类型的指针。
cpp
// 先通过变量的形式拿到地址编号
int a = 10; // &a
int b = 20; // &b
// 让指针指向空间a
p = &a; // *p就是a
*p = 15; // a == 15
p = &b; // *p就是b, 对p赋值就改变了p的指向
*p = 35; // b = 35;
char * q = (char *)&a;
// *q就是a的第一个字节的空间
4、指针操作指向的空间
表示:*指针名
后续操作需要看 类型决定后续操作。
int * p = 地址; *p是int型按int型操作
char *p = 地址; *p是char型按char型操作
struct book* 盘= 地址,*p是struct book 结构体类型,按结构体操作
5、指针本身空间
表示:指针名
操作的时候可能会改变指针的指向
指针本身空间大小和系统有关,32位--4个字节 , 64位 -- 8个字节
指针变量空间只存地址编号,能够存储地址编号即可,与指向对象类型无关。
6、指针偏移
前提:指针有明确的指向,
指针偏移和指针指向对象类型有关,以它为单位进行偏移。
指针指向对象类型 从 指针的定义 上看。
cpp
char ch = 'a';
int b = 30;
double d;
char *p = &ch;
int *q = &b;
double *t = &d;
printf("%p %p %p\n",p,q,t);
printf("%p %p %p\n",p+1,q+1,t+1);
指针偏移偏移一般用于连续的空间 --- 数组、动态内存申请
cpp
int arr[] = {5,29,30,57,8,49,20};
int *p = arr; // 等价于 p = &a[0]
printf("%d",*(p+0)); // arr[0] 在这里*解地址的意思
printf("%d",*(p+1)); // arr[0] 在这里*解地址的意思