实例讲函数

Posted 涛涌四海

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实例讲函数相关的知识,希望对你有一定的参考价值。

通过实例讲函数

0、函数的引入

【问题案例1】:打印一个*构成的5层金字塔,如图1所示。
【求解思路】可以用五个printf语句实现。

#include <stdio.h>
//打印5层的
void main()
{
	printf("    *\\n");
	printf("   * *\\n");
	printf("  * * *\\n");
	printf(" * * * *\\n");
	printf("* * * * *\\n");
}

【问题案例2】打印一个n层的金字塔,如图2所示。
【求解思路】通过循环n次,打印n行。每一行由打印空格和打印*两部分任务组成。

#include <stdio.h>
void main()
{
	int n;  			//n表示金字塔有多少层
	int i,j,k;			//i控制每一层,j控制i层空格的过程,k控制i层的* 打印
	
	//1 输入n
	printf("请输入一个整数:");
	scanf("%d",&n);

	//2分n行处理
	for(i=1;i<=n;i++)	//循环n次
	{
		//2.1 打印空格
		for(j=1;j<=n-i;j++)
			printf(" ");

		//2.2 打印星和末尾的换行
		for(k=1;k<=i;k++)
			printf("* ");
		printf("\\n");	//打印换行在循环体外面
	}
}

【问题案例3】打印4个不同层的金字塔。
描述:输入一个n,输出n层,n+1,n+3和n+5层的4个金字塔。
【求解思路】可以讲案例2的代码复制成4段,代码见【附录代码1】。行数较多,存在明显的代码重复,可以将重复的内容,功能相似(相同)的定义为函数,通过调用函数求解,代码见【附录代码2】

1、函数的概念

函数是一段程序段,是语句的集合。一般他有特定的功能。

2、声明函数

当函数调用语句在函数实现(定义)之前,需要现在调用前做函数声明。

3、定义函数

定义一个函数,实际是通过多个语句,实现一个具体功能,形成函数。

  • 一般格式:
    返回值类型 函数名(形式参数列表)
    {
    函数语句
    }
  • 【说明1】:如果没有返回值,函数类型为void,如果有返回值(见实例1),函数类型为返回值的类型(见实例2)。

【实例1】打印星花函数

void printStar(int n)   // 功能是打印n个星,并换行
{
     for(int i=1;i<=n;i++)
         printf("* ");
     printf("\\n");
}

【实例2】
bigger函数,功能是比较两个整数的大小返回较大数。

int bigger(int a,int b)
{
    if (a>b)    //当a大于b时
        return a;  //返回a值
    else
        return b;  //返回b值
}
  • 【说明2】:一个函数可以有多个return语句(但是只能有一个return语句得到执行),也可以没有return语句(没有返回值时)。return语句的功能是返回函数调用的地方,必要时带回计算的结果。当函数没有计算的结果可以返回时,return可以省略。
  • 【说明3】:函数的参数。
  • 参数是函数功能多样的一个关键因素,即没参数是,函数功能非常单一,比如打印“hello”,有参数则可以变化,例如打印“hello”+name,结果会根据name的值,打印对不同name人问好。
  • 参数可以分为形式参数和实际参数,两类。函数定义是参数列表内的参数均是形式参数,它定义是没有实际的值。实际参数是函数调用时,参数列表内的所有参数。见【实例3】:bigger(3,5)、bigger(x,y)
#include <stdio.h>
int bigger(int a,int b)    //a,b是形参,定义时没有实际的值
{
     return a>b?a:b;    //返回一个条件表达式
}
void main( )
{
    int x,y,z;
    printf("请输入3个整数:");
    scanf("%d%d%d",&x,&y,&z);
    
    //打印最大数
    printf("最大数是%d.\\n",bigger(z,bigger(x,y))) //调用时参数x,y,z都有具体的值,是实际参数 
}

4、调用函数

  • 当一个问题中有多个功能类似(或相同)的子问题时,将其定义为函数。然后则可以多次调用该函数,实现代码简化。
  • 函数调用即使用定义好的函数,解决一个问题。例如输出“hello world”,可以使用printf库函数。
  • 如果需要输出“hello *** ”,*是某个具体的名字。库函数printf不能直接处理时,则可以定义自己的函数,进行调用。例如打印星花构成的金字塔问题。
  • 我们称库函数意外定义的新函数为自定义函数。

5、函数综合应用举例

【实例3】打印n层、n+1层、n+3层和n+5层的4个金字塔问题。
求解思路:定义打印金字塔函数,调用4次函数打印题目要求的n、n+1、n+3、n+5层的4个金字塔。

#include <stdio.h>
void printPyrimid(int n);//声明 函数,打印n层金字塔函数
void main()
{
	int n;  //控制层数

	//1 输入n
	printf("请输入一个整数:");
	scanf("%d",&n);

	//2 打印金字塔,通过调用函数
	printPyrimid(n);
	printPyrimid(n+1);
	printPyrimid(n+3);
	printPyrimid(n+5);
}

void printPyrimid(int n)//定义,实现函数
{
	
	int i,j,k;

	//process,分行处理,n行,每次打印第i行
	for(i=1;i<=n;i++)
	{
		//打印空格,i行的空格是n-i个
		for(j=1;j<=n-i;j++)//循环n-i次
			printf(" ");

		//打印星,i行的星是i个
		for(k=1;k<=i;k++)
			printf("* ");
		
		//打印换行
		printf("\\n");
	}
}

6、问题与思考

  • 问题1:函数名字的起名有什么规则和建议?

  • 回答:函数名字要复合C语言标识符的规则,有数字、字母和下划线构成,开头不能是数字,不能是保留字。建议函数名要简明释义,一方面简单不要太长,二就是名字和功能匹配易于理解。

  • 问题2:函数一定有参数吗?

  • 回答:函数不一定有参数,即可以有无参数的函数,这要根据实际需要来决定。

  • 思考1:读附录2的代码和实例3的代码,思考分析他们各自的优点,谈谈哪个更好。

  • 思考2:数组的参数可以是int类型,可以是char类型,也可以是double类型等数组。是否可以是他们的数组作为参数?

  • 思考3:能否做一个排序函数,参数是数组。

7、小结

  • 函数能够实现代码复用、增强程序易读性和模块化编程。
  • 函数这部分是程序设计中的关键知识点,这部分的掌握属于编程能力提升的关键节部分。

8、附录

【附录代码1】产生的问题是代码代码长,重复较多,不易读。

#include <stdio.h>
void main()
{
	int n;  			//n表示金字塔有多少层
	int i,j,k;			//i控制每一层,j控制i层空格的过程,k控制i层的* 打印
	
	// n层金字塔
	//1 输入n
	printf("请输入一个整数:");
	scanf("%d",&n);

	//2 打印n行金字塔,可分n行处理
	for(i=1;i<=n;i++)	//循环n次
	{
		//2.1 打印空格
		for(j=1;j<=n-i;j++)
			printf(" ");

		//2.2 打印星和末尾的换行
		for(k=1;k<=i;k++)
			printf("* ");
		printf("\\n");	//打印换行在循环体外面
	}
	
	// n+1金字塔
	//1 输入n
	printf("请输入一个整数:");
	scanf("%d",&n);
	n = n + 1;
	//2 打印n行金字塔,可分n行处理
	for(i=1;i<=n;i++)	//循环n次
	{
		//2.1 打印空格
		for(j=1;j<=n-i;j++)
			printf(" ");

		//2.2 打印星和末尾的换行
		for(k=1;k<=i;k++)
			printf("* ");
		printf("\\n");	//打印换行在循环体外面
	}
	
	// n+3层金字塔
	//1 输入n
	printf("请输入一个整数:");
	scanf("%d",&n);
	n=n+3;
	
	//2 打印n行金字塔,可分n行处理
	for(i=1;i<=n;i++)	//循环n次
	{
		//2.1 打印空格
		for(j=1;j<=n-i;j++)
			printf(" ");

		//2.2 打印星和末尾的换行
		for(k=1;k<=i;k++)
			printf("* ");
		printf("\\n");	//打印换行在循环体外面
	}
	
	//n+5层金字塔
	//1 输入n
	printf("请输入一个整数:");
	scanf("%d",&n);
	n = n + 5;
	
	//2 打印n行金字塔,可分n行处理
	for(i=1;i<=n;i++)	//循环n次
	{
		//2.1 打印空格
		for(j=1;j<=n-i;j++)
			printf(" ");

		//2.2 打印星和末尾的换行
		for(k=1;k<=i;k++)
			printf("* ");
		printf("\\n");	//打印换行在循环体外面
	}
}

【附录代码2】特点是函数解决问题,模块化,代码精简,易于理解。

#include <stdio.h>
void printStar(int n)    // 函数功能是打印n个星,并换行
{
     for(int i=1;i<=n;i++)
         printf("* ");
     printf("\\n");
}
void printSpace(int n)   // 函数功能是打印空格
{
	//打印空格,n个
	for(int j=1;j<=n;j++)//循环n次
			printf(" ");
}

void printPyrimid(int n);//声明 函数,打印n层金字塔函数
void main()
{
	int n;  //控制层数

	//1 输入n
	printf("请输入一个整数:");
	scanf("%d",&n);

	//2 打印金字塔,通过调用函数
	printPyrimid(n);
	printPyrimid(n+1);
	printPyrimid(n+3);
	printPyrimid(n+5);
}

void printPyrimid(int n)	//定义,实现函数
{	
	int i;
							//分行处理,n行,每次打印第i行
	for(i=1;i<=n;i++)
	{
		printSpace(n-i);	//打印空格,i行空格是n-i个
		printStar(i);		//打印星,i行的星是i个
	}
}

以上是关于实例讲函数的主要内容,如果未能解决你的问题,请参考以下文章

片段事务中的实例化错误

实例讲函数

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

web前端开发JQuery常用实例代码片段(50个)

创建自己的代码片段(CodeSnippet)

递归函数实例助理解