目录
前言
本文是在下对指针基础知识的笔记和一些理解,如果有不正确的地方还请大佬指点。后续会不间断更新笔记,也是在学习的路上留一些足迹吧。
1 指针
1.1 地址的概念
地址:内存单元的编号
地址因为会存在一种指向关系(一个地址会唯一的指向一个字节空间),所以将地址也称为指针。
指针:内存单元的编号(地址)
而这个编号是用十六进制模拟的一个数字,是一个常量。意味着指针也是是一个常量。
1.2 一级指针
概念:一级指针存储原变量的地址
定义指针变量的格式:
存储类型 数据类型 *指针变量名;
分析:
存储类型:指针变量名在内存空间中开辟的位置
数据类型:指针所指向的数据类型
数据类型*:指针的数据类型
指针变量名:分配连续空间的名字
eg:int a = 90;
int *p = a;
p = &a;
1.3 二级指针
概念:二级指针用来存储一级指针的地址
定义二级指针变量的格式:
存储类型 数据类型 **指针变量名;
分析:
存储类型:二级指针自身的存储类型
数据类型:二级指针的指向类型即一级指针所指向的类型
数据类型 *:二级指针的指向类型
数据类型 **:二级指针自身的数据类型
eg:*p = a;
*pp = p;
**pp = a;
1.4 数组指针
概念:指向一维数组的指针,也称为“行指针”
定义数组指针的格式:
存储类型 数据类型 (*指针变量名)[元素个数];
分析:
存储类型:代表数组指针开辟空间的位置
数据类型:数组指针所指向的一维数组中的元素的数据类型
eg:int arr[6] = {1,2,3,4,5,6};
int (*p)[6] = &arr;
1.5 指针数组
概念:数组元素是指针类型的数据
定义指针数组的格式:
存储类型 数据类型 * 数组名[元素个数];
分析:
存储类型:数组开辟空间的位置
数据类型:指针数组中每一个元素所指向的数据类型
数据类型 *:指针数组中每一个元素的数据类型
eg:char * pStr[5] = {“aaa”,”bbb”,”ccc”,”ddd”,”eee”};
理解:首先是一个数组,里面的元素全为指针类型,即:char *。存储的这5个来自于常量区中的各自字符串中的首地址。
1.6 指针与一维数组的关系
指针的算术运算:+ - ++ --
eg:假设目前存在两个整形指针:int *p ,*q;(PS:q在内存中的地址是大于p的)
p+N:代表指针向地址增大的方向移动N个数据类型的大小(p + N = p + sizeof(数据类型)*N)
p-N:代表指针向地址减小的方向移动N个数据类型的大小(p - N = p - sizeof(数据类型)*N)
p++:代表指针向地址增大的方向移动1个数据类型的大小(p = p + sizeof(数据类型)*1)(改变指针自身的指向)
p--:代表指针向地址减小的方向移动1个数据类型的大小(p = p - sizeof(数据类型)*1)(改变指针自身的指向)
q-p:代表两个地址之间相差数据元素的个数(q - p / sizeof(数据类型))
前提:指针的类型必须一样。
arr[i]与*(arr+i)等价
1.7 经典例题
#include <stdio.h>
int main()
{
char *str[4] = {"welcome","to","new","beijing"};
char **p = str+1;
str[0] = (*p++)+1;
str[1] = *(p+1);
str[2] = p[1]+3;
str[3] = p[0] + (str[2] - str[1]);
printf("%s %s %s %s\n",str[0],str[1],str[2],str[3]);
return 0;
}
o beijing jing g
首先:str 是一个指针数组。它的值是这个数组首元素的地址。
指针 | 指针指向一个地址 | 地址存放的元素 |
str | 0xA | welcome\0 |
str+1 | 0xB | to\0 |
str+2 | 0xC | new\0 |
str+3 | 0xD | beijing\0 |
char **p = str + 1;
str+1存放的是第二个元素的地址,即str+1 = 0xB,p是一个指向char*类型的指针,所以
p = str + 1;
*p = 0xB;
str[0] = (*p++) + 1;
*p = 0xB ;所以str[0] = 0xB + 1,即to的第二个字符'o'的地址。
同时因为p++,此时p = str + 2。
打印为'o'。
str[1] = *(p+1);
p+1 = str+3。
*(p+1) = 0xD即为'beijing'中'b'的地址。
打印为'beijing'。
str[2] = p[1] + 3;
p[1]等价于*(p+1),所以str[2] = *(p+1) + 3;
*(p+1) = 0xD;
所以实际上str[2] = 0xD + 3,为'beijing'中'j'的地址。
打印为'jing'。
str[3] = p[0] + (str[2] - str[1]);
str[2]为'j'的地址,str[1]为'b'的地址,所以str[2] - str[1]为3。
p[0]等价于*p,p = str+2; 而str+2是str[2]的地址,所以 *p = 0xD + 3;
所以str[3] = 0xD + 3 + 3,为'beijing'中'g'的地址。
打印为'g'。