指针数组
指针数组是一个存放指针的数组
如
int *arr1[10];
char *arr2[10] = {"hello", "world", "123",};
char **arr3[5];
数组指针
数组指针的定义
int [10]即为p的类型
数组指针的使用
数组地址的存储
int arr1[10];
int(*p)[10] = &arr1;
int *arr2[10];
int* (*p1)[10] = &arr2;
int **p2 = arr2;
二维数组的传参
例如
int main()
{
int arr[3][5] = { 0, 1, 2 };
test(arr);
return 0;
}
在这里,我们test()函数的参数进行设计
void test(int arr[3][5])
{
printf("%d\n", arr[0][1]);
}
void test(int (*arr)[5])
{
printf("%d\n", *(*(arr)+1));
}
存放数组指针的数组
int(*p[10])[5]; //存放数组指针的数组
//p先与[]结合,说明p是一个数组,数组有10个元素
//然后我们去掉p[10],即int(* )[5],即数组p的类型
//int(*p[10])[5]表示一个存放数组指针的数组,这个数组有10个元素,每个元素都是一个数组指针,指向有5个元素,类型为int的数组
指针和数组的定义与声明
我们创建两个源文件tesc.c和main.c,分别写入不同的代码
例1
char arr[] = "abcdef";
main.c
extern char *arr;
int main()
{
printf("%s\n", arr);
return 0;
}
在这里,我们在test.c中定义arr有7个字节;在main.c中声明时只声明了4个字节;由于声明和定义使用的是同一块空间,所以,在main.c的角度,arr只声明了4个字节,即arr占用的是“abcd”4个字节,但在输出时,arr是当作一个地址来输出的,即把“abcd”当作地址输出,所以内存访问出错
改正
printf("%s\n", (char *)&arr);
例2
test.c
char *p = "abcdef";
main.c
extern char p[];
int main()
{
printf("%s\n", p);
return 0;
}
在test.c中,p为4个字节,即a的地址;在main.c中,p[ ]最多有4个元素;p表示数组名,表示在test.c中首元素的地址,输出时,把a的地址当成4个字符输出。
改正
printf("%s\n",(char *) * (int *) p);
printf("%s\n", *(char **)p);
函数指针
函数指针
函数指针的定义
void ()即为pfun的类型
函数指针数组
函数指针数组的定义
int ()即数组pfun的类型
函数指针数组的应用-转移表
例如:计算器
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 main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, Add, Sub, Mul, Div }; //转移表
while (input)
{
printf("************************\n");
printf("**** 1.add 2.sub ****\n");
printf("**** 3.mul 4.dov ****\n");
printf("**** 0.exit ****\n");
printf("************************\n");
printf("请选择:");
scanf("%d", &input);
if (input <= 4 && input >= 1)
{
printf("输入操作数:");
scanf("%d %d", &x, &y);
ret = (*p[input])(x, y); //调用
printf("ret = %d\n", ret);
}
else
{
break;
}
//switch (input)
//{
//case 1:
// printf("请输入操作数:");
// scanf("%d %d", &x, &y);
// ret = Add(x, y);
// break;
//case 2:
// printf("请输入操作数:");
// scanf("%d %d", &x, &y);
// ret = Sub(x, y);
// break;
//case 3:
// printf("请输入操作数:");
// scanf("%d %d", &x, &y);
// ret = Mul(x, y);
// break;
//case 4:
// printf("请输入操作数:");
// scanf("%d %d", &x, &y);
// ret = Div(x, y);
// break;
//case 0:
// break;
//}
//if (input)
// printf("ret = %d\n", ret);
}
return 0;
}
指向函数指针数组的指针
指向函数指针数组的指针的定义
void (*pfunarr[5])(int x) = { test };
(*pfunarr[0])(1);
void (*(*ppfunarr)[5])(int x) = &pfunarr;
总结
int *arr[5];
int (*p)[5];
int (*parr[10])[5];
void (*pfun)();
int (*pfun[10])();
void (*(*ppfunarr)[5])(int x);