【重拾C语言】五、模块化程序设计——函数(定义、调用、参数传递、结果返回、函数原型;典例:打印字符图形、验证哥德巴赫猜想)
目录
前言
五、模块化程序设计——函数
5.1 计算三角形的重心
5.2 函数
5.2.1 函数定义
5.2.2 函数调用
a. 函数调用的形式和过程
b. 参数传递
值传递
指针传递
c. 函数结果返回
5.2.3 函数原型(先调用后定义)
5.3 程序设计实例
5.3.1 打印字符图形
5.3.2 哥德巴赫猜想
5.4 程序调试
前言
本文介绍了模块化程序设计——函数,其中包括如何定义函数、函数的调用形式和过程、参数传递(值传递和指针传递)、函数结果的返回以及函数原型的使用。具体的程序设计实例有打印字符图形和验证哥德巴赫猜想。
五、模块化程序设计——函数
在C语言中,我们可以使用函数实现模块化程序设计,将一些独立功能的部分写成单独的函数,使得程序更加结构化和清晰。
5.1 计算三角形的重心
我们可以根据给定的三角形顶点坐标(x1, y1)、(x2, y2)和(x3, y3)来计算三角形的重心。重心G的坐标计算公式如下:
以下是使用C语言实现的函数:
#include <stdio.h>void centroid(float x1, float y1, float x2, float y2, float x3, float y3, float *Gx, float *Gy) {*Gx = (x1 + x2 + x3) / 3;*Gy = (y1 + y2 + y3) / 3;
}int main() {float x1, y1, x2, y2, x3, y3, Gx, Gy;scanf("%f%f%f%f%f%f", &x1, &y1, &x2, &y2, &x3, &y3);centroid(x1, y1, x2, y2, x3, y3, &Gx, &Gy);printf("Centroid of the triangle is: (%.2f, %.2f)\n", Gx, Gy);return 0;
}
(关于指针的使用详见本系列后文)
5.2 函数
5.2.1 函数定义
函数定义包括返回值类型、函数名、参数列表以及函数体。
类型符 函数名(形式参数表) {函数体
}
其中,返回类型符指定了函数返回的数据类型,可以是基本数据类型(如int、char、float等)或自定义的数据类型。函数名是函数的标识符,用于在程序中调用该函数。参数列表是一组用逗号分隔的参数,可以包含零个或多个参数,每个参数包括参数类型和参数名。函数体是函数的具体实现代码,包括一系列语句和操作。以上面 centroid 函数为例:
函数的目的是计算一个三角形的质心坐标。它接受6个输入参数,分别是三角形的3个顶点的x和y坐标(x1, y1, x2, y2, x3, y3),以及两个指针变量(float *Gx
和float *Gy
),用于存储计算得到的质心的x和y坐标。
在函数体中,通过将三个顶点的x坐标相加并除以3,将结果存储在*Gx
指向的内存位置中,表示质心的x坐标。同样,将三个顶点的y坐标相加并除以3,将结果存储在*Gy
指向的内存位置中,表示质心的y坐标。
请注意,在C语言中,函数的声明和定义可以分开进行,即可以在程序的开头声明函数的原型(函数名、参数列表和返回类型),然后在后面的位置实现函数的定义。这种分离的方式可以提供更好的代码组织和模块化。
(详见5.2.3 函数原型)
5.2.2 函数调用
函数名(实际参数表)
函数调用是在主函数或其他函数中使用已定义的函数。通过函数名和实际参数列表来调用函数。例如,在 main 函数中,我们调用了 centroid 函数并传入了6个实际参数和2个用于存储结果的指针。
- 定义一个函数后,就可以在程序中调用这个函数:
- 标准库函数:在程序的最前面用#include命令包含相应的头文件。
- 自定义函数:程序中必须有相对应的函数定义。
a. 函数调用的形式和过程
在C语言中,函数调用通过函数名和实际参数列表的形式进行。函数调用的一般形式是:
函数名(参数1, 参数2, ...);
其中,函数名是要调用的函数的名称,参数是传递给函数的输入值。
函数调用的过程如下:
- 程序执行到函数调用的位置时,会跳转到被调用函数的起始位置。
- 在被调用函数中,执行函数体中的语句,处理传递进来的参数。
- 如果函数有返回值,计算并返回结果。
- 执行完函数体中的语句后,返回到函数调用的下一条语句,继续执行。
b. 参数传递
在C语言中,函数参数可以通过值传递(传递参数的副本)或指针传递(传递参数的地址)的方式进行传递。
-
值传递
- 当使用值传递方式传递参数时,函数内部对参数的修改不会影响到函数外部的变量。即函数内部操作的是参数的副本。
-
指针传递
- 当使用指针传递方式传递参数时,函数内部可以通过指针来访问和修改函数外部的变量。通过传递变量的地址,函数可以直接对原始变量进行操作。
c. 函数结果返回
- 函数可以有返回值,也可以没有返回值。函数的返回值通过
return
语句来指定。 - 函数的返回值可以是任意基本类型(如整数、浮点数等),也可以是指针类型或结构体类型。
- 在函数中使用
return
语句将结果返回给调用函数。返回值可以直接返回,也可以存储在变量中后再返回。
例如,以下是一个函数的示例,它计算两个整数的和并返回结果:
int add(int a, int b) {int sum = a + b;return sum;
}
在调用该函数时,可以将返回值赋给一个变量:
int result = add(3, 5);
在这个例子中,函数 add
接收两个整数参数 a
和 b
,计算它们的和并将结果返回。函数调用 add(3, 5)
的结果为 8,然后将返回值 8 赋给变量 result
。
5.2.3 函数原型(先调用后定义)
函数原型是函数定义的简化形式,用于告诉编译器函数的信息,包括函数的返回值类型、函数名和参数列表(包括参数类型和参数名)。函数原型的目的是在函数调用之前提供函数的声明,让编译器知道函数的存在及其参数和返回值的类型。
在C语言中,函数原型的语法形式为:
返回值类型 函数名(参数列表);
例如,对于之前提到的 centroid 函数,可以编写函数原型如下:
void centroid(float x1, float y1, float x2, float y2, float x3, float y3, float *Gx, float *Gy);
通过提供函数原型,我们可以在主函数之前声明函数,使得编译器能够正确地解析函数调用,并检查函数调用的参数类型和返回值类型的匹配性。这提高了程序的可读性和可维护性。在本例5.1中,函数原型可以省略,因为我们把 centroid 函数放在 main 函数的前面。
在程序的开头声明函数的原型:
#include <stdio.h>void centroid(float x1, float y1, float x2, float y2, float x3, float y3, float *Gx, float *Gy);int main() {float x1, y1, x2, y2, x3, y3, Gx, Gy;scanf("%f%f%f%f%f%f", &x1, &y1, &x2, &y2, &x3, &y3);centroid(x1, y1, x2, y2, x3, y3, &Gx, &Gy);printf("Centroid of the triangle is: (%.2f, %.2f)\n", Gx, Gy);return 0;
}void centroid(float x1, float y1, float x2, float y2, float x3, float y3, float *Gx, float *Gy) {*Gx = (x1 + x2 + x3) / 3;*Gy = (y1 + y2 + y3) / 3;
}
5.3 程序设计实例
5.3.1 打印字符图形
#include <stdio.h>void printCharacterPattern(int n) {int i, j, space;// 打印上半部分for (i = 1; i <= n; i++) {// 打印空格for (space = 1; space <= n - i; space++) {printf(" ");}// 打印字母for (j = 1; j <= (2 * i) - 1; j++) {printf("%c ", 'A' + i - 1);}printf("\n");}// 打印下半部分for (i = n - 1; i >= 1; i--) {// 打印空格for (space = 1; space <= n - i; space++) {printf(" ");}// 打印字母for (j = 1; j <= (2 * i) - 1; j++) {printf("%c ", 'A' + i - 1);}printf("\n");}
}int main() {int n;printf("Enter the number of lines: ");scanf("%d", &n);printf("\n");printCharacterPattern(n);return 0;
}
5.3.2 哥德巴赫猜想
哥德巴赫猜想:任意一个大于2的偶数都可以表示成两个素数之和。我们可以编写一个函数,找到两个素数,使它们的和等于一个给定的偶数。
#include <stdio.h>int isPrime(int number) {int i;if (number <= 1) {return 0;}for (i = 2; i <= number / 2; i++) {if (number % i == 0) {return 0;}}return 1;
}void verifyGoldbachConjecture(int n) {int i, flag = 0;if (n % 2 != 0 || n <= 2) {printf("Invalid input! Please enter an even number greater than 2.\n");return;}for (i = 2; i <= n / 2; i++) {if (isPrime(i) && isPrime(n - i)) {printf("%d = %d + %d\n", n, i, n - i);flag = 1;}}if (flag == 0) {printf("The Goldbach conjecture is not verified for the number %d.\n", n);}
}int main() {int n;printf("Enter an even number greater than 2: ");scanf("%d", &n);verifyGoldbachConjecture(n);return 0;
}
- 在上面的代码中,定义了两个函数:
isPrime
和verifyGoldbachConjecture
。isPrime
函数用于检查一个数是否是素数;verifyGoldbachConjecture
函数用于验证哥德巴赫猜想。- 首先检查输入是否为一个大于2的偶数,然后通过遍历所有可能的素数对来验证猜想。如果找到满足猜想的素数对,则打印出相应的表示;如果找不到满足猜想的素数对,则输出相应的提示信息。
5.4 程序调试
ChatGPT:
程序调试是指对程序进行测试和排除错误的过程。在程序开发过程中,经常会出现各种错误,比如语法错误、逻辑错误、运行时错误等。调试的目标是找出程序中存在的错误并修复它们,确保程序能够按照预期的方式运行。
下面是一些常见的程序调试技术和方法:
打印调试信息:通过在关键位置插入打印语句,输出变量的值或程序执行到达的位置,以便观察程序的执行过程和状态,从而找出问题所在。
使用调试器:调试器是一种工具,可以用来逐步执行程序、观察变量的值、检查内存和寄存器的状态,以及跟踪程序的执行流程。通过调试器,可以更深入地分析程序的运行情况和定位错误。
单元测试:编写针对程序中单个函数或模块的测试用例,验证其是否按照预期工作。通过逐个测试函数,可以逐步排查错误并验证程序的正确性。
边界值测试:针对程序处理数据的边界情况进行测试,包括最大值、最小值、边界条件等。边界值测试可以揭示一些潜在的问题,如数组越界、整数溢出等。
追踪错误:对于运行时错误,可以使用追踪技术来定位错误发生的位置。可以通过观察错误信息、栈跟踪和日志等来追踪错误的来源,进而修复问题。
代码审查:请同事或其他开发人员对代码进行审查,有时候他们能够发现你忽略的问题或提出改进的建议。
在进行程序调试时,建议采用自底向上的方法,逐步调试和测试程序的不同部分,确保每个部分的正确性,最后再整体进行测试。
相关文章:
【重拾C语言】五、模块化程序设计——函数(定义、调用、参数传递、结果返回、函数原型;典例:打印字符图形、验证哥德巴赫猜想)
目录 前言 五、模块化程序设计——函数 5.1 计算三角形的重心 5.2 函数 5.2.1 函数定义 5.2.2 函数调用 a. 函数调用的形式和过程 b. 参数传递 值传递 指针传递 c. 函数结果返回 5.2.3 函数原型(先调用后定义) 5.3 程序设计实例 5.3.1 打印…...
Unity实现设计模式——迭代器模式
Unity实现设计模式——迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式…...
【数据结构与算法】之“堆”介绍
目录 堆的基本存储 一、概念及其介绍 二、适用说明 三、结构图示 堆的 shift up 堆的 shift down 基础堆排序 一、概念及其介绍 二、适用说明 三、过程图示 优化堆排序 索引堆及其优化 一、概念及其介绍 二、适用说明 三、结构图示 堆的基本存储 一、概念及其介…...
ncnn Fatal signal 11 (SIGSEGV) 使用GPU加速崩溃
如果你的报错堆栈中包含以下信息,其中的关键信息是 anon:dalvik-classes2.dex extracted in memory Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x3c in tid 8619 (eplabv3plusncnn), pid 8619 () 2023-10-07 15:48:31.395 9793-9793 DEBUG …...
计算机考研 | 2018年 | 计算机组成原理真题
文章目录 【计算机组成原理2018年真题44题-15分】【第一步:信息提取】【第二步:具体解答】 【计算机组成原理2018年真题45题-8分】【第一步:信息提取】【第二步:具体解答】 【计算机组成原理2018年真题44题-15分】 某计算机采用页…...
用Configuration注解的方式写一个java过滤器的详细实例?
在Java中,可以使用Configuration注解和Spring框架来创建和配置过滤器。下面是一个详细的示例: 首先,创建一个实现javax.servlet.Filter接口的过滤器类,例如MyFilter: import javax.servlet.*; import java.io.IOExce…...
基于Springboot实现旧物置换网站平台演示【项目源码+论文说明】分享
基于Springboot实现旧物置换网站平台演示 摘要 随着时代在一步一步在进步,旧物也成人们的烦恼,许多平台网站都在推广自已的产品像天猫、咸鱼、京东。所以开发出一套关于旧物置换网站成为必需。旧物置换网站主要是借助计算机,通过对用户进行管…...
想要精通算法和SQL的成长之路 - 存在重复元素
想要精通算法和SQL的成长之路 - 存在重复元素 前言一. 存在重复元素II二. 存在重复元素III2.1 基于红黑树增删改查 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 存在重复元素II 原题链接 思路: 我们用HashSet存储元素,做到去重的效果。同时存储…...
使用华为eNSP组网试验⑸-访问控制
今天练习使用华为sNSP模拟网络设备上的访问控制,这样的操作我经常在华为的S7706、S5720、S5735或者H3C的S5500、S5130、S7706上进行,在网络设备上根据情况应用访问控制的策略是一个网管必须熟练的操作,只是在真机上操作一般比较谨慎ÿ…...
iPhone苹果手机闹钟智能跳过节假日怎么设置?
国内绝大多数的手机用户使用的操作系统只有三个,安卓、鸿蒙和苹果的ios。而iPhone苹果手机的忠实用户是非常多的,所以日积月累中用户数量也就非常庞大,并且相当一部分用户都是上班族。而工作忙碌的上班族因为事情比较多,为了避免自…...
TenDB Cluster 简介
文章目录 1.简介2.TSpider3.TenDB4.Tdbctl5.TenDB Cluster Operator参考文献 1.简介 TenDB Cluster 是腾讯游戏 CROS DBA 团队提供的 MySQL 分布式关系型数据库解决方案。主要特点包括:透明分库分表、高可用的 MySQL 集群服务,透明及在线的扩容及缩容&a…...
【刷题笔记10.6】LeetCode:翻转二叉树
LeetCode:翻转二叉树 一、题目描述 给你一颗二叉树的根节点root,翻转这颗二叉树,并返回其根节点。 二、分析 我们在做二叉树题目时候,第一想到的应该是用 递归 来解决。 仔细看下题目的 输入 和 输出,输出的左右…...
【高阶数据结构】图详解第一篇:图的基本概念及其存储结构(邻接矩阵和邻接表)
文章目录 1. 图的基本概念1.1 什么是图1.2 有向图和无向图1.3 完全图1.4 邻接顶点1.5 顶点的度1.6 路径1.7 路径长度1.8 简单路径与回路1.9 子图1.10 连通图1.11 强连通图1.12 生成树 2. 图的存储结构2.1 邻接矩阵2.2 邻接矩阵代码实现结构定义构造函数添加边打印图测试 2.3 邻…...
IPV4跟IPV6的区别
如今互联网快速发展ipv4已经满足不了现在的需求,那么这时候就需要用更大的地址空间来代替,这时候ipv6就可以满足这一需求,相比ipv4它有更大的地址空间可供使用。下面我将分享一下有何区别。 IPv4与IPv6之间的区别: 1、地址长度的区别:IPv4具…...
利用fitnesse实现api接口自动化测试
上午在园子里乱逛,看了不少小伙伴们分享的接口测试方面的知识,仔细想想,我做接口测试也有几个年头了,大家所叙述到的一些经验或多或少,我也曾遇到过,突然意识到知识的点滴积累是多么的重要,我记…...
【LeetCode】1154.一年中的第几天
题目描述: 给你一个字符串 date ,按 YYYY-MM-DD 格式表示一个 现行公元纪年法 日期。返回该日期是当年的第几天。 示例 1: 输入:date "2019-01-09" 输出:9 解释:给定日期是2019年的第九天。示…...
4.物联网射频识别,RFID开发【智能门禁项目】
补充:学习路径 一。项目介绍及需求分析 1.酒店智能门禁使用场景介绍 1.客人入住 客人在前台办理入住手续,前台管理员通过门禁管理系统为客户开一张门禁卡 客户持卡到相应客房,用IC 卡刷卡开门 客人过了入住时间后,卡自动失效&a…...
CompletableFuture 和 Future 的选择,以及CompletableFuture的用法
在 Java 编程中,异步编程是一种重要的技术,它允许你在执行长时间运行的任务时不会阻塞主线程。为了支持异步编程,Java 提供了 Future 和 CompletableFuture 这两个关键的类。在本文中,我们将比较它们的特点、优缺点以及使用场景。…...
美国第三大财产和意外险公司利宝保险集团利用 OpenText EnCase 取证收集技术控制法律风险和成本
美国第三大财产和意外险公司利宝保险集团利用 OpenText EnCase 取证收集技术控制法律风险和成本 利宝保险集团通过内部取证收集技术控制法律风险和成本。OpenText EnCase Information Assurance(以前称为 EnCase eDiscovery)使保险公司巨头能够自信高效地…...
打包报错JavaScript heap out of memory
npm run build 的时候出现了Reached heap limit Allocation failed - JavaScript heap out of memory,报错信息如下图所示。 奇怪的时候这个报错信息在本地不会出现,通过jekins在服务器打包部署的时候才会出现。于是进入服务器执行下面一句代码ÿ…...
Android Camera FW 里的requestId和frameId
安卓相机frameworks里面经常出现requestId和frameId,最近简单看了一下代码,发现相关流程还是很复杂的,总结来看requestId 就是上层(java)发送的repeating(capture)请求的id,是从0开始递增的。 这是CameraD…...
代理IP与Socks5代理在技术世界的多元应用
在数字化时代,网络工程师的任务不仅是维护网络的稳定性,还需要应对各种技术挑战。代理IP与Socks5代理作为技术工具箱中的两把利器,在跨界电商、爬虫、出海业务、网络安全和游戏领域中发挥了关键作用。本文将深入探讨这两项技术在不同领域的多…...
计算机专业毕业设计项目推荐12-志愿者管理系统(Spring+Js+Mysql)
志愿者管理系统(SpringJsMysql) **介绍****各部分模块实现** 介绍 本系列(后期可能博主会统一为专栏)博文献给即将毕业的计算机专业同学们,因为博主自身本科和硕士也是科班出生,所以也比较了解计算机专业的毕业设计流程以及模式,在编写的过程…...
苹果文件传到mac电脑用什么软件?
在数字化时代,文件传输已经成为我们日常生活中不可或缺的一部分。然而,苹果用户在将手机文件传输到电脑时,往往会面临一些困扰。曾经的“文件传输助手”并不能完全满足用户的需求。于是,很多人开始寻找更便捷的解决方案。在本文中…...
深入理解Docker:简化部署与管理的利器
文章目录 引言Docker简介Docker的背景和发展Docker的优势和特点 Docker的基本概念和架构镜像(Image)容器(Container)仓库(Repository)Docker架构 Docker的常用命令和操作Docker的安装和配置Docker镜像的管理…...
软考对找工作有用吗?
软考是指软件技术专业资格考试,是由中国人力资源和社会保障部主管的一项国家级考试。软考的目标是评估和认证软件技术人员的专业能力,提高软件行业的整体素质和竞争力。那么,软考对找工作有用吗?本文将从以下几个方面进行分析。 首…...
Android系统启动之init进程启动+Zygote进程启动分析
一、基础概念理解 init进程 Android系统所有进程的祖先,是Android系统内核初始化完毕后,进入用户空间启动的第一个进程。 Android虚拟机 Dalvik虚拟机是谷歌自己设计的用于Android平台的虚拟机。Android4.4同时提供了Dalvik和ART虚拟机。Android5.0以后…...
微信这样的加人方式,既安全又解放双手
在当今竞争激烈的市场环境下,如何高效地管理和运营私域流量成为企业发展的关键。 1.批量自动化加好友的优势 (1)提高效率:批量自动化添加好友功能可以帮助企业添加大量潜在客户或目标客户。相比手动逐个添加好友,自动…...
CVE-2023-5129:libwebp开源库10分漏洞
谷歌为libwebp漏洞分配新的CVE编号,CVSS评分10分。 Libwebp是一个用于处理WebP格式图像编解码的开源库。9月6日,苹果公司安全工程和架构(SEAR)部门和加拿大多伦多大学研究人员在libwebp库中发现了一个0 day漏洞,随后&…...
从零开始的C++(六)
1.类和对象补充: 静态成员,有静态成员函数和静态成员变量,特点是不为类的某个对象所有,而是为同类所有对象共有。因为是为同类对象共同拥有,所以计算对象的大小的时忽略静态成员。因为静态成员是放在静态区࿰…...
关于做旅游网站的参考文献/建立网站一般要多少钱
序曲出塞二首 其一【唐】 秦时明月汉时关,万里长征人未还。但使龙城飞将在,不教胡马度阴山。这是一首边塞诗,昌龄从描写景物景入手,首句勾勒出一幅冷月照边关的苍凉景象。"秦时明月汉时关"暗示了这里的战事自秦汉以来一…...
南京 微网站 建站/近两年成功的网络营销案例
一个事务必须具有以下四个特点,即所谓的ACID特性: 原子性:所有的操作要么全部成功,要么全部失败。一致性:在事务完成后,系统保持一致性状态。隔离性:在一个事务成功或失败前,产生的…...
阿里云轻云服务器可以放多个网站啊怎么做/深圳竞价排名网络推广
下面介绍一下 Yii2.0 对数据库 一些简单的操作 User::find()->all(); 此方法返回所有数据;User::find()->one(); 此方法返回一条数据;User::find()->limit(3) 此方法返回3条数据User::find()->count(); 此方法返回记录的数…...
如何做网站报价/南昌seo专业团队
今天看到kite项目中的一段代码,发现挺有意思的。 // generateToken returns a JWT token string. Please see the URL for details: // http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-13#section-4.1 func generateToken(aud, username, issuer, pri…...
建设彩票网站多少钱/长沙网站搭建优化
一、修改端口号 spring-boot 默认的端口号是8080,如需修改。 1、新建一个src/main/resources 文件夹 2、在这个文件夹下新建一个application.propertise 文件 3、在这个文件里写 server.port 80 4、注意 要使用spring-boot:run启动。 配置文件名称必须为applicatio…...
英文互动网站建设/网络关键词优化方法
ArcGIS案例学习笔记-点群密度统计 联系方式:向日葵,135-4855-4328,xiexiaokui#qq.com 目的:对于点群,统计分布密度 数据: 方法: 1. 生成格网 2. 统计个数,制作专题图 联系方式…...