• 指针--用指针变量作函数参数的实例(按值调用与模拟按引用调用)、函数指针及其应用


    一、用指针变量作函数参数的实例

    思考题:
    例题:从键盘输入某班学生某门课成绩(每班人数最多不超过40人,具体人数由键盘输入),是分析下列程序是否能实现计算并输出最高分以及相应学号。

    #include 
    #define N 40
    void FindMax(int score[],long num[],int n,int pmaxscore,long pmaxnum);
    int main(void)
    {
    	int score[N],maxscore;
    	int n,i;
    	long num[N],maxnum;
    	printf("How many students?");
    	scanf("%d",&n);
    	printf("Input student`s ID and score:\n");
    	for(i=0;i<n;i++)
    	{
    		scanf("%ld%d",&num[i],&score[i]);
    	}
    	FindMax(score,num,n,maxscore,maxnum);
    	printf("maxscore = %d,maxnum = %ld\n",maxscore,maxnum);
    	return 0;
     } 
     
     void FindMax(int score[],long num[],int n,int pmaxscore,long pmaxnum)
     {
     	int i;
     	pmaxscore = score[0];
     	pmaxnum = num[0];
     	for(i=1;i<n;i++)
     	{
     		if(score[i]>pmaxscore)
     		{
     			pmaxscore = score[i];
     			pmaxnum = num[i];
    		 }
    	 }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述
    错误的原因在于用普通变量作函数参数进行按值调用不能再被调函数中改变相应的参数值。虽然可以用return 语句返回最高值,但return 只能返回一个值,要的到最高分即学号这样的两个值,必须使用指针变量作函数参数,即模拟按引用调用,因此需要将程序修改如下:

    #include 
    #define N 40
    void FindMax(int score[],long num[],int n,int *pmaxscore,long *pmaxnum);
    int main(void)
    {
    	int score[N],maxscore;
    	int n,i;
    	long num[N],maxnum;
    	printf("How many students?");
    	printf("\n");
    	scanf("%d",&n);
    	printf("Input student`s ID and score:\n");
    	for(i=0;i<n;i++)
    	{
    		scanf("%ld%d",&num[i],&score[i]);
    	}
    	FindMax(score,num,n,&maxscore,&maxnum);
    	printf("maxscore = %d,maxnum = %ld\n",maxscore,maxnum);
    	return 0;
     } 
     
     void FindMax(int score[],long num[],int n,int *pmaxscore,long *pmaxnum)
     {
     	int i;
     	*pmaxscore = score[0];
     	*pmaxnum = num[0];
     	printf("\n");
     	for(i=1;i<n;i++)
     	{
     		if(score[i]>*pmaxscore)
     		{
     			*pmaxscore = score[i];
     			*pmaxnum = num[i];
    		 }
    	 }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    指针梳理:创建变量pmaxscore pmaxnum为整形,“FindMax(score,num,n,&maxscore,&maxnum);”
    这句中&调用地址,传递给findmax,再通过值得对比,获得最大值,
    “printf(“maxscore = %d,maxnum = %ld\n”,maxscore,maxnum);”
    这句打印得就是获得得最大值。
    在这里插入图片描述
    由于指针形参所指向的变量的值在函数调用结束后才能被确定,因此这两个指针形参称为函数的出口参数,函数FindMax()的前三个形参再函数调用前必须确定其值,因此称为函数的入口参数。

    这个题目得另一个解法:(我只做简要得原理论述,程序相对简单,容易理解)

    #include 
    #define n 4
    int score[n];
    
    void Sum(int score[],int *sum)
    {
    	int i;
    	for(i=1;i<n;i++)
    	{
    		*sum=*sum+score[i];
    	}
    }
    
    int main()
    {
    	int *sum=&score[0];
    	int i;
    	printf("shuru:");
    	for(i=0;i<n;i++)
    	{
    		scanf("%d",&score[i]);
    	 } 
    	 Sum(score,sum);
    	 printf("%d",*sum);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    该程序通过直接获取数组首地址,传入函数Sum中,进行处理,最后返回需要得答案。
    在这里插入图片描述

    指针得使用非常重要,需要读者进行理解,练习。

    二、函数指针及其应用
    函数指针(Function Pointers)就是指向函数得指针(Pointer to a Function)
    指向函数得指针变量存储得是一个函数再内存中得入口地址。
    冯·诺依曼体系结构强调程序与数据共同存储再内存中,函数是子程序,当然也存储在内存中,指向存储这个函数得第一条指令得地址,称为函数得入口地址。
    在前面我们了解到一个数组名其实就是存储数组第一个元素得内存地址,同理,一个函数名就是这个函数得源代码在内存中得起始地址,编译器将不带()得函数名解释为该函数得入口地址,函数指针在某些场合是非常有用的。
    例题:
    对输入学生得数据进行排序(升序、降序)

    #include 
    
    #define N 40
    int readscore(int score[]);
    void printscore(int score[],int n); 
    void ascendingsort(int a[],int n);
    void descendingsort(int a[],int n);
    void swap(int *x,int *y);
    
    int main(void)
    {
    	int score[N],n;
    	int order;
    	n=readscore(score);
    	printf("Total students are %d\n",n);
    	printf("Enter 1 to sort in ascending order,\n");
    	printf("Enter 2 to sort in descending order:");
    	scanf("%d",&order);
    	printf("Data items in original order \n");
    	printscore(score,n);
    	if(order==1)
    	{
    		ascendingsort(score,n);
    		printf("Data items in ascending order\n");
    	}
    	else
    	{
    		descendingsort(score,n);
    		printf("Data items in descending order\n");
    	}
    	printscore(score,n);
    	return 0;
    }
    
    int readscore(int score[])
    {
    	int i=-1;
    	do{
    		i++;
    		printf("Input score:");
    		scanf("%d",&score[i]);
    	}while(score[i]>=0);
    	return i;
    }
    
    void printscore(int score[],int n)
    {
    	int i;
    	for(i=0;i<n;i++)
    	{
    		printf("%4d",score[i]);
    	}
    	printf("\n");
    }
    
    void ascendingsort(int a[],int n)
    {
    	int i,j,k;
    	for(i=0;i<n-1;i++)
    	{
    		k=i;
    		for(j=i+1;j<n;j++)
    		{
    			if(a[j]<a[k]) k=j;
    		}
    		if(k!=i) swap(&a[k],&a[i]);
    	}
    }
    
    void descendingsort(int a[],int n)
    {
    	int i,j,k;
    	for(i=0;i<n-1;i++)
    	{
    		k=i;
    		for(j=i+1;j<n;j++)
    		{
    			if(a[j]>a[k]) k=j;
    		}
    		if(k!=j) swap(&a[k],&a[i]);
    	}
    }
    
    void swap(int *x,int *y)
    {
    	int temp;
    	temp=*x;
    	*x=*y;
    	*y=temp;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    在这里插入图片描述
    在这里插入图片描述
    修改程序,将升降排序合二为一:

    #include 
    
    #define N 40
    int readscore(int score[]);
    void printscore(int score[],int n); 
    void selectionsort(int a[],int n,int (*compare)(int a,int b));
    int ascendingsort(int a,int b);
    int descendingsort(int a,int b);
    void swap(int *x,int *y);
    
    int main(void)
    {
    	int score[N],n;
    	int order;
    	n=readscore(score);
    	printf("Total students are %d\n",n);
    	printf("Enter 1 to sort in ascending order,\n");
    	printf("Enter 2 to sort in descending order:");
    	scanf("%d",&order);
    	printf("Data items in original order \n");
    	printscore(score,n);
    	if(order==1)
    	{
    		selectionsort(score,n,ascendingsort);//函数指针指向ascending() 
    		printf("Data items in ascending order\n");
    	}
    	else
    	{
    		selectionsort(score,n,descendingsort);//函数指针指向descending()
    		printf("Data items in descending order\n");
    	}
    	printscore(score,n);
    	return 0;
    }
    
    int readscore(int score[])
    {
    	int i=-1;
    	do{
    		i++;
    		printf("Input score:");
    		scanf("%d",&score[i]);
    	}while(score[i]>=0);
    	return i;
    }
    
    void printscore(int score[],int n)
    {
    	int i;
    	for(i=0;i<n;i++)
    	{
    		printf("%4d",score[i]);
    	}
    	printf("\n");
    }
    //函数功能:调用函数指针compare指向得函数实现对数组a的交换法排序
    void selectionsort(int a[],int n,int (*compare)(int a,int b))
    {
    	int i,j,k;
    	for(i=0;i<n-1;i++)
    	{
    		k=i;
    		for(j=i+1;j<n;j++)
    		{
    			if((*compare)(a[j],a[k]))k=j;
    		}
    		if(k!=i)  swap(&a[k],&a[i]);
    	}
     } 
    int ascendingsort(int a,int b)
    {
    	return a<b;
    }
    int descendingsort(int a,int b)
    {
    	return a>b;
    }
    
    void swap(int *x,int *y)
    {
    	int temp;
    	temp=*x;
    	*x=*y;
    	*y=temp;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    在这里插入图片描述
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FJntlZWx-1686370230305)(null)]
    过于int (*compare)(int a,int b)
    圆括号的优先级是最高的,因此这句话可以解释为:
    compare-----> * -------> ( ) ------->int
    他告诉编译器函数selectionsort()的这个形参compare是一个指针类型,该指针变量可以指向一个两个整形形参、返回值为整形的函数。即compare是一个函数指针。这里,*compare两侧的圆括号必不可少,他将 * 和compare先结合,表示compare是一个指针变量。然后,(*compare)与其后的()结合,表示该指针变量可以指向一个函数。

    如果少去了compare两边的括号,就会变成
    compare-----》()-------》 * ---------》 int
    因此,它声明的不是一个函数指针,而是一个两个整型形参并返回整形指针的函数。

  • 相关阅读:
    SpringMVC五种数据提交方式的优化
    给定DNA序列,查找有效匹配子串
    PMP最新考纲难在哪里?面对新教材的来袭,我该怎么计划考试?
    python机器学习基础教程02-鸢尾花分类
    Python语言学习:Python语言学习之文件读取&写入/操作系统(OS模块详解)的简介、案例应用之详细攻略
    奇安信 测试|测试开发 面试真题|面经 汇总
    Workfine新手入门:数据规范之进度条
    PG14启动报错“max_stack_depth“ must not exceed 7680kB
    警惕 有种过敏叫“牛奶蛋白过敏”
    java计算机毕业设计高校实习实训管理系统源码+mysql数据库+系统+lw文档+部署
  • 原文地址:https://blog.csdn.net/ww1425408527/article/details/131138899