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

news2024/12/23 9:04:54

前言:如果把所有的程序代码都写在一个主函数(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. 定义空函数
void dummy()  //类型名:void,函数名:dummy
{}

调用函数

函数调用的形式

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

  1. 函数调用语句
    把函数调用单数作为一个语句。例如:
void print()
{
	printf("***********\n");
}
int main()
{
	print();//此时函数不带回任何值
	return 0;
}

  1. 函数表达式
    函数调用出现在另一个表达式中,例如c=max(a,b); max(a,b) 是一次函数调用,它是赋值表达式的一部分。这时函数带回一个确定的值以参加运算。例如:
c = max(a,b);//将a和b中的较大值赋给c值

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

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

函数调用时的数据传递

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. 在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。在发生函数调用时,函数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;
}

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


例题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;
}

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


例题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;
}

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


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

🫵🫵🫵 祝各位接下来好运连连 💞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1121118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day02_numpy_demo

Numpy Numpy的优势ndarray属性基本操作 ndarray.func() numpy.func()ndarray的运算&#xff1a;逻辑运算、统计运算、数组间运算合并、分割、IO操作、数据处理,不过这个一般使用的是pandas Numpy的优势 Numpy numerical数值化 python 数值计算的python库&#xff0c;用于快…

Node.js--》简易资金管理系统后台项目实战(后端)

今天开始使用 node vue3 ts搭建一个简易资金管理系统的前后端分离项目&#xff0c;因为前后端分离所以会分两个专栏分别讲解前端与后端的实现&#xff0c;后端项目文章讲解可参考&#xff1a;前端链接&#xff0c;我会在前后端的两类专栏的最后一篇文章中会将项目代码开源到我…

arduino 记录

​ 知识整理 Arduion U8G2简要说明 u8g2显示分为全页显示与分页显示和U8X8的无ram显示 全页显示需要单片机提供1024字节的ram&#xff0c;分页显示分为需要256字节和125字节的ram U8X8不需要ram,但不可画图&#xff0c;只能显示文字 全页使用 clearbuff senddbuff 分页…

javaweb中的转发与重定向

2023.10.22 在一个web应用中应该如何完成资源的跳转&#xff1f; 转发重定向 转发和重定向有什么区别&#xff1f; 转发是由服务器端进行的页面跳转&#xff0c;而重定向是由浏览器端进行的页面跳转。 ①代码上的区别&#xff1a; 转发&#xff1a; // 获取请求转发器对象…

Sublime Text forMac/Windows:高效代码编辑器的终极指南

你是否曾为寻找一款高效、强大且用户友好的代码编辑器而感到困扰&#xff1f;现在&#xff0c;让我们一起探索Sublime Text的魅力。Sublime Text是一款流行的代码编辑器&#xff0c;以其强大的功能和简洁的设计赢得了开发者的喜爱。本文将带你了解Sublime Text的各项特性&#…

1、VMware虚拟机及网络配置

一、VMware虚拟网络编辑器 1、选择NAT模式并配置子网 2、进入NAT设置&#xff0c;配置网关 3、宿主机网络适配器设置 二、创建虚拟机 在这里插入图片描述 三、开启虚拟机&#xff0c;安装操作系统 在该网段内配置静态ip&#xff0c;指定网关为前面NAT配置的网关地址…

游戏找不到msvcr100dll怎么办,分享5个有效修复方法

一、游戏找不到msvcr100dll会造成的困扰 在当今的数字时代&#xff0c;电子游戏已经成为了我们生活中不可或缺的一部分。它们为我们提供了娱乐和放松的机会&#xff0c;让我们能够在忙碌的生活中找到乐趣。然而&#xff0c;当我们在玩游戏时&#xff0c;可能会遇到一些技术问题…

【性能测试】MySQL慢查询原因/排查思路+SQL优化与性能定位思路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Mysql慢查询现象、…

十四天学会C++之第八天:文件操作

1. 文件的打开和关闭 文件操作的基本概念。打开文件&#xff1a;使用fstream库打开文件以供读写。关闭文件&#xff1a;确保文件在使用完毕后正确关闭。 文件的打开和关闭&#xff1a;C 文件操作入门 在C编程中&#xff0c;文件操作是一项重要的任务&#xff0c;可以读取和写…

Java日志系统之Log4j2

Log4j2介绍 Log4j2是Log4j的升级版&#xff0c;参考Logback的优秀设计并修复了一些问题。主要优点有&#xff1a; 异常处理&#xff0c;在logback中&#xff0c;Appender中的异常不会被应用感知到&#xff0c;但是在log4j2中&#xff0c;提供了一些异常处理机制。性能提升&am…

Java高级编程----集合

集合 集合概述Collection接口List接口简介ArrayList集合Set接口简介Hash Set接口简介Map接口简介TreeMap集合Properties集合 集合概述 为了在程序中可以保存数目不确定的对象&#xff0c;Java提供了一系列特殊类&#xff0c;这些类可以存储任意类型的对象&#xff0c;并且长度…

使用java mail SMTPTransport发送邮箱,本地秒到,一上服务器就20-30s左右,生产环境直接发送失败。

一、代码 pom文件 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!--pom.xml添加javax.mail的引用&#xff0c;或者项目引入…

【最短路径算法】一文掌握Dijkstra算法,详解与应用示例+代码

目录 1 Dijkstra算法 2 Dijkstra算法的步骤 3 Dijkstra算法python实现 4 Dijkstra算法应用示例详解 1 Dijkstra算法 Dijkstra算法&#xff08;迪杰斯特拉算法&#xff09;是一种用于在加权图中查找从一个起始节点到所有其他节点的最短路径的算法。该算法最初由荷兰计算机科…

JVM 基础篇:类加载器

一.了解JVM 1.1什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟计算机功能来实现的&#xff0c;JVM屏蔽了与具体操作系统平台相关的信息&#xff0c;Java程序只需…

通讯录和内存动态管理

目录 (通讯录)动态增长版 实现效果 找单身狗 题目 源码 思路 三个内存函数的模拟实现 模拟实现strncpy 模拟实现strncat 模拟实现atoi (通讯录)动态增长版 该版本通讯录在原版的基础上增加了检查容量函数&#xff0c;实现了通讯录的动态…

在PS中轻松实现肖像磨皮,感受Imagenomic Portraiture 4的强大

每个人都希望自己的肖像照片看起来漂亮、清晰并且光滑。然而&#xff0c;在处理肖像照片时&#xff0c;要达到这些效果通常需要花费大量时间和精力。如果您正在寻找一种简单快捷的方法来优化您的肖像照片&#xff0c;那么Imagenomic Portraiture 4插件将是您的理想选择。 Imag…

单接口的批量测试如何实现

一、痛点&#xff1a;一条测试数据对应一个测试方法 前面的章节中我们已经写代码实现了登录接口的处理调用&#xff0c;但是一个接口往往是需要多条测试用例才能完整的覆盖到每一种情况&#xff0c;针对于单接口多条测试用例需要执行的情况&#xff0c;该如何处理呢&#xff0…

uboot移植之mx6ull_alientek_nand.h文件详解一

一. 简介 mx6ull_alientek_nand.h文件是 开发板的 uboot的一个配置文件。每个开发板都有一个 .h的配置文件。 mx6ull_alientek_nand.h文件其实是 之前针对正点原子ALPHA开发板移植的 Uboot配置文件。 本文简单分析一下 针对正点原子ALPHA开发板的 配置文件&#xff1a; mx6u…

STL模拟实现—vector

引言&#xff1a;本篇文章主要是模拟实现vector&#xff0c;但不同于stl中vector的成员变量都是迭代器&#xff0c;这个自定义的vector是一个T* 的数据变量和一个int类型的size和int类型的capacity。&#xff08;有时间再写三个迭代器的版本吧&#xff01;&#xff09; 首先来看…

Redis学习(第八章缓存策略)

目录 RdisExample 课程介绍 1.Redis介绍 2.Redis 安装 3. Redis的数据结构 4. Redis缓存特性 5. Redis使用场景 6. Redis客户端-Jedis 7. Jedis Pipeline 8. Redis缓存策略 学习资料 QA 相关问题 http, socket ,tcp的区别 RdisExample 项目代码地址&#xff1a;htt…