本文共 3340 字,大约阅读时间需要 11 分钟。
在之前学习数组的时候接触过指针,我们可以了解到指针和数组之间并没有关系,看前面的文章回顾一下:
那么到底什么是指针数组 ,数组指针 ,函数指针, 函数指针数组, 指向函数指针数组的指针呢?接下来我们就深入的学习下指针。
【指针数组】
一.定义:简单来说就是存放指针的数组。首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。
二.代码表示定义:
int *arr1[10];char *arr2[5];char **arr3[5];
int *arr1[10]的理解 :这里需要明白一个符号之间的优先级问题。“[]”的优先级比“*”要高。arr1先与“[]”结合,构成一个数组的定义, 数组名为arr1,int* 修饰的是数组的内容,即数组的每个元素;所以int *arr1[10] 就是一个数组,其包含10个指向int类型数据的指针。
【数组指针】
一.定义:数组指针就是指针。首先它是一个指针,它指向一个数组。在32位系统下永远是占4个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称。
二.代码表示定义:
int (*p)[10];
int (*p)[10]的理解:在这里“()”的优先级比“[]”高,“*”号和p构成一个指针的定义,指针变量名为p,int修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。所以p是一个指针,它指向一个包含10个int类型数据的数组,即数组指针。
注意:只要数组指针int (*p)[10],其中10不可以改为其他数字,更不可以不写,因为数组大小也是判定数组类型相同的一个指标,比如在数组传参时第二个维数不可以省略一样。
三.指针数组的应用:
#include#include int main(){ int arr[10] = { 0 }; int *p1 = arr; int(*p2)[10] = &arr + 1; printf("%p\n", arr);//整个数组地址;00D3FA2C printf("%p\n", arr+1);//下一个元素的地址;00D3FA30(首元素加4) printf("%p\n", &arr+1);//下一个数组的地址,即数组指针;00D3FA54(首元素加40) printf("%p\n", p1);//00D3FA2C printf("%p\n", p2);//00D3FA54 system("pause"); return 0;}
从上面代码可以看出,p2是数组指针,指向的是下一个数组。它 是存放数组地址的。
【函数指针】
一.定义:就是函数的指针,它是一个指针,指向一个函数。
二.代码表示定义:
char *(*fun)(char *p1, char *p2);
fun与*结合,是一个指针变量,它指向一个函数。这个函数有两个指针类型的参数,函数的返回值也是一个指针。
三.函数指针的使用:
#include#include #include char * fun(char * p1, char * p2){ int i = 0; i = strcmp(p1, p2); if (0 == i) { return p1; } else { return p2; }}int main(){ char * (*pf)(char * p1, char * p2)=fun;//定义一个函数指针pf //pf=&fun; char* ret=(*pf) ("aa", "bb"); printf("%s\n", ret);//bb system("pause"); return 0;}
我们使用指针的时候,需要通过*(解引用)来取其指向的内存里面的值,函数指针使用也如此。通过用(*pf)取出存在这个地址上的函数,然后调用它。
注意:给函数指针赋值时,可以用&fun或直接用函数名fun。这是因为函数名被编译之后其实就是一个地址,所以这里两种用法没有本质的差别。
【函数指针数组】
一.定义:把函数的地址存到一个数组中,那么这个数组就叫函数指针数组。
二.代码表示定义:
int main(){ int(*parr1[10])(); //int *parr2[10]();//语法报错“parr2”数组元素类型不能是函数 //int (*)() parr3[10];//语法错误:“)” system("pause"); return 0;}
所以正确定义函数指针数组为int(*parr1[10])(),它是一个数组,数组名为parr1,int (*)()是函数指针,则数组内存储了10个指向函数的指针。
三,函数指针数组的应用:转移表
编写一个计算器,可以使用switch循环语句选择case 来实现,但是这样运算量大,现在使用函数指针数组来实现,使之优化。
//计算器(函数指针数组):#include#include //选择运算:int my_add(int x, int y){ return x + y;}int my_sub(int x, int y){ return x - y;}int my_mul(int x, int y){ return x * y;}int my_div(int x, int y){ if (0==y) { printf("Error"); return -1; } else { return x / y; }}void menu(){ printf("**************************\n"); printf("***1.add 2.sub***\n"); printf("***3.mul 4.div***\n"); printf("*** 0.quit***\n"); printf("**************************\n"); printf("please select");}int main(){ int(*p[5])(int x, int y) = { 0,my_add, my_sub, my_mul, my_div };//定义函数指针数组直接可以内访问数组内的函数指针。 int input = 0; int ret = 0; do{ menu(); scanf_s("%d", &input); if (input >= 1 && input <= 4) { int x, y; printf("Please Input Your Data For Cal :"); scanf_s("%d%d", &x,&y); ret = (*p[input])(x, y); printf("Result:%d\n", ret); } else if (input == 0) { printf("Bye!\n"); break; } else { printf("You Input Error,Please Inpue[1,4]\n"); } } while (1); system("pause"); return 0;}
打印结果是:
【指向函数指针数组的指针】
一,定义:函数指针数组指针就是一个指针。只不过这个指针指向一个数组,这个数组里面存的都是指向函数的指针。
二.代码表示定义:
char (*(*pf)[10])(char *p)
理解:pf是指针。这个指针指向一个包含了10个元素的数组;这个数字里面存的是指向函数的指针<char (*)()>;这些指针指向一些返回值类型为指向字符的指针、参数为一个向字符的指针的函数。