目录
在指针的类型中我们知道有一种指针类型为字符指针 char* ;



这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。

int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5];//二级字符指针的数组


3.数组指针 数组指针是指针!

int *p1[10];
int (*p2)[10];
//p1, p2分别是什么?
int (*p)[10];
//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。
//这里要注意:[ ]的优先级要高于*号的,所以必须加上()来保证p先和*结合。


根据上面的代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。
实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下) 本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型 数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.
既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。


第2种方法一般用在二维数组中:







- int Add(int x, int y)
- {
- return x + y;
- }
- int main()
- {
- int arr[10] = { 0 };
- printf("%p\n", &arr);//取数组地址
- printf("%p\n", &arr);//取数组地址
-
- printf("%p\n", Add);//取函数地址(这两个没什么区别,拿到的都是函数的地址)
- printf("%p\n", &Add);//取函数地址
-
- int (*pf)(int x, int y) = &Add;//pf就是函数指针变量
-
- return 0;
- }



- int main()
- {
- //代码1
- (*(void (*)())0)();
- //void (*)()-->函数指针
- //(void (*)())0-->强制类型转换-->把0转换一个函数的地址
- //(*(void (*)())0)()-->把0转换成一个(void (*)())类型的函数指针,然后去调用0地址的函数
-
- typedef void(*pf_t)(int);//pf_t放在里面
-
- //代码2
- void (*signal(int, void(*)(int)))(int);
- pf_t signal(int, pf_t);
- //上述代码是一次函数声明
- //声明的函数叫:signal
- //signal函数的第一个参数是int类型
- //signal函数的第二个参数是一个函数指针类型,该函数指针指向的函数参数是int,返回类型是void
- //signal函数的返回类型也是一个函数指针类型,该函数指针指向的函数参数是int,返回类型是void
- //
- return 0;
- }
要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?

- int Add(int x, int y)
- {
- return x + y;
- }
- int Sub(int x, int y)
- {
- return x - y;
- }
- int main()
- {
- int(*pf)(int, int);//函数指针
- //函数指针数组-->可以存放多个【参数相同,返回类型相同】的函数的地址
- int (*pfArr[2])(int, int) = { Add,Sub };//[]优先级高于*
-
- int ret = pfArr[1](2, 3);
- printf("ret = %d\n", ret);
- ret = pfArr[0](2, 3);
- printf("ret = %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;
- do
- {
- menu();
- printf("请选择:>");
- scanf("%d", &input);
-
-
- switch (input)
- {
- case 1:
- printf("请输入两个操作数:>");
- scanf("%d %d", &x, &y);
- ret = Add(x, y);
- printf("%d\n", ret);
- break;
- case 2:
- printf("请输入两个操作数:>");
- scanf("%d %d", &x, &y);
- ret = Sub(x, y);
- printf("%d\n", ret);
- break;
- case 3:
- printf("请输入两个操作数:>");
- scanf("%d %d", &x, &y);
- ret = Mul(x, y);
- printf("%d\n", ret);
- break;
- case 4:
- printf("请输入两个操作数:>");
- scanf("%d %d", &x, &y);
- ret = Div(x, y);
- printf("%d\n", ret);
- break;
- case 0:
- printf("退出计算机\n");
- break;
- default:
- printf("选择错误\n");
- break;
- }
- } while (input);
- 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 (*pfArr[5])(int, int) = { 0,Add,Sub,Mul,Div };
- do
- {
- menu();
- printf("请选择:>");
- scanf("%d", &input);
- if (input = 0)
- {
- printf("退出计算机\n");
- break;
- }
- if (input >= 1 && input <= 4)
- {
- printf("请输入两个操作数:>");
- scanf("%d %d", &x, &y);
- ret = pfArr[input](x, y);
- printf("%d\n", ret);
- }
- else
- {
- printf("选择错误!\n");
-
- }
- } while (input);
- return 0;
- }
指向函数指针数组的指针是一个 指针。
指针指向一个数组 ,数组的元素都是函数指针。

- void test(const char* str)
- {
- printf("%s\n", str);
- }
- int main()
- {
- //函数指针pfun
- void (*pfun)(const char*) = test;
- //函数指针的数组pfunArr
- void (*pfunArr[5])(const char* str);
- pfunArr[0] = test;
- //指向函数指针数组pfunArr的指针ppfunArr
- void (*(*ppfunArr)[5])(const char*) = &pfunArr;
- return 0;
- }