26.指针数组和数组指针和函数指针和指针函数
指针数组 : 存放指针的数组
int main()
{
int arr[10];
//整形数组
int* arr2[5];
//(整形)指针数组 -->变量名是arr2类型是 int* [5]
return 0;
}
数组指针 :指向数组的指针
int main()
{
int arr[10] = { 0 };
int(*pArr)[10] = &arr; //数组指针,&arr表示整个数组的地址
char str[5] = { 0 };
char(*pStr)[5] = &str; //数组指针,&arr表示整个数组的地址
return 0;
}
使用一维数组指针
void ArrPrint(int arr[], int num) //(int* arr, int num)
{
int i = 0;
for (i = 0; i < num; i++)
{
printf("%d ",*(arr + i)); //arr[i]
}
printf("\n");
}
void ArrPrint1(int (*PArr)[10], int num)
{
int i = 0;
for (i = 0; i < num; i++)
{
//printf("%d ",(*parr)[i] );
printf("%d ", *((*parr)+i) );
}
printf("\n");
}
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7 ,8 ,9, 10 };
int num = sizeof(arr) / sizeof(int);
ArrPrint(arr, num); //arr表示数组的首元素地址
ArrPrint1(&arr, num);
return 0;
}
使用二维数组指针
void ArrPrint2(int arr[][5], int row, int col) //(int* arr, int num)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
//printf("%d ", arr[i][j]);
//printf("%d ", *(arr[i] + j));
printf("%d ", *( (*arr + i * col) + j));
}
}
printf("\n");
}
void ArrPrint3(int (*PArr)[5], 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));
printf("%d ", *( (*(PArr + i) + j) ) );
}
}
printf("\n");
}
int main()
{
int arr[3][5] = { 1, 2, 3, 4, 5,
6, 7 ,8 ,9, 10,
11, 12, 13, 14, 15 };
int num = sizeof(arr) / sizeof(int);
int col = sizeof(arr[0]) / sizeof(int);
int row = num / col;
ArrPrint2(arr, row, col); //arr表示二维数组的首元素地址(此时与一维数组首元素的意义是一样的)
ArrPrint3(arr, row, col); //arr表示二维数组首元素地址(是指二维数组真个第一行数组的地址)
return 0;
}
总结:
数组指针分一维和二维两种
对一维数组指针解引用有两种方式
(*parr)[i]
*((*parr)+i)
对二维数组指针解引用有三种方式
PArr[i][j]
*(PArr[i] + j)
*( (*(PArr + i) + j) )
函数指针 :指向函数地址的指针
int Add(int x, int y)
{
return x+y;
}
int main()
{
int arr[5];
int (*pa)[5] = &arr;
printf("%p\n", &Add);
printf("%p\n", Add);
int (*p)(int, int) = Add;//p是函数指针
int ret = p(2, 3); //注意*在这里是不体任何作用的int ret = *p(2, 3);
printf("%d\n", ret);
return 0;
}
typedef struct Stu
{
char name[20];
int age;
float score;
}Stu;
int main()
{
typedef unsigned int uint;
void (*signal(int, void(*)(int)))(int);
//简化
typedef void (*pfun_t)(int);
//void(*p)(int);
pfun_t signal(int, pfun_t);
//signal是一个函数声明
//signal函数有两个参数,第一个参数是int类型,
//第二个参数是函数指针类型
//该函数指针指向的函数,参数是int,返回类型是void
//signal函数的返回类型是一个函数指针,该函数指针指向的函数,
//参数是int,返回类型是void
return 0;
}
函数指针数组
对于函数指针数组的创建如下:
int my_strlen(const char*str)
{
int len = 0;
while (*(str + len++) != '\0');
return --len;
}
int main()
{
int* arr[10];
char* arr2[5];
//函数指针数组
char str[] = "xiao du zhen ke ai";
int (*ps)(const char*) = &my_strlen;
int (*ps2)(const char*) = &my_strlen;
int (*ps3)(const char*) = &my_strlen;
//int (*psArr[3])(const char*) = {ps, ps2, ps3};//函数指针数组
int (*psArr[3])(const char*) = { &my_strlen, &my_strlen, &my_strlen };//函数指针数组
int ret = psArr[0](str);
printf("length of str = %d \n",ret);
//存放函数指针的数组
return 0;
}
void menu()
{
printf("******************************\n");
printf("*** 1. add 2. sub ***\n");
printf("*** 3. mul 4. div ***\n");
printf("*** 0.exit ***\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;
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
//函数指针数组-转移表
int (*pArr[5])(int, int) = {0, Add, Sub, Mul, Div};
do
{
menu();
printf("请选择:>");
(void)scanf("%d", &input);
printf("请输入两个操作数:>");
(void)scanf("%d%d", &x, &y);
ret = pArr[input](x, y);
printf("ret = %d\n", ret);
} while (input);
return 0;
}
**总结: 函数指针无需解引用就能使用,解引用多次也不影响作用 函数指针最大的优势在于: 可以将参数个,数类型及返回值相同的函数归为一类函数放入函数指针数组中去,再以合适的判断条件去调用,就可以极大的简化重复使用的代码 **