1. 内存概念
内存是计算机中的一种存储器,为了更好的管理内存
大部分现代计算机将内存以字节为单位进行划分,一个字节等于8个比特位
每一个字节都有一个唯一的地址,进行区分和管理
2. 指针基础
在内存概念的基础上,理解指针
2.1 什么是指针
C语言中的指针,实际上指的是一个存储内存地址的变量,如下例
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a; // 指针
return 0;
}
例中pa就是一个指针变量,存储整形变量在内存中的地址
int* pa = &a
&a 表示取出变量a在内存中的起始地址
int* pa,*表示pa存储的是一个地址,int 表示pa存储的是一个整形变量的地址
2.2 指针大小
指针是一个存储地址的变量,变量需要几个字节才能存储地址?
地址大小由机器地址线的个数决定,32位地址线,地址大小为4个字节,64位地址线,地址大小为8个字节
2.3 指针类型的作用
指针有类型? 在2.1的例子中
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a; // 指针
return 0;
}
指针变量pa存储整形变量a的地址,所以pa的类型是int*整形指针,指针是有类型的
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char* pc = NULL;
int* pi = NULL;
short* ps = NULL;
long* pl = NULL;
float* pf = NULL;
double* pd = NULL;
}
指针类型有什么作用 ?
1. 类型决定 * 访问几个字节
观察下面两个例子
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 0x11223344;
int* pa = &a;
*pa = 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 0x11223344;
char* pa = (char*)&a;
*pa = 0;
}
当pa为int*整形指针时,*引用访问4个字节
pa为char*字符指针时,*解引用访问1个字节
2. 类型决定指针步长
#define _CRT_SECURE_NO_WARNINGS
#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);
}
3. 指针运算
3.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);
}
从中可以发现,指针+整数,是向高地址移动的,指针的步长由指针的类型决定
3.2 指针 - 整数
#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);
}
如图,指针-整数时,指针向低地址移动,移动的步长由类型决定
3.3 指针 - 指针
#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语言规定,指针 - 指针时,必须要确保两个指针指向同一内存块
同时,保证两个指针类型相同
4. 二级指针
4.1 什么是二级指针
指针是一个存储地址的变量,既然是一个变量,那么就可以用&取地址操作符,取出变量的地址
二级指针就是一个存储一级指针地址的变量,也叫做指向指针的指针
#include <stdio.h>
int main()
{
int a = 0;
int* pa = &a; // 一级指针
int* *ppa = &pa; // 二级指针
}
如图,二级指针ppa存储一级指针pa的地址
4.2 二级指针的声明与赋值
int* *ppa;
ppa前面的*, 表示ppa是一个指针变量,用来存储地址
int*, 表示变量ppa存储的是一个一级整形指针的地址
int* *ppa = &pa;
二级指针和一级指针一样,可以用 =赋值运算符,进行赋值
4.3 二级指针的使用
#define _CRT_SECURE_NO_WARNINGS
#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