零基础入门学习C语言009讲:指针(6)

版权声明:转载请标明出处 https://blog.csdn.net/qq_41556318/article/details/89737279

指向函数的指针

用函数指针变量调用函数

可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个函数的入口地址就称为函数的指针。

/****************************/
/* 比较a 和 b的大小,求大值 */
/****************************/

#include <stdio.h>

#if(0)
void main()
{
	int max(int, int);
	int a, b, c;

	scanf("%d %d", &a, &b);

	c = max(a, b);

	printf("a = %d, b = %d, max = %d\n\n", a, b, c);
}
#endif

int max(int x, int y)
{
	int z;

	if (x > y)
	{
		z = x;
	}
	else
	{
		z = y;
	}

	return z;
}

#if(1)
//将 main 函数改写为
#include <stdio.h>

void main()
{
	int max(int, int);
	int(*p)();
	int a, b, c;

	p = max;
	scanf("%d %d", &a, &b);

	c = (*p)(a, b);

	printf("a = %d, b = %d, max = %d\n\n", a, b, c);
}

#endif

用指向函数的指针作函数参数

函数指针变量常用的用途之一是把指针作为参数传递到其他函数。

前面介绍过,函数的参数可以是变量、指向变量的指针变量、数组名、指向数组的指针变量等。

现在介绍指向函数的指针也可以作为参数,以实现函数地址的传递,这样就能够在被调用的函数中使用实参函数。

它的原理可以简述如下:有一个函数(假设函数名为sub),它有两个形参(x1和x2),定义x1和x2为指向函数的指针变量。在调用函数sub时,实参为两个函数名f1和f2,给形参传递的是函数f1和f2的地址。这样在函数sub中就可以调用f1和f2函数了。

实战演练

题目:

设一个函数process,在调用它的时候,每次实现不同的功能。(有点类似多态)

输入a和b两个数,第一次调用process时找出a和b中大者,第二次找出其中小者,第三次求a与b之和。

/***********************************************************/
/*  设一个函数process,在调用它的时候,每次实现不同的功能。*/
/*  输入a和b两个数,第一次调用process时找出a和b中大者,*/
/*  第二次找出其中小者,第三次求a与b之和。               */
/***********************************************************/

#include <stdio.h>

void main()
{
	int max(int, int);            /* 函数声明 */
	int min(int, int);            /* 函数声明 */
	int add(int, int);            /* 函数声明 */

	void process(int x, int y, int(*fun)());    /* 函数声明 */

	int a, b;

	printf("Endter a and b: ");
	scanf("%d %d", &a, &b);

	printf("max = ");
	process(a, b, max);

	printf("min = ");
	process(a, b, min);

	printf("sum = ");
	process(a, b, add);
}

int max(int x, int y)              /* 函数定义 */
{
	int z;

	if (x > y)
	{
		z = x;
	}
	else
	{
		z = y;
	}

	return z;
}

int min(int x, int y)              /* 函数定义 */
{
	int z;

	if (x < y)
	{
		z = x;
	}
	else
	{
		z = y;
	}

	return z;
}

int add(int x, int y)
{
	int z;

	z = x + y;
	return z;
}

void process(int x, int y, int(*fun)())    /* 函数定义 */
{
	int result;

	result = (*fun)(x, y);
	printf("%d\n", result);
}

返回指针值的函数

一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。其概念与以前类似,只是带回的值的类型是指针类型而已。

这种带回指针值的函数,一般定义形式为

    类型名  *函数名(参数表列);

例如:

int *a(int x,int y);

例题讲解

有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。

#include <stdio.h>

void main()
{
	double score[][4] = { { 60.0, 70.0, 80.5, 90.5 }, { 56.0, 89.0, 67.0, 88.0 }, { 34.2, 78.5, 90.5, 66.0 } };
	double *search(double(*pointer)[4], int n);
	double *p;
	int i, m;

	printf("Please enter the number of student: ");
	scanf("%d", &m);

	printf("The scores of No.%d are: \n", m);

	p = search(score, m);

	for (i = 0; i < 4; i++)
	{
		printf("%5.2f\t", *(p + i));
	}

	printf("\n\n\n");
}

double *search(double(*pointer)[4], int n)
{
	double *pt;

	pt = *(pointer + n);

	return pt;
}

例题升级

对上例中的学生,找出其中有不及格课程的学生及其学生号。

#include <stdio.h>

void main()
{
	double score[][4] = { { 60.0, 70.0, 80.5, 90.5 }, { 56.0, 89.0, 67.0, 88.0 }, { 34.2, 78.5, 90.5, 66.0 } };
	double *search(double(*pointer)[4], int n);
	double *p;
	int i, m;
	printf("不及格的学生有:\n");
	for (i = 0; i < 3; i++)
	{
		search(score, i);
	}

	printf("\n\n\n");
}

double *search(double(*pointer)[4], int n)
{
	double *pt;

	pt = *(pointer + n);

	for (int i = 0; i < 4; i++)
	{
		if ((*pt+i)<60)
		{
			printf("%d号 ", n);
			break;
		}
	}
	
}

指针函数和函数指针的区别

这两个概念都是简称:

指针函数是指带指针的函数,即本质是一个函数。

函数指针是指向函数的指针变量,因而函数指针本身首先应是指针变量,只不过该指针变量指向函数。

指针数组和指向指针的指针

指针数组的概念:

一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为

类型名 数组名[数组长度];

例如:

int *name[4];

从实例来认识问题

#include <stdio.h>

void main()
{
	int a[5] = { 1, 3, 5, 7, 9 };
	int *name[5] = { &a[0], &a[1], &a[2], &a[3], &a[4] };
	int i;

	for (i = 0; i < 5; i++)
	{
		printf("%d   ", *name[i]);
	}
	printf("\n\n");
}

例题分析

例题: 将下边字符串按字母顺序(由小到大)输出。

 char *name[]={"Baidu.com", "www.baidu.com", "mpp.csdn.net","cdshn.com/dz"};

提示:

一,我们可以声明一个数组指针来指向;

二,将排序利用strcmp()函数来解决;

三,各个功能抽象为函数或文件。

指针数组

#include <stdio.h>
#include <string.h>

void main()
{
	void sort(char *name[], int n);
	void print(char *name[], int n);

	char *name[] = { "Baidu.com", "www.baidu.com", "mpp.csdn.net", "Baidu.com/dz" };
	int n = 4;

	sort(name, n);
	print(name, n);
}

void sort(char *name[], int n)
{
	char *temp;
	int i, j, k;

	for (i = 0; i < n - 1; i++)
	{
		k = i;

		for (j = i + 1; j < n; j++)
		{
			if (strcmp(name[k], name[j]) > 0)
			{
				k = j;
			}
			if (k != i)
			{
				temp = name[i];
				name[i] = name[k];
				name[k] = temp;
			}
		}
	}
}

void print(char *name[], int n)
{
	int i;

	for (i = 0; i < n; i++)
	{
		printf("%s\n", name[i]);
	}
}

指向指针的指针

怎样定义一个指向指针数据的指针变量呢?

形式可以如: char **p;

p的前面有两个*号。*运算符的结合性是从右到左,因此**p相当于*(*p),显然*p是指针变量的定义形式。如果没有最前面的*,那就是定义了一个指向字符数据的指针变量。

现在它前面又有一个*号,表示指针变量p是指向一个字符指针变量的。*p就是p所指向的另一个指针变量。

#include <stdio.h>

void main()
{
	char *name[] = { "Baidu.com", "www.baidu.com", "mpp.csdn.net", "Baidu.com/dz" };
	char **p;
	int i;

	for (i = 0; i < 4; i++)
	{
		p = name + i;
		printf("%s\n", *p);
	}
}

指针数组作 main 函数的形参

指针数组的一个重要应用是作为main函数的形参。在以往的程序中,main函数的第一行一般写成以下形式:

void  main()

括弧中是空的。实际上,main函数可以有参数。

例如:void  main(int  argc,char  *argv[ ])

argc和argv就是main函数的形参。

main函数是由操作系统调用的。那么,main函数的形参的值从何处得到呢?

显然不可能在程序中得到。实际上实参是和命令一起给出的。也就是在一个命令行中包括命令名和需要传给main函数的参数。

命令行的一般形式为:

命令名 参数1 参数2……参数n

从实例来认识问题

#include <stdio.h>
#include <stdlib.h>

void main(int argc, char *argv[])
{
	int i;

	printf("the number of string is : %d\n", argc - 1);

	for (i = 1; i < argc; i++)
	{
		printf("the string %d is : %s\n", i, argv[i]);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41556318/article/details/89737279