7 指针
7.1基本概念
- 指针:一个变量的地址
- 指针变量:专门存放另一个变量地址的变量
定义:int *ptr这里的变量名时ptr,而不是*ptr.
指针变量的引用:
- &a求变量a的地址
- *a取指针所指向变量的内容
7.2 指针的运算
±运算:
- 指针与整型值加减结果是指针,表示使该指针指向该指针下移或上移存储单元的个数。
- 存储单元大小为指向变量的数据类型所需内存大小。
- 指针与指针相加无意义
- 指针之间相减为数据的个数
7.3 指针与数组
7.3.1 对数组元素的引用方法
- 下标法
- 指针法:
int a[10],*p,i; p=a; *(p+i)//访问对应a[i]元素,注意这里是指数组第i+1个元素
指针变量与数组名的区别:
指针变量的内容可以在程序执行过程中被改变,而数组名因为是一个地址常量,所以一旦其被定义,就无法改变
数组名做函数参数:
编程时都是将形参数组名作为指针变量来处理
7.3.2 指针与字符串
char *pstr; char *pstr="hello world"; char *pstr;pstr="hello world"; //output printf("%s",pstr); printf("%c",*(pstr+i));
字符指针变量与字符数组的区别:
- 前者存放的是地址(字符串的首地址)
- 后者是由若干个元素组成,每个元素存放一个字符
//初始化 { char a[10];a="hello!";//这是错误的!因为把数组a看成指针,它的首地址是无法改变的。 char *ps;ps="hello";//这是正确的 } //访问,同数组相同 { printf("%c",a[2]); }
字符指针数组定义后,必须先被赋值后使用;而定义一个字符数组即可马上使用。
{ char a[10];gets(a); char *b;gets(b);//这是错误的,改为下方 char *b;b=a;gets(b); //原因:我觉得是由于定义一个数组是需要在内存中开辟空间去存放,而定义一个指针则不需要开辟固定空间,so }
7.3.3 指针和二维数组
本质在于二维数组可以看成一个一维数组,这个一维数组又是包含若干元素的一维数组;
{ int a[2][3]; //a[1]表示使第一行元素的首地址 //特别强调,这里的二维数组的a与a[0]两者的基类型不同;a代表二维数组首元素的地址,首元素不是一个整型变量,而是一个由6个整型元素所组成的一维数组,因此a代表的是首行首地址。 }
(*)7.3.4 指向数组的指针(数组指针)与指针数组
1 指向数组的指针
特点:
- 指向的数据类型是数组,而不是简单数据类型
int (*p)[4]; //本身是一个指针变量,其指向的数据类型是包含4个元素的数组,这个数组中的元素是int型
2 指针数组
特点:
- 元素均为指针类型数据,其中每一个元素都相当于一个指针变量。
int *p[4]; //指针数组通常用来处理字符串问题
个人觉得和链表的结构有些相像,就是不用关注元素内部存储的细节,通过一个个指针对地址进行连接,实现了存储空间的高效利用。具体可以看看讲义的图表有助理解。
7.3.5 指向函数的指针与指针函数
1 指向函数的指针
这个地址就被称为函数的入口地址(指针),也就是说可以通过这个指针变量来调用这个函数。
int (*p)(int ,int); //p是一指向函数的指针,这个函数中有两个参数其类型都是int型,同时这个函数的返回值是int型
{ int max(int a,int b); int (*p)(int,int);//定义 int a,b,c; p=max;//这是其中关键一步,赋值时,只给函数名 。。。 c=(*p)(a,b);//使用时括号不要丢了,丢了就变成指针了,不是指针指向的函数了 }
2 指针型函数
特点:
函数带回一个整型、字符值很常见,这里的不过就是带回的是指针罢了
int *a(int x,int y) //名称为a的函数中有两个参数,返回一个指向int类型的指针
7.3.6 指针的指针
本质就是指针指向的元素恰好是指针(地址),主要用来灵活的操作指针数组。
上次看了bilibili上有个up主通过创建指针的指针,在不修改原来的程序结构的情况下,对原来指针的指向的值进行修改。