指针数组与多级指针
指针数组
由于指针本身也是变量,所以一组同类指针也可以像其它变量一样形成一个数组。如果一个数组的元素均为某一类型的指针,则称该数组为指针数组。
语法如下:
类型名 *数组名[数组长度];
char *string[10];
案例:编写一个函数,用二分法查找某一个城市名在城市表中是否出现,要求用递归实现。
#include<stdio.h>
#include<string.h>
int binarySearch(char *table[],int lh,int rh,char *str)
{
int mid,result;
if(lh<=rh){
mid=(lh+rh)/2;
result=strcmp(table[mid],str);
if(result==0){
return mid;
} else if(result>0){
return binarySearch(table,lh,mid-1,str); //往左一半找
}else{
return binarySearch(table,mid+1,rh,str); //往右一半找
}
}
return -1; //没有找到
}
int main(){
char *city[6]={"beijing","guangzhou","jilin","shenzhen","wuhan","xianyang"};
printf("shenzhen出现在%d\n",binarySearch(city,0,5,"shenzhen"));
printf("beijing出现在%d\n",binarySearch(city,0,5,"beijing"));
return(0);
}
值得注意的是:这段代码中的字符串数组应该按照字母顺序排列,否则二分查找算法无法正确找到对应的字符串索引位置。
main函数的参数
案例:求n个正整数的平均值的程序。
课本上给出的代码如下:
#include<stdio.h>
int ConvertStringToInt(char *s)
{
int num=0;
while(*s){
num=num*10+*s-'0';
++s;
}
return num;
}
int main(int argc,char *argv[]){
int sum=0;
for(int i=1;i<=argc;i++)
sum+=ConvertStringToInt(argv[i]);
printf("%d\n",sum/(argc-1));
return(0);
}
我暂时弄不清楚它到底想干嘛,懵了。这是啥操作???
多级指针
在定义指针变量时,指针变量所指向的变量的类型可以是任意类型。如果一个指针变量所指向的变量的类型是指针类型,则称为多级指针。如:
int x=15,*p=&x,**q=&p; //同理,三级指针:类型名 ***变量名;
案例:用指向指针的指针访问指针数组
#include<stdio.h>
int main(){
char **p,*city[]={"aa","bb","cc","dd","ee"};
for(p=city;p<city+5;++p){
printf("%s\n",*p);
}
return(0);
}
二维数组与指向一维数组的指针
语法:
基类型 (*指针变量名)[一维数组的规模];
案例:通用的二维数组输入/输出函数。
#include <stdio.h>
void inputMatrix(int *a,int row,int col);
void displayMatrix(int *a,int row,int col);
int main()
{
int array[5][4];
inputMatrix((int *)array,5,4);
displayMatrix(&array[0][0],5,4);
return(0);
}
void inputMatrix(int *a,int row,int col)
{
int i,j;
for(i=0;i<row;++i){
printf("\n请输入第%d行的%d个元素:",i+1,col);
for(j=0;j<col;++j)
scanf("%d",a+i*col+j);
}
}
void displayMatrix(int *a,int row,int col)
{
int i,j;
for(i=0;i<row;++i){
printf("\n");
for(j=0;j<col;++j)
printf("%d\t",*(a+i*col+j));
}
}
动态二维数组
C语言不支持直接申请动态的二维数组,申请一个动态的二维数组需要程序员自己解决。最简单的方法是将二维数组转换成一维数组。例如需要一个3行4列的整型二维数组,可以申请一个12个元素的一维数组。
案例:动态的二维数组。
#include <stdio.h>
int main()
{
int **a,i,j,k=0;
a=(int **)calloc(3,sizeof(int *));
for(i=0;i<3;++i){
a[i]=(int *)calloc(4,sizeof(int));
}
for(i=0;i<3;++i){
for(j=0;j<4;++j){
a[i][j]=k++;
}
}
for(i=0;i<3;++i){
printf("\n");
for(j=0;j<4;++j){
printf("%d\t",a[i][j]);
}
}
for(i=0;i<3;++i){
free(a[i]);
}
free(a);
return(0);
}
函数指针
指向函数的指针
在C语言中,指针可以指向一个整型变量、实型变量、字符串、数组等,也可以指向一个函数。所谓指针指向一个函数就是让指针保存这个函数的入口地址,以后就可以通过这个指针调用某一个函数,这样的指针称为指向函数的指针。
指向函数的指针主要有两个作用:作为另一个函数的参数以及用于实现菜单选择。
函数指针作为函数参数
指向函数的指针最常见的应用是将函数作为另一个函数的参数。
案例1:设计一个函数count,可以根据用户的需要统计一个字符串中的各种字符数,如大小写字母,数字,空格等。
#include <stdio.h>
int count(char *str,int (*f)(char));
int isUpper(char ch);
int isSpace(char ch);
int main()
{
char *s="I am a daughter.";
printf("%s中有%d个大写字母\n",s,count(s,isUpper));
printf("%s中有%d个空格\n",s,count(s,isSpace));
return(0);
}
int count(char *str,int (*f)(char))
{
int cnt=0;
while(*str){
if(f(*str)) ++cnt;
++str;
}
return cnt;
}
int isUpper(char ch)
{
return ch<='Z' && ch>='A';
}
int isSpace(char ch)
{
return ch==' ';
}
案例2:设计一个计算某个函数定积分的函数。
定积分的物理意义是某个函数与x轴围成的区域面积。
图示:
#include <stdio.h>
double f(double x);
double integral(double (*f)(double),double,double);
int main()
{
printf("%f",integral(f,0,2));
return(0);
}
double f(double x)
{
return x;
}
double integral(double (*f)(double),double a,double b)
{
double s=0,x;
for(x=a+0.005;x<=b;x+=0.01){
s+=0.01*f(x);
}
return s;
}
//该函数计算了f(x)=x在[0,2]上的积分,输出结果为:2.000000
函数指针用于菜单选择
案例:设计一个工资管理系统,要求系统具有如下功能:添加员工、删除员工、修改员工信息、打印工资单、打印汇总表。
#include <stdio.h>
int main()
{
int select;
while(1){
printf("1--add\n");
printf("2--erase\n");
printf("3--modify\n");
printf("4--print salary\n");
printf("5--print report\n");
printf("0--quit\n");
scanf("%d",&select);
switch(select){
case 0:return 0;break;
case 1:add();break;
case 2:erase();break;
case 3:modify();break;
case 4:printSalary();break;
case 5:printReport();break;
default:printf("input error\n");
}
}
return(0);
}
如果用函数指针又该如何实现呢?
#include <stdio.h>
int main()
{
int select;
void (*func[6])()={null,add,erase,modify,printSalary,printReport};
while(1){
printf("1--add\n");
printf("2--erase\n");
printf("3--modify\n");
printf("4--print salary\n");
printf("5--print report\n");
printf("0--quit\n");
scanf("%d",&select);
if(select==0) return 0;
if(select >5 || select<0){
printf("input error\n");
}else{
func[select]();
}
}
return(0);
}
以上两个代码片段都是不完整的,具体功能需要自行添加。
完整代码我将会在下一章节贴出来。