指针数组与多级指针

指针数组

由于指针本身也是变量,所以一组同类指针也可以像其它变量一样形成一个数组。如果一个数组的元素均为某一类型的指针,则称该数组为指针数组

语法如下:

类型名 *数组名[数组长度];
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);
}

值得注意的是:这段代码中的字符串数组应该按照字母顺序排列,否则二分查找算法无法正确找到对应的字符串索引位置。

C语言之指针(下)_二维数组

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);
}

C语言之指针(下)_二维数组_02

二维数组与指向一维数组的指针

语法:

基类型 (*指针变量名)[一维数组的规模];

案例:通用的二维数组输入/输出函数。

#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语言之指针(下)_ci_03

动态二维数组

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语言之指针(下)_#include_04

函数指针

指向函数的指针

在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==' ';
}

C语言之指针(下)_ci_05

案例2:设计一个计算某个函数定积分的函数。

定积分的物理意义是某个函数与x轴围成的区域面积。

图示:

C语言之指针(下)_#include_06

#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);
}

以上两个代码片段都是不完整的,具体功能需要自行添加。

完整代码我将会在下一章节贴出来。