概念
- 指地址
- 比如变量a的地址&a,这是一个地址,同时也是一个指针
- 可以说指针&a 指向变量a
- 指指针变量
- 比如int *p 此处变量p是指指针变量,简称指针
指针变量
- 一个专门用来存放内存地址的变量
- 指针就是指针变量
- 格式
- 类型 *指针变量名
- * 是定义指针的固定格式
- 类型:指针变量指向的内存空间存放的数据类型
- 指向:如果我保存了你的地址,那么就说我指向你
- 类型 *指针变量名
int arr[10];
// arr表示首元素地址,此处指针类型首元素的类型
int *p3 = arr;
// 指向整个int [10]数组基地址的指针变量
int (*p4)[10]= &arr;
指针就是一个存放其他变量地址的变量
指针的类型就是它指向的那段内存空间的类型后+ “”*“号
int *p1 = &a;
char str[6] = "hello";
// str 首元素地址, 存储str的指针就是 "首元素类型 *" 类型
char *p2 = str;
// &str 整个数组,整个数组是 char [6] 类型,存储他的指针就应该是char (*)[6]
// 因为优先级问题一定要打个小括号
char (*p3)[6] = &str;
指针赋值和索引
- 赋值
- 赋给指针的地址,类型需要跟指针的类型相匹配
- 索引
- 指的是通过指针,获得其指向的目标
指针运算
- 指针加法(指针的偏移)
- 按照指针指向的类型数据进行运算(指针偏移的单位由指针的类型大小所决定)
- 类型大小:
- 指针变量所指向的内存空间的数据类型
int a;//在内存中申请4个字节的空间,由变量名a间接访问
int *p;//在内存中申请8个字节的空间,存放一个地址,这个地址所指向的内容是int类型
p = &a; //&:取地址符,&a获取a变量的地址,把这个地址存放在指针变量p中
*p // *:解引用,访问该指针指向的目标, a值与 *p的值
*p = *(&a) = a;//取地址符与解引用是逆运算
int array[] = {10, 20, 30, 40, 50, 60};
// 定义一个指针变量存储数组的首元素的地址(存储的所有方法罗列出来)
int *p = array;
// 通过数组名array 和 指针变量 将所有能够打印出50的值的方法都罗列出来
printf("%d \n", array[4]);
printf("%d \n", *(array + 4));
printf("%d \n", 4 [array]);
printf("%d \n", p[4]);
printf("%d \n", *(p + 4));
printf("%d \n", 4 [p]);
// 注意以下方法了解就行
char *p1 = (char *)p;
printf("%d \n", *(int *)(p1 + 16));
int (*p2)[6] = &array;
// 先 *p2 解引用把整个数组地址范围缩小为 首元素地址
// 再 +4 解引用, 拿到第四个子元素
printf("%d \n", *(*p2 + 4));
printf("%d \n", p2[0][4]);
printf("%d \n", (*p2)[4]);
地址运算
- 内存地址
- 字节:
- 字节是内存的容量单位,一个字节有8位
- 地址:
- 系统为了区分每一个字节而对他们逐一进行的编号
- 字节:
- 基地址
- 单字节数据:
- 基地址就是字节编号
- 多字节数据:
- 基地址是其所有字节中编号最小的一个
- 单字节数据:

//定义了一个字符串数组arr
char arr[12] = "hello world";
//定义了一个字符类型的指针指向数组的首元素的地址
char *p1 = arr;
定义了一个字符类型的指针指向整个数组
char (*p2)[12] = &arr;
printf("%p %p \n", p1, p2);
//打印的地址是+1字节打印
printf("%p \n", p1 + 1);
//打印的地址是+整个数组占用字节数的大小打印
printf("%p \n", p2 + 1);
// 强制类型转换
int *p3 = (int *)arr; // char *
printf("%p \n", p3 + 1); // 因为p3是个 int型指针这里+1 偏移一个int(4)字节
// p3 + 1 偏移4字原始数据 "hello world" 其基地址第一个o的地址
// p3 是int *型, 解引用按整形解引用读四个字节 "o wo" 转为ascii码 字节一 111 字节二 32 字节三 119 字节四 111 其中 按照“ow o”的顺序进行排列 因为o是其基地址
printf("%d \n", *(p3 + 1));
printf("%d \n", *(char *)(p3 + 1));// 解引用用了类型强转 p3解引用是当前地址向后读四个字节,强转变为char *类型再解引用只读一个字节
int num = 0xffaabbcc;
//定义了一个字符类型的指针指向num的基地址
char *pn = (char *)#
// *(pn + 1) = 0x99;//0xffaa99cc 修改了偏移一位的地址的值为99
pn[2] = 0xee; //0xffeebbcc 修改了偏移两位的地址的值为ee
printf("%#x \n", num);
Comments NOTHING