很容易混淆的概念其实并不难理解
1,指针数组;
看字面意思就知道这一定是一个数组,里面的原酸全部是指针
例如,定义一个简单的指针数组
char *p[10]; //这就是一个包含十个字符指针的数组。
例:
#include<stdio.h>
int main()
{
char *p[7];
char arr[] = "abcdef";
int i = 0;
for (i = 0; i < 7; i++)
{
p[i] = arr;
}
printf("%s", p[6]);
}
输出结果是abcdef.
这个简单的程序就用到了指针数组,他定义了一个数组包含了7个字符指针,for循环每一个指针都指向了arr数组定义的字符串。
2,数组指针
从名字上看就能知道他是一个指针,是一个指向数组的指针。
例如:
#include<stdio.h>
int main()
{
char arr[6] = "abcde";
char(*p)[6] = &arr; //数组指针才能取数组的地址。
printf("%s", *p);
}
这个简单的程序最后的输出结果当然是arr字符数组中的内容了。
通过数组指针也能更改数组中的内容,对于上面的程序*((*p)+1)=‘a‘;就把第二个元素改成了‘a’;*p便是arr的地址。
3,函数指针
一样,从名字上看,这便是一个指向函数的指针,他是如何定义的呢,
例:
int num(int a,int b)
{
return a+b;
}
int mian()
{
int (*p)(int ,int )=num; //这便是一个指向num函数的一个函数指针了,int 是函数的返回值,
后面是数据类型,它所指向的函数必须和他有同样的返回值和数据类型。
int ret=(*p)(10,20);
printf("%d",ret);//结果是30.
}
4,函数指针数组
从名字上也能看楚这首先是一个数组,数组元素是指针,而每一个指针都指向了一个函数,这个麻烦的东西有什么用了,
事实证明他在某些地方非常有用处,首先来看他是如何定义的
例:
int (*p[4])(int ,int)
//这便是一个有4个元素的函数指针数组了,这个数组中的每一个指针指向的函数必须是一样的数据类型和返回值。
具体有什么用我们来看一段代码。
这个代码是一个简单的计算器。
#include <stdio.h> void print_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) { if (y == 0) { printf("除数为0\n"); return -1; } return x / y; } int(*pfun[5])(int, int) = {0,add, sub, mul, div}; //函数指针的数组(转移表) int main() { int input = 1; while (input) { int n1 = 0; int n2 = 0; int ret = 0; print_menu(); printf("请选择>:"); scanf("%d", &input); printf("请输入两个操作数>:"); scanf("%d%d", &n1, &n2); ret = pfun[input](n1, n2); /*switch (input) //如果不用函数指针数组便要用switch来实现,可以看出如果计算器功能很多,那么 代码也会相当庞大 { case 1: ret =add(n1,n2); break; case 2: ret = sub(n1, n2); break; case 3: ret = mul(n1, n2); break; case 4: ret = div(n1, n2); break; }*/ printf("ret = %d\n",ret); } return 0; }
可以看出此时函数指针数组大大减少了代码的长度。