【轻松学 C:编程小白的大冒险】— 16 函数的定义与调用

在这里插入图片描述

  • 在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。
  • 而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。

【轻松学 C:编程小白的大冒险】— 16 函数的定义与调用

  • 一、函数:把代码变成“乐高积木”的魔法
  • 二、函数定义:打造你的专属“代码黑匣子”
    • 2.1 函数的“出厂说明书”长啥样?
    • 2.2 三要素详解:每个零件都有大作用
      • ① 返回值类型:函数的“快递回执”
      • ② 函数名:函数的“户口本姓名”
      • ③ 参数列表:函数的“食材采购清单”
  • 三、函数调用:让“代码机器人”动起来的三种姿势
    • 3.1 直接调用:适合“干完就走”的void函数
    • 3.2 赋值调用:适合有返回值的函数
    • 3.3 表达式调用:让函数参与数学运算
    • 3.4 参数传递原理:值传递的“影分身魔法”
  • 四、实战案例:用函数搭建“智能奶茶店系统”
    • 4.1 函数化拆分:把大问题拆成小零件
      • ① 杯型转容量函数
      • ② 加料计价函数
    • 4.2 主函数组装:调用函数生成订单
  • 五、💡 函数使用避坑小课堂:新手必看!
    • 5.1 返回值失踪案:忘记写return
    • 5.2 参数类型穿越剧:实参与形参不匹配
    • 5.3 函数声明失踪案:先调用后定义
    • 5.4 致命错误:错误的main函数返回类型
  • 六、编程冷笑话:函数的“内心OS”
  • 七、✨ 今日金句


  • “函数在手,代码我有!”—— 来自一位成功封装了起床闹钟函数的程序员

一、函数:把代码变成“乐高积木”的魔法

  • 你有没有过这样的经历?
  • 写代码时重复写了十遍“计算圆周长”的公式,改一个参数却漏掉三个地方,最后对着报错信息抓耳挠腮?🤯
  • 别慌!编程界早就发明了“偷懒神器”——函数
  • 它就像代码世界的“乐高积木”,把重复的逻辑封装成一个个独立模块,想用的时候直接“拼”起来就行
  • 再也不用像流水线工人一样重复搬砖啦!

二、函数定义:打造你的专属“代码黑匣子”

2.1 函数的“出厂说明书”长啥样?

  • 先来看函数的标准定义格式,一目了然👇
返回值类型
函数名
参数列表
形参1
形参2
...
函数体
执行语句
是否有返回值?
return 结果
void无返回值
  • 翻译成人类语言就是:
返回值类型 函数名(参数1类型 参数1名称, 参数2类型 参数2名称) {在这里写具体要执行的操作(比如计算、打印);如果有返回值,必须用return语句把结果“吐”出来;
}
  • 特别注意:C语言规定,main函数必须是整个程序的“入口函数”,它的返回值类型必须是int
  • 就像餐厅的大门必须有明确的“入口”标识,这是程序与操作系统对话的“官方接口”。

2.2 三要素详解:每个零件都有大作用

① 返回值类型:函数的“快递回执”

  • int:返回整数,精准到个位,像你的年龄(比如返回两数之和return a + b;)。
  • float/double:返回带小数的数,允许有误差,像体重秤的读数(比如返回圆面积return 3.14 * r * r;)。
  • void:“啥也不返”型,像发消息“已读不回”,执行完就完事(比如打印日志的函数void print_log() { ... })。
  • 特殊场景main函数的return 0是程序向操作系统发送的“完工报告”,0表示“程序正常结束”,就像快递员送达后在系统里标记“签收成功”,操作系统会根据这个数字判断程序是否顺利跑完。

② 函数名:函数的“户口本姓名”

  • 命名规则比给娃取名字还严格,必须遵守“编程界Naming公约”:
正确示范反面教材为啥不行?
calc_average123_avg不能以数字开头,像“123号同学”难记
get_user_namegn太简略!别人看不懂是干啥的
check_logincheckLogin拼音+英文混搭?编程界不接受“中英混血”

③ 参数列表:函数的“食材采购清单”

  • 形参(形式参数):函数定义时的“Placeholder”,相当于剧本里的角色名(比如“主角A”“配角B”),只说明“我需要菜名和辣度”,但没说具体是啥。可以理解为函数的“临时变量”,调用时才会被赋值,就像拍戏时演员给角色赋予具体形象。
  • 实参(实际参数):调用函数时的“真材实料”,比如cook("火锅", 5),直接告诉函数“我要做5级辣的火锅”!

三、函数调用:让“代码机器人”动起来的三种姿势

3.1 直接调用:适合“干完就走”的void函数

  • 比如定义一个“打招呼”函数,直接喊它名字就行,无需接收返回值:
void say_hi() {printf("Hi, I'm your function!\n");
}int main() {say_hi(); // 直接调用,函数会打印一句话,就像喊一声“帮我打招呼”,不用等回复return 0; // 程序跑完了,向操作系统报告“一切正常”,就像考试结束交卷时写上“考生已答完”
}

3.2 赋值调用:适合有返回值的函数

  • 把函数的返回值存到变量里,就像把外卖放进你的饭盒:
int add(int a, int b) { // 加法函数,返回a+b的结果return a + b;
}int main() {int result = add(3, 5); // 调用函数并赋值给result,相当于让函数当“计算器”,算完把结果递给你printf("3+5=%d\n", result); // 输出8return 0; // 带着计算结果“交差”,告诉系统“任务完成,结果正确”
}

3.3 表达式调用:让函数参与数学运算

  • 函数可以像数字一样嵌入表达式,比如边计算边乘2:
int total = add(10, 20) * 2; // (10+20)*2=60,函数在这里相当于一个“会计算的数字”

3.4 参数传递原理:值传递的“影分身魔法”

  • 想象你有一张“原图”变量original,把它传给函数beauty
void beauty(int photo) { // 形参photo是原图的“复印件”,就像你把U盘里的文件复制一份给别人,原件还在你手里photo += 100; // 只修改复印件,原图不变,就像别人在复印件上画画,你的原件始终干净整洁
}int main() {int original = 50;beauty(original); // 实参传递的是original的值(50),相当于把文件内容复制一份给函数printf("原图还是%d分真实!\n", original); // 输出50,没变!因为函数拿的是“副本”,改的是“副本”return 0; // 程序确认“原件未被修改”,安心结束
}

画个“值传递流程图”,秒懂原理👇:

main函数
original = 50
调用 beauty(original)
创建副本 photo = 50
修改 photo = 150
函数返回
original 保持 50

关键点:C语言默认是“值传递”,函数拿到的是参数的复印件,不会修改原始变量,就像你给朋友的是照片复印件,原件永远在你相册里完好无损。


四、实战案例:用函数搭建“智能奶茶店系统”

  • 假设你要开发一个奶茶店计费系统,需求如下:
  1. 根据杯型(M/L/XL)计算容量
  2. 根据加料(珍珠/椰果/布丁)计算价格
  3. 生成订单报告

4.1 函数化拆分:把大问题拆成小零件

① 杯型转容量函数

int get_cup_volume(char size) {switch(size) {case 'M': return 500; // 中杯500mlcase 'L': return 700; // 大杯700mlcase 'XL': return 1000; // 超大杯1000mldefault: return 0; // 防止无效输入,就像餐厅拒绝“火星杯型”的奇怪订单}
}

② 加料计价函数

float calculate_topping(int pearl, int coconut, int pudding) {return pearl*1.5 + coconut*2.0 + pudding*3.0; // 珍珠1.5元/份,椰果2元/份,布丁3元/份,精确计算每笔加料费用
}

4.2 主函数组装:调用函数生成订单

#include <stdio.h>// 前面定义的两个函数...int main() {// 顾客点单:大杯(L),2份珍珠,1份椰果char cup_size = 'L';int pearl = 2, coconut = 1, pudding = 0;// 调用函数计算int volume = get_cup_volume(cup_size); // 获取容量,函数就像“杯型翻译官”,把L转成700mlfloat topping_cost = calculate_topping(pearl, coconut, pudding); // 计算加料费,函数是“加料收银员”float total_price = topping_cost + volume/100.0*5; // 基础价每100ml 5元,700ml就是7*5=35元,总价=加料费+基础价// 打印订单printf("=== 您的奶茶订单 ===\n");printf("杯型:%c杯(%dml)\n", cup_size, volume);printf("加料:珍珠%d份,椰果%d份\n", pearl, coconut);printf("总价:%.1f元\n", total_price);return 0; // 订单计算完毕,程序向系统报告“奶茶店系统已完成任务,没有bug!”,可以安心“下班”啦~
}

运行结果

=== 您的奶茶订单 ===
杯型:L杯(700ml)
加料:珍珠2份,椰果1份
总价:22.0元

模块化的好处:如果未来杯型价格调整,只需要修改get_cup_volume一个函数,其他代码完全不用动,维护成本暴跌!就像奶茶店换了新的杯型模具,只需要改模具设计图,不用重装修整个店铺。

五、💡 函数使用避坑小课堂:新手必看!

5.1 返回值失踪案:忘记写return

int calculate(int a, int b) {int result = a * b; // 算完了但没return!相当于做好了饭却不端上桌
} // 报错:缺少返回语句,编译器大喊:“结果呢?我等着交差呢!”

后果:函数会返回一个随机垃圾值,就像外卖没写地址,不知道会送到哪个“内存小区”,可能导致后续计算出错,就像用错误的配料做奶茶,顾客喝了要投诉!


5.2 参数类型穿越剧:实参与形参不匹配

void heat_water(int temp) { // 形参是int,要求输入整数温度printf("加热到%d度\n", temp);
}heat_water(100.9); // 实参是double,强制截断为100!小数部分被“截肢”,相当于把100.9℃的水当成100℃加热

后果:小数部分被“截肢”,实际加热温度比预期低,可能导致“奶茶不够烫”事故,顾客抱怨“这奶茶温吞吞的!”


5.3 函数声明失踪案:先调用后定义

int main() {print_message(); // 调用在定义之前,编译器不认识!就像你没介绍朋友,直接喊“这是我兄弟”,别人会一脸懵return 0;
}void print_message() { // 定义在后面,报错!编译器说:“没提前告诉我有这个人,我不认!”printf("Hello from function!\n");
}

解决办法:在main函数前加一句声明:void print_message();,相当于提前告诉编译器“我后面会定义这个函数,先记个名字”,就像提前告诉朋友“等会来个叫小明的,是我哥们”。


5.4 致命错误:错误的main函数返回类型

void main() { // 严重错误!C语言不允许void main,这是很多编程教材的“历史遗留问题”printf("Hello world\n");
}
// ❌ 正确姿势:必须返回int
int main() {printf("Hello world\n");return 0; // 标准结尾,缺一不可!就像写作文必须有开头和结尾,少了结尾老师要扣分
}

六、编程冷笑话:函数的“内心OS”

  • Q:为什么函数从来不会迷路?
    A:因为它总是被“调用”(call),目标明确,不像指针喜欢到处乱指~

  • Q:为什么void函数最佛系?
    A:它没有返回值的烦恼,就像程序员遇到“需求待定”时,默默写代码不说话~

  • Q:为什么main函数的return 0像晚安问候?
    A:因为它意味着“程序今天的工作结束啦,明天见~”,让操作系统安心睡觉💤


七、✨ 今日金句

“函数是代码世界的‘瑞士军刀’,
把重复的逻辑磨成锋利的刀刃,
让你的代码像乐高一样自由拼接,
一个人就能写出千军万马的气势!”
—— 记住,return 0不是随便写的结束符,而是程序对世界的温柔告别:“我已完成使命,一切安好。”

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

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

相关文章

多模态大语言模型arxiv论文略读(七十四)

UniQA: Unified Vision-Language Pre-training for Image Quality and Aesthetic Assessment ➡️ 论文标题&#xff1a;UniQA: Unified Vision-Language Pre-training for Image Quality and Aesthetic Assessment ➡️ 论文作者&#xff1a;Hantao Zhou, Longxiang Tang, Ru…

Flutter - UIKit开发相关指南 - 线程和异步

线程和异步 编写异步代码 Dart采用单线程执行模型,支持Isolates(在另一个线程上运行Dart代码)、事件循环和异步编程。除非生成一个Isolates&#xff0c;否则Dart代码将在主UI线程中运行&#xff0c;并由事件循环驱动。Flutter的事件循环相当于iOS的主线程上的RunLoop。 Dart…

【愚公系列】《Manus极简入门》038-数字孪生设计师:“虚实映射师”

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…

西门子WinCC Unified PC的GraphQL使用手册

TIA V20版本&#xff1a;添加用户 添加角色&#xff0c;并充分授权&#xff0c;尤其是GraphQL的读写权限。 通过SIMATIC Runtime Manager启动wincc unifi工程。 打开浏览器&#xff0c;访问本地的https://localhost/graphql/&#xff0c;运行正常如图&#xff1a; 连接外…

开源长期主义:浅谈DeepSeek技术主张与早期论文

开源、长期主义与DeepSeek的技术愿景 ©作者|格林 来源|神州问学 导入&#xff1a;Deepseek在早期就开源了许多优秀的指令模型与对话模型&#xff0c;并发布了多篇论文。以下&#xff0c;我们将基于Deepseek在早期发布的6篇论文&#xff0c;来梳理Deepseek公司的技术路径与…

TTS-Web-Vue系列:Vue3实现内嵌iframe文档显示功能

&#x1f5bc;️ 本文是TTS-Web-Vue系列的新篇章&#xff0c;重点介绍如何在Vue3项目中优雅地实现内嵌iframe功能&#xff0c;用于加载外部文档内容。通过Vue3的响应式系统和组件化设计&#xff0c;我们实现了一个功能完善、用户体验友好的文档嵌入方案&#xff0c;包括加载状态…

Elasticsearch索引设计与调优

一、分片策略设计 1.‌分片容量规划 单分片容量建议30GB(日志场景可放宽至100GB),避免超大分片引发查询延迟。分片总数计算公式:总数据量 / 30GB 1.2(20%余量应对未来增长)。主分片数创建后不可修改,副本分片数支持动态调整。2.‌分片分布优化 PUT logs-2025 { &qu…

Spring AI 集成 Mistral AI:构建高效多语言对话助手的实战指南

Spring AI 集成 Mistral AI&#xff1a;构建高效多语言对话助手的实战指南 前言 在人工智能应用开发领域&#xff0c;选择合适的大语言模型&#xff08;LLM&#xff09;与开发框架至关重要。Mistral AI 凭借其高效的多语言模型&#xff08;如 Mistral-7B、Mixtral-8x7B 等&am…

从新手到高手:全面解析 AI 时代的「魔法咒语」——Prompt

引言&#xff1a;AI 时代的「语言炼金术」 在人工智能技术突飞猛进的今天&#xff0c;我们正在经历一场堪比工业革命的生产力变革。从聊天机器人到图像生成&#xff0c;从数据分析到自动化写作&#xff0c;AI 模型正在重塑人类与信息交互的方式。而在这一切背后&#xff0c;隐…

MySQL 8.0安装(压缩包方式)

MySQL 8.0安装(压缩包方式) 下载安装包并解压 下载 https://dev.mysql.com/downloads/mysql/可关注“后端码匠”回复“MySQL8”关键字获取 解压&#xff08;我解压到D:\dev\mysql-8.4.5-winx64目录下&#xff09; 创建mysql服务 注意&#xff0c;这步之前一定要保证自己电…

免费Ollama大模型集成系统——Golang

Ollama Free V2 Web 功能实现&#xff1a;界面交互与后端逻辑 一、Web 界面概述 Ollama Free V2 的 Web 界面提供了丰富的交互功能&#xff0c;包括模型选择、图片上传、历史记录查看等。界面使用 Bootstrap 进行布局&#xff0c;结合 JavaScript 实现动态交互。 二、前端界…

【AI】人工智能数据标注细分和商业机会

一、数据标注的常见方法 数据标注是为人工智能模型训练提供高质量标签的过程&#xff0c;根据数据类型&#xff08;图像、文本、音频、视频等&#xff09;的不同&#xff0c;标注方法也有所差异&#xff1a; 1. 图像标注 分类标注&#xff1a;为图像分配类别标签&#xff08…

lanqiaoOJ 652:一步之遥 ← 扩展欧几里得定理

【题目来源】 https://www.lanqiao.cn/problems/652/learning/ 【题目背景】 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 【题目描述】 从昏迷中醒来&#xff0c;小明发现自己被关在X星球的废矿车里。矿车停在平直的废弃…

HTTP / HTTPS 协议

目录 一、前言&#xff1a; 二、Fiddler 抓包工具&#xff1a; 三、http 协议&#xff1a; 1、http 请求&#xff1a; 1.&#xff08;1&#xff09;请求行&#xff1a; 1、(2) 请求头&#xff1a; 1、(3) 请求正文: 2、http 响应&#xff1a; 2、(1) 状态码&#x…

使用泛型加载保存数据

文章速览 泛型泛型概述定义优点 实例加载数据保存数据 一个赞&#xff0c;专属于你的足迹&#xff01; 泛型 泛型概述 泛型&#xff08;Generics&#xff09;是 C# 中一种重要的编程特性&#xff0c;它允许程序员编写灵活且类型安全的代码。通过使用泛型&#xff0c;可以创建…

Redis内存淘汰策略和过期键删除策略有哪些?

Redis 提供 8 种内存淘汰策略&#xff0c;以下是详细解析及场景建议&#xff1a; 一、核心策略解析 noeviction (默认策略) 机制&#xff1a;内存满时拒绝新写入操作&#xff0c;返回错误优势&#xff1a;绝对数据安全场景&#xff1a;金融交易系统、医疗数据存储 allkeys-lr…

【C/C++】自定义类型:结构体

文章目录 前言自定义类型&#xff1a;结构体1.结构体类型的声明1.1 结构体回顾1.1.1 结构的声明 1.1.2 结构体变量的创建和初始化1.2 结构的特殊声明1.3 结构的自引用 2.结构体内存对齐2.1 对⻬规则2.2 为什么存在内存对齐&#xff1f;2.3 修改默认对⻬数 3. 结构体传参4.结构体…

PPO算法:一种先进的强化学习策略

什么是PPO算法&#xff1f; PPO&#xff08;Proximal Policy Optimization&#xff09;是一种增强学习算法&#xff0c;主要应用于解决连续控制任务。PPO算法在2017年由OpenAI提出&#xff0c;旨在解决传统策略梯度方法在连续控制任务中面临的挑战。PPO算法通过引入一个近似目…

OpenCV实现数字水印的相关函数和示例代码

OpenCV计算机视觉开发实践&#xff1a;基于Qt C - 商品搜索 - 京东 实现数字水印的相关函数 用OpenCV来实现数字水印功能&#xff0c;需要使用一些位操作函数&#xff0c;我们需要先了解一下这些函数。 1. bitwise_and函数 bitwise_and函数是OpenCV中的位运算函数之一&…

基于Python的计算机科学研究话题管理系统的设计与实现 - 爬虫

标题:基于Python的计算机科学研究话题管理系统的设计与实现 - 爬虫 内容:1.摘要 本文聚焦于基于Python的计算机科学研究话题管理系统的爬虫部分。背景是随着计算机科学研究的快速发展&#xff0c;相关话题数据海量且分散&#xff0c;人工管理效率低。目的是设计并实现一个能高…