指针的数组:
一维数组:
形式和初始化方式:
char *p[3] ={"hello","world","fine"}.
该代码的含义为:定义了一个char *类型(数组用来装地址),3个空间的数组,并将三个字符串常量的首地址赋给了数组。
此时p指的是该数组的首地址:要访问内部的地址数据可以通过
下标运算符:a[0],a[1],a[2]的方式使用。
也可以通过*运算来进行访问:
*(p),*(p+1),*(p+2)等方式来进行。
注意:访问的数据类型是char 类型的地址(指针)
指针 + 函数:
原理:函数也是一块一块的存放在内存空间中的。
通过对函数名取地址就可以的到函数的首地址。
形式和初始化方法:
先给一个函数形式的例子:
int add(int a,int b)//是一个函数
//函数名——代表函数的入口地址
//函数对应的数据类型——通过去掉变量名的方法确定,即 int(int a,int b) 其中a,b可不写
//代表的是一类函数
//返回值为int 型
//带有两个int型的变量
由对上面的函数分析确定了两个问题:
1.函数的地址用什么表示?
对add取地址来表示
2.要定义一个什么类型的指针来存储地址?
知道了定义指针的类型要与指针指向的数据类型相同。
所以指针类型为函数类型int (int,int)
所以书写形式:int(*p)(int,int);
初始化方法:
int (*p)(int,int) =add;//将函数首地址给了相同类型的指针p
指针的使用方法:
int a , b;
我们通过“p(a,b)”的方式来调用函数(不需要在p前面加*运算符),其中()也算是一种运算符:其表示对p所表示的函数进行调用
说明:
1.可以定义一个函数类型的指针:
保存函数的入口地址。
2.通过指着指针变量:
我们可以访问这个函数的功能,通过指针来对函数尽心调用。
回调函数
了解了指针和函数结合的用法,我们就可以涉及到回调函数的使用。
回调(callback):其指的是在调用一个函数的过程中又通过指针函数的方式调用了另一个函数。
具体代码举例:
include<stdio.h>
2
3 int Funadd(int x,int y)
4 {
5 return x+y;
6 }
7
8 int Funde(int x,int y)
9 {
10 return x-y;
11 }
12
13 int Funmul(int x,int y)
14 {
15 return x*y;
16 }
17
18 int Fundivid(int x,int y)
19 {
20 return x/y;
21 }
22
23 void processDate(int a,int b,int (*p)(int,int))
24 {
25 printf("fianl = %d ",p(a,b));
26 }
27
28 int main(int argc, const char *argv[])
29 {
30 int a = 3,b = 5;
int (*p)(int,int) = Funadd;
32 processDate(a,b,p);
33 return 0;
34 }
其中在processDate函数之中就是留了一个int (int,int)类型的函数接口来实现数据的处理,该种方式就叫做函数的回调。
指针形式的基本总结:
首先回顾指针类型的定义规则:
基类型 + * + 指针名称
数组的定义:
一维:
数组类型 + 数组名 +[常量表达式]
二维:
数组类型 + 数组名 +[常量表达式][常量表达式]
eg:
一维:
char a[n];int a[n],
二维:
char a[n][n];//其数据类型为 char [n]
int a[n][n];//其数据类型为 int [n]
指针和基本数据类型(以int 和 char来进行举例):
int a;
char a;
对应类型指针表示:
int *p;
char *p;
一维字符数组的指针表示:
int a[n];
int *p;
访问方式:*(p+i)或p[i];访问int 或 char型的数据
char a[n];
char *p;
二维数组的指针表示:
int a[n][n];
int (*P)[n];
char a[n][n];
char (*p)[n];
访问方式:*(*(p+i)+j)或p[i][j]//i代表的是int [n]或char [n]的偏移量,j代表的是int或char 类型的偏移量。
指针数组+指针:
int *P;//其代表int型的指针
char *p//其代表的是char 类型的指针
对应的数组的写法:
int *a[3]//其表示的是定义了一个数组a,其中数组a装的元素为int *类型的指针
char *p[3]//与上类似
该数组指针的写法:
由于存的是指针类型,所以定义的指针的基类型为数组对应的类型:
int **p;//从右往左第一个*的含义为标志p是一个指针,第二个*是与前面的int *联系在一起的,表示该指针p存放的是int* 类型的指针
char **p;//与上类似
访问方式:
由于其中放的的是指针,通过调用指针的方式来使用指针的形式如下:
**(p+i);//(p+i)表示的是该指针数组的偏移量,从右往左第一个*指的是访问数组(p+i)中的地址,第二个*表示的是访问该地址所指向的数据。
对于函数传参时形参实参的指针使用原则:
当传参时传的是基本数据类型时,传的就是基本类型的指针,
当传参时传的是一维数组时,其指针类型也为对应数据类型的指针。
当传参时传的是二维数组时,其指针类型为一维数组对应形式的指针。
char a[n][n] ———— char(*p)[n];
通过定义指针和指针数组,并通过指针访问指针数据的例子举例:
#include <stdio.h>
int main() {
// 定义一个整型数组
int numbers[3] = {10, 20, 30};
// 定义一个指向整型的指针数组,数组长度为3
int *pointerArray[3];
// 初始化指针数组,使其指向numbers数组中的元素
for (int i = 0; i < 3; ++i) {
pointerArray[i] = &numbers[i];
}
// 定义一个指向指针的指针,即指向指针数组元素的指针
int **pointerToPointer = &pointerArray[0];
// 通过指针访问指针数组中的元素
// 首先通过pointerToPointer访问指针数组的第一个元素
// 然后通过*pointerToPointer访问它指向的整型数据
printf("%d\n", **pointerToPointer); // 输出10
// 移动指针到指针数组的下一个元素
pointerToPointer++;
// 再次通过指针访问数据
printf("%d\n", **pointerToPointer); // 输出20
// 继续移动指针并访问数据
pointerToPointer++;
printf("%d\n", **pointerToPointer); // 输出30
return 0;
}
```c