• 【C语言】用函数实现模块化程序设计


    前言:如果把所有的程序代码都写在一个主函数(main函数)中,就会使主函数变得庞杂、头绪不清,使阅读和维护程序变得困难。此外,有时程序中要多次实现某一功能,如果重新编写实现此功能就会使得程序冗长、不精炼。

    💖 博主CSDN主页:卫卫卫的个人主页 💞
    👉 专栏分类:C程序设计谭浩强版本 👈
    💯代码仓库:卫卫周大胖的学习日记💫
    💪关注博主和博主一起学习!一起努力!
    在这里插入图片描述



    怎样定义函数

    为什么要定义函数

    C语言要求,在程序中所用到的所有函数,必须“先定义,后使用”。例如max函数去求两个数的较大者,必须事先先按规范对它进行定义,指定它的名字、函数返回值类型、函数实现的功能以及参数的个数与类型,将这些信息通知编译系统。这样,在程序执行max时,编译系统就会按照定义时所指定的功能执行。如果事先不定义,编译系统怎么能知道max是什么、要实现什么功能。

    定义函数应包括以下几个内容

    1. 指定函数的名字,以便以后按名调用
    2. 指定函数的类型,即函数的返回值类型
    3. 指定函数的参数的名字和类型,以便在调用函数时向它们传递数据。对无参函数不需要这项。
    4. 指定函数应当完成什么操作,也就是函数是做什么的,即函数的功能。这是最重要的,是在函数体中解决的。

    定义函数的方法

    1. 定义无参函数

    注:函数名后面括号内的void表示"",即函数没有参数。
    函数体内包括声明部分语句部分


    1. 定义有参函数
      类型名 函数名()
      {
      函数体
      }
      函数体包括声明部分和语句部分


      类型名 函数名(void)
      {
      函数体
      }

    以下定义的max函数是有参函数:

    int max(int x,int y)
    {
    	int z;    //声明部分
    	z = x > y? x:y;
    	return z;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    类型名 函数名(形式参数列表)
    {
    函数体
    }

    函数体包含声明部分和语句部分


    1. 定义空函数
    void dummy()  //类型名:void,函数名:dummy
    {}
    
    • 1
    • 2

    调用函数

    函数调用的形式

    函数调用一般形式为:
    函数名(实参列表)

    1. 函数调用语句
      把函数调用单数作为一个语句。例如:
    void print()
    {
    	printf("***********\n");
    }
    int main()
    {
    	print();//此时函数不带回任何值
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 函数表达式
      函数调用出现在另一个表达式中,例如c=max(a,b); max(a,b) 是一次函数调用,它是赋值表达式的一部分。这时函数带回一个确定的值以参加运算。例如:
    c = max(a,b);//将a和b中的较大值赋给c值
    
    • 1

    3.函数参数
    函数调用作为另一个函数调用时的实参。例如:

    m = max(a,max(b,c));//将b,c中的较大值与a比较,在将他们的最大值赋值给m
    
    • 1

    函数调用时的数据传递

    1.形式参数和实际参数
    在调用有参函数时,主调函数和被调用函数之间有数据传递关系。从前面已知:在定义函数时函数名后面括号中的变量名称为"形式参数"(简称形参)或"虚拟参数"。在主函数中调用一个函数时,函数名后面括号中的参数称为"实际参数"(简称实参)。实际参数可以是常量、变量或表达式。
    2. 实际参数和形参间的数据传递
    在调用函数的过程中,系统会把实参的值传递给被调用函数的形参。或者说,形参从实参得到了一个值。该值在函数调用期间有效,可以参加该函数的运算。


    例题:输入两个整数,要求输出其中值较大者。要求用函数来找到大数。

    int Max(int x, int y)
    {
    	return x > y ? x : y;
    }
    int main()
    {
    	int a = 0;
    	int b = 0;
    	scanf("%d %d", &a, &b);
    	int ret = Max(a, b);
    	printf("max = %d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果:
    在这里插入图片描述


    函数调用的过程

    1. 在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。在发生函数调用时,函数max的形参才被临时分配内存单元。可以通俗的理解成,形参是对实参的一份临时拷贝。
    2. 将实参的值传递给对应的形参。
    3. 在执行max函数期间,由于形参已经有值,就可以利用形参进行有关的运算。
    4. 通过return语句将函数值带回主调函数。且应当注意返回值的类型与函数类型一致。如果函数不需要返回值,则不需要return语句。这时函数的类型定义为void类型。
    5. 调用结束,形参单元被释放。注意:实参单元仍保留并维持原值,没有改变。

    函数的返回值

    通常,希望通过函数调用使用主调函数能得到一个确定的值,这就是函数值(函数的返回值)。

    1. 函数的返回值是通过函数中的return语句获得的。
    2. 函数值的类型。既然函数有返回值,这个值当然应属于某一个确定的类型,应当在定义函数时指定函数值的类型。
    3. 在定义函数时指定的函数类型一般应该和return语句中的表达式一致。

    习题练习

    例题1:写两个函数分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数并输出结果。

    int common_divisor(int x, int y)
    {
    	int max = x > y ? x : y;
    	int min = x < y ? x : y;
    	while (min)
    	{
    		if (x % min  == 0 && y % min == 0)//将它们两个数的较小的数往下除
    		{
    			return min;
    		}
    		min--;
    	}
    }
    int common_multiple(int x, int y)
    {
    	int n = 1;
    	while (n * x % y != 0)//最小公倍数一定是他们两个的倍数
    	{
    		n++;
    	}
    	return n * x;
    }
    int main()
    {
    	int num1 = 0;
    	int num2 = 0;
    	scanf_s("%d %d", &num1, &num2);
    	int divisor = common_divisor(num1, num2);//最大公约数
    	int multiple = common_multiple(num1, num2);//最小公倍数
    	printf("divisor = %d multiple = %d\n", divisor,multiple);
    	return 0;
    }
    
    • 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

    运行结果:
    在这里插入图片描述


    例题2:写一个判素数的函数,在主函数输入一个整数,输出是否为素数的信息。

    void prime_number(int x)//素数只有1和它本身能被整除
    {
    	int flag = 0;
    	int i = 0;
    	if (x == 1)//如果该数是1就直接返回素数
    	{
    		printf("是素数\n");
    	}
    	else if (x == 0)//是0就返回不是
    	{
    		printf("不是素数\n");
    	}
    	else
    	{
    		for (i = 2; i < x; i++)//从2开始到它本身看是否有能被整除的数
    		{
    			if (x % i == 0)
    			{
    				flag = 1;
    				break;
    			}
    		}
    		if (flag)
    		{
    			printf("不是素数\n");
    		}
    		else
    		{
    			printf("是素数\n");
    		}
    	}
    }
    int main()
    {
    	int n = 0;
    	scanf_s("%d", &n);
    	prime_number(n);
    	return 0;
    }
    
    • 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

    运行结果:
    在这里插入图片描述


    例题3:写一个函数,使输入的一个字符串按反序存放,在主函数中输入和输出字符串。

    void reverse_arr(char* str, int len)//逆序字符串
    {
    	char* left = str;//保存左边的地址
    	char* right = str + len - 1;//保存右边的地址
    	while (left < right)//两两进行交换
    	{
    		char tmp = *left;
    		*left = *right;
    		*right = tmp;
    		left++;
    		right--;
    	}
    }
    int main()
    {
    	char arr[100] = { 0 };
    	gets(arr);
    	printf("initial:%s\n", arr);
    	int len = strlen(arr);
    	reverse_arr(arr,len);
    	int i = 0;
    	printf("reverse:%s\n", arr);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    运行结果:
    在这里插入图片描述


    结语:今天的内容就到这里吧,谢谢各位的观看,如果有讲的不好的地方也请各位多多指出,作者每一条评论都会读的,谢谢各位。

    🫵🫵🫵 祝各位接下来好运连连 💞
  • 相关阅读:
    电源升压模块dc/dc直流低压升高压隔离电压变换器5v12v24v48v转50v70v80v100v110v200v250v300v500v600v微功率
    【Java】文件操作 详解
    【Linux】详解套接字编程
    可视化+多人协同技术原理和案例分享
    智能解决装箱问题:使用优化算法实现高效包装
    2-2: HyperText Transfer Protocol超文本传输协议及HTTP发展历程
    js实现对象数组去重
    C#提高编程效率专辑--自动代码生成器
    Python爬虫:安全与会话管理
    SSM - Springboot - MyBatis-Plus 全栈体系(二十三)
  • 原文地址:https://blog.csdn.net/m0_64826370/article/details/133912651