指针的概念
字符指针的形式一般为 char*
char ch = 'a';
char* pc = &ch;
有时候也可以让字符指针指向字符串
char* p = "abcdef";//此时 p 里存着的是 a 的地址
const char* p = "abdef";//这样指向的字符串就不能通过 *p 进行修改了。
字符指针例题
指针数组是数组
int* arr[5]; //存放整型指针的数组
char* str[5]; //存放字符指针的数组
指针数组的定义格式
int* p1[5];
1. 模拟二维数组
int arr1[] = {1,2,3,4};
int arr2[] = {2,2,3,4};
int arr3[] = {3,2,3,4};
int* parr[] = {arr1,arr2,arr3};//parr 数组就是指针数组
2. 指向字符指针
数组指针是指针
数组名的理解
数组指针的定义
int arr[10] = {0};
int (*parr)[10] = &arr;//parr 用来存放数组的地址,parr 就是数组指针。
int arr[] = {1,2,3,4,5};
int (*p)[5] = &arr;
printf("%d\n",(*p)[2]);//*p <==> arr
管理二维数组
//parr 存储第一行的地址,[4] 表示每行有 4 列
void print(int(*parr)[4],int row,int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
//printf("%d ", parr[i][j]);
printf("%d ", *(*(parr + i) + j));//这两种写法等价
}
putchar('\n');
}
}
int main()
{
int arr[4][4] = { {1,2,3,4},{2,2,3,4},{3,2,3,4},{4,2,3,4} };
print(arr, 4, 4);//传第一行的地址过去
return 0;
}
分析下面代码的的意思
int (*parr[10])[5];
void test(int arr[]) //1:√
{}
void test(int arr[10]) //2:√
{}
void test(int* arr) //3:√
{}
void test2(int* arr[20])//4:√
{}
void test2(int** arr) //5:√
{}
int main()
{
int arr[10] = { 0 }; //每个元素都是 int 类型的变量
int* arr2[20] = { 0 }; //每个元素都是 int* 类型的变量
test(arr);
test2(arr2);
return 0;
}
void test(int arr[3][5]) //1:√
{}
void test(int arr[][]) //2:×
{}
void test(int arr[][5]) //3:√
{}
void test(int* arr) //4:×
{}
void test(int* arr[5]) //5:×
{}
void test(int(*arr)[5]) //6:√
{}
void test(int** arr) //7:×
{}
int main()
{
int arr[3][5] = { 0 };
test(arr);
}
void print(int* p, int sz)//用一级指针接收传过来的数组首元素地,可行。
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d\n", *(p + i));
}
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9 };
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
print(p, sz);//一级指针p,传给函数
return 0;
}
void test(int** ptr) //ptr 是用来接收一级指针的地址的
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int* p = &n;
int** pp = &p;
test(pp); //将 pp 里存着的 p 的地址传过去
test(&p); //直接将 p 的地址传过去
return 0;
}
函数指针的定义格式
返回类型 (*指针变量名)(指向的函数的参数类型)
如何得到函数的地址?
定义函数指针
int (*pf)(int,int) = &add;
int (*pf)(int,int) = add;
//这两种形式都能将 add 的地址赋给函数指针 pf
函数指针的使用
函数指针数组的概念
函数指针数组的定义
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int mul(int x, int y)
{
return x * y;
}
int div(int x, int y)
{
return x / y;
}
int(*pfarr[])(int, int) = { add,sub,mul,div };//pfarr 就是函数指针数组
函数指针数组的调用
使用函数指针数组实现计算器
void menu(void)
{
printf("|----------------------------------|\n");
printf("|1.加法 2.减法 3.乘法 4.除法 0.退出|\n");
printf("|----------------------------------|\n");
}
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int mul(int x, int y)
{
return x * y;
}
int div(int x, int y)
{
return x / y;
}
void calc(int (*pfarr[])(int, int), int input)
{
int a = 0;
int b = 0;
printf("输入要计算的两个数\n");
scanf("%d %d", &a, &b);
printf("%d\n", pfarr[input](a, b));
}
int main()
{
int i = 0;
int input = 0;
int(*pfarr[])(int, int) = { 0,add,sub,mul,div };
//塞个 0 放到下标为 0 的位置,确保输入和实际函数的位置相同
int sz = sizeof(pfarr) / sizeof(pfarr[0]);
do
{
menu();
printf("选择你的操作\n");
scanf("%d", &input);
if (input >= 1 && input < sz)
{
calc(pfarr, input);//根据输入的数调用数组对应位置的计算器功能
}
else if (0 == input)
{
printf("退出计算器\n");
break;
}
else
{
printf("选择错误,请重试\n");
}
} while (input);
return 0;
}
函数指针数组指针的定义
int main()
{
int (*pfarr)(int,int) = {0,add,sub,mul,div};//函数指针数组
int (*(*ppfarr)[5])(int,int) = &pfarr; //指向 (函数指针数组) 的指针
return 0;
}
回调函数的概念
举个栗子
void calc(int (*pf)(int, int))
{
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
printf("%d\n", pf(x, y));
}
int add(int x ,int y)
{
return x + y;
}
int main()
{
calc(add);
return 0;
}