指针初阶
1. 指针
地址,空间
大部分数字计算机将内存,分割为一个个空间,每一个空间大小为一个字节
每一个字节,都对应着一个编号进行管理,这些编号也称为地址

什么是指针,指针变量
C语言通常称为低级语言,这里的低级是指C语言与计算机底层有紧密的联系,可以通过指针来访问内存空间
所以,指针可以理解为地址
既然指针就是地址,那么指针变量就是存储地址的变量
口语中的指针,实际上是指针变量
指针的申明
int * pa
* 表示pa是一个指针,
int, 表示指针的类型为整形, 存储的是一个整形变量的地址,也叫做指向整形的指针

取地址& ,间接引用* 操作符
直接看一个例子
#include <stdio.h>
int main()
{
int a = 1;
int* pa = &a;
*pa = 2;
printf("%d", a);
}

执行流程
1,int a = 1
开辟4个字节的空间,然后将1存进去


2,int* pa = &a
&, 取地址操作符
&a表示取出整形变量a的起始地址,存入整形指针pa的存储空间中


3, *pa = 2
* ,间接寻址操作符,通过地址访问对应的空间
pa 存储的是a的地址, *pa 实际上访问的是a的空间,然后将存入2


2. 指针类型
指针的大小
#include <stdio.h>
int main()
{
printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(double*));
}

指针是存储地址的变量,地址的大小由机器地址线决定
所以指针的大小都是一样的,和类型无关
那么,指针类型的意义是什么 ?
类型的意义
1. 类型决定,*寻址的权限
观察下面两个例子
#include <stdio.h>
int main()
{
int a = 0x11223344;
int* pa = &a;
*pa = 0;
}

#include <stdio.h>
int main()
{
int a = 0x11223344;
char* pa = (char*)&a;
*pa = 0;
}

当pa的类型为整形时,*寻址可以一次性访问4个字节
pa类型为字符时, 只能访问一个字节
2. 类型决定,指针的步长
#include <stdio.h>
int main()
{
int a = 0x11223344;
int* pa = &a;
char* pb = (char*)&a;
printf("%p\n", pa);
printf("int*: %p\n", pa + 1);
printf("char*: %p\n", pb + 1);
}

pa, 整形指针, +1跳过了4个字节
pb, 字符指针, +1跳过了1个字节
类型决定指针进行运算时,具体跳过多少个字节
3. 指针运算
指针 + 整数
#include <stdio.h>
int main()
{
int a = 0;
int* pa = &a;
char* pb = (char*)&a;
printf("%p\n", pa);
printf("%p\n", pa+1);
printf("%p\n", pb);
printf("%p\n", pb + 1);
}

从中可以发现,指针+整数,是向高地址移动的,指针的步长由指针的类型决定

指针 - 整数
#include <stdio.h>
int main()
{
int a = 0;
int* pa = &a;
char* pb = (char*)&a;
printf("%p\n", pa);
printf("%p\n", pa - 1);
printf("%p\n", pb);
printf("%p\n", pb - 1);
}

指针-整数时,指针向低地址移动,移动的步长由类型决定
指针 - 指针
#include <stdio.h>
int main()
{
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
printf("%d\n", &arr[9] - &arr[0]);
}

指针 - 指针,得到的是两个指针之间的元素个数
分析


注意:
C语言规定,指针 - 指针时,必须要确保两个指针指向同一内存块
同时,保证两个指针类型相同
指针 - 指针的应用
// 求字符串长度
#include <stdio.h>
int len1(char* str)
{
int count = 0;
char* ps = str;
while (*str != '\0')
{
str++;
}
return str - ps; // 指针 - 指针
}
int main()
{
char arr[] = "abcdef";
int res = len1(arr);
printf("%d\n", res);
return 0;
}

指针的关系运算
可以用关系运算符,对两个指针进行比较
比较的结构,取决于两个指针在同一内存块中的地址
#include <stdio.h>
int main()
{
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
printf("%d\n", &arr[9] <= &arr[0]);
printf("%d\n", &arr[9] >= &arr[0]);
}

数组元素9的地址大于或等于元素0 的地址,为1(真)
所以,两个指针之间进行比较,实际上比较的是地址
4. 二级指针
什么是二级指针
指针是一个存储地址的变量,既然是一个变量,那么就可以用&取地址操作符,取出一个变量的地址
所以,二级指针就是存储一个一级指针地址的变量,也叫做指向指针的指针
#include <stdio.h>
int main()
{
int a = 0;
int* pa = &a; // 一级指针
int* *ppa = &pa; // 二级指针
}


二级指针的声明与赋值
int* *ppa;
ppa前面的*, 表示pppa是一个指针变量,用来存储地址
int*, 表示变量ppa存储的是一个一级整形指针的地址
int* *ppa = &pa;
二级指针和一级指针一样,可以用 =赋值运算符,进行赋值
二级指针的使用
#include <stdio.h>
int main()
{
int a = 0;
int* pa = &a; // 一级指针
int** ppa = &pa; // 二级指针
**ppa = 1;
printf("%d\n", a);
}

* *ppa = 1
*ppa,表示访问ppa的空间, ppa存放的是pa的地址, 所以可以这么理解 **ppa = *(pa)
*pa, 访问的是a的空间,并存入1
浙公网安备 33010602011771号