当前位置: 首页 > news >正文

C语言(12)——进阶函数

Hi!冒险者😎,欢迎闯入 C 语言的奇幻异世界🌌!

我是 ankleless🧑‍💻,和你一样的闯荡者~ 这是我的冒险笔记打怪升级之路——C语言之路📖,里面有踩过的坑🕳、攒的技能🌟、遇的惊喜🌈,希望能帮你少走弯路✨。

愿我们在代码山峦⛰各自攀登,顶峰碰拳👊,共赏风景呀!🥳

1. 函数的概念

在数学中,我们了解的简单的函数如: y = ax + b,其中a和 b是常数,对于任意给定的一个x,都有唯一的一个y与之对应,函数具有一一对应的特性。

同样地,我们在C语言中也引入了函数的概念,有些翻译为:子程序(程序块),子程序这种翻译更加准确一些,C语言中的函数就是一个完成特定功能的一小段代码。这段代码是有着特殊的写法和调用方法的。

C语言的程序其实是由无数个小的函数组合而成的,也可以说:一个大的计算任务可以分解成若干个小的函数(对应较小的任务)完成,同时一个函数如果能完成某项特定任务的话,这个函数也可以是复用的(重复使用),提升了开发软件的效率。

在C语言中我们一般会用到两种函数:库函数,自定义函数

2. 库函数

2.1 库函数的概念

一些常见的库函数可以在下方 博客中查询学习,遇见没有的函数可以私信博主~

C语言(02)——标准库函数大全(持续更新)_c语言库函数大全-CSDN博客

C语言中规定了C语言的各种语法规则,C语言并不提供库函数;C语言的国际标准ANSI C规定了一些常用的函数的标准,被称为标准库,那不同的编译器厂商根据ANSI提供的C语言标准就给出了一系列函数的实现。这些函数称之为库函数

我们可以在后续的网址中学习不同的库函数:cplusplus.com - The C++ Resources Network

2.2 库函数的使用方法

对库函数的了解和认识一般包含以下几个方面:

函数的返回值

函数名

函数的参数类型

函数的功能

函数的示例

我们不妨以fgets函数为例(下图是他在C++reference中的表现形式):

从上述图片中我们可以知道fgets为函数名,char *为他的返回值,char * str、int num,和file * stream均为他的参数,由参数类型和名称构成。

他的作用是:从流中读取字符串,将他们存储在输入的指针char*中,他的读取停止有三种情况:

读取num - 1个字符元素时;遇到换行符时;遇到了文件末尾EOF(此时返回NULL)

3. 自定义函数

自定义函数是C语言中重要的一个功能,他使得程序员可以发挥他们的主观能动性,因此这个模块的学习是十分重要的。

3.1 函数的声明和定义

简单说

  • 声明:告诉编译器 “我有这个函数,别报错”,像留个 “功能预告”;
  • 定义:真正把函数的 “干活逻辑” 写出来,是函数的 “实体内容”。

其实自定义函数的表现形式和库函数是一样的,如下:

ret_type fun_name(形式参数)
{
}

ret_type 是函数返回类型

fun_name 是函数名

括号中放的是形式参数

{}括起来的是函数体

┌───────────────┐
│   函数声明    │──→ 告诉编译器:有 Add 函数,参数、返回值是啥
└───────────────┘↓
┌───────────────┐
│   main 函数   │──→ 调用 Add(3,5),找定义好的逻辑
└───────────────┘↓
┌───────────────┐
│   函数定义    │──→ 真正计算 3+5,返回结果
└───────────────┘

为啥需要声明
如果函数定义写在 main 后面,编译器执行 main 时,会 “看不到” 函数逻辑,直接报错。声明就是提前 “打招呼”,让编译器放心

3.2 形参(形式参数)

简单说:函数定义 / 声明里,括号里的参数是 “形参”,相当于 “占位符”。调用函数时,才会用实际的值替换它。

代码示例

// Add 里的 a、b 就是形参,定义时只是占位
int Add(int a, int b) { return a + b;
}int main() {// 调用时,3 替换 a,5 替换 b,这时候才有实际值int result = Add(3, 5); return 0;
}

一句话总结:形参是 “函数里的变量占位”,调用时才会被实参(实际的值) 填充,形参实际上是实参内容的copy

3.3 实参(实际参数)

简单说:调用函数时,传给函数的具体值,就是实参。实参会 “填充” 到形参里,让函数干活。

代码示例

int Add(int a, int b) { // a、b 是形参(占位)return a + b;
}int main() {// 3 和 5 是实参,调用时传给 Add 函数int result = Add(3, 5); printf("结果:%d\n", result);return 0;
}

对比理解

  • 形参:函数里的 “变量名”(定义时用,占位用)
  • 实参:调用时的 “具体值”(传给函数,让形参有实际内容)

4. 函数的相关使用

学会定义函数后,还要掌握这些 “技巧”,让函数用得更灵活

4.1 return语句

作用

  1. 给函数 “返回一个结果”(比如 Add 返回 a + b);
  2. 提前结束函数(遇到 return,函数直接停止,回到调用处)。

代码示例 1(返回结果)

int Add(int a, int b) {// 返回 a + b 的结果,函数结束return a + b; 
}

代码示例 2(提前结束函数):

void PrintInfo(int age) {if (age < 0) {// 年龄不合法,直接结束函数,不执行下面的 printfreturn; }printf("年龄:%d\n", age);
}int main() {PrintInfo(-5); // 不会打印,直接 return 了PrintInfo(18); // 打印:年龄:18return 0;
}

注意

  • void 类型的函数(返回 void),可以写 return;(不加值),用来提前结束函数;
  • 非 void 类型(比如 intchar),return 后面必须跟对应类型的值

4.2 static函数(静态函数)

作用:用 static 修饰函数,让函数 “只能在当前文件里用”,其他文件看不到、不能调用。

代码示例(文件:test.c)

// 静态函数,只能在 test.c 里用
static int Add(int a, int b) { return a + b;
}int main() {// 可以调用(在同一个文件)int result = Add(3, 5); return 0;
}

如果其他文件(比如 main.c)想调用

// main.c 里尝试调用 test.c 的 static 函数
int main() {// 报错!Add 是 static,只能在 test.c 里用Add(3, 5); return 0;
}

啥时候用
想让函数 “私有”(只在当前文件干活,不暴露给其他文件),就用 static,避免函数名冲突

4.3 extern函数(外部函数)

作用:用 extern 可以 “跨文件调用函数”,告诉编译器:“这个函数在其他文件里定义,你别报错”。

场景:项目分多个文件,函数写在 A 文件,想在 B 文件用。

代码示例(分两个文件):

  • 文件:func.c(定义函数)
    // 定义 Add 函数
    int Add(int a, int b) { return a + b;
    }

  • 文件:main.c(调用函数)
    // 告诉编译器:Add 函数在其他文件定义(extern 可省略,默认支持跨文件找)
    extern int Add(int a, int b); int main() {// 调用 func.c 里的 Add 函数int result = Add(3, 5); printf("结果:%d\n", result);return 0;
    }

    注意

  • C 语言里,函数默认就是 “extern 类型”(跨文件可见),所以 extern 经常可以省略;
  • 用 extern 是明确告诉编译器 “去其他文件找函数”,让代码更清晰

总结

知识点核心作用简单示例
函数声明 + 定义声明 “预告”,定义 “实现逻辑”int Add(int a, int b); + 函数体
形参函数里的 “占位变量”,调用时被实参填充Add(int a, int b) 里的 a、b
实参调用函数时的 “具体值”,传给形参Add(3, 5) 里的 3、5
return 语句返回结果、提前结束函数return a + b; 或 return;
static 函数函数 “私有化”,只能在当前文件用static int Add(...)
extern 函数跨文件调用函数(默认也支持,写 extern 更清晰)extern int Add(...)

http://www.lryc.cn/news/623782.html

相关文章:

  • 北京JAVA基础面试30天打卡12
  • 语音转文字,如何提升内容创作效率?
  • 智能汽车领域研发,复用云原始开发范式?
  • WebSocket--精准推送方案(二):实时消息推送-若依项目示例
  • 在职老D渗透日记day19:sqli-labs靶场通关(第26a关)get布尔盲注 过滤or和and基础上又过滤了空格和注释符 ‘)闭合
  • 【架构师从入门到进阶】第五章:DNSCDN网关优化思路——第十一节:网关安全-对称与非对称加密
  • 告别“测试滞后”:AI实时测试工具在敏捷开发中的落地经验
  • 【165页PPT】锂电池行业SAP解决方案(附下载方式)
  • 自动驾驶中的传感器技术34——Lidar(9)
  • 定时器中断点灯
  • 记一次安装OpenStack(Stein)-nova报错问题解决
  • 42 C++ STL模板库11-容器4-forward_list
  • 利用标准IO实现寻找文件中字符出现最多次数
  • Opencv 形态学与梯度运算
  • python的软件工程与项目管理课程组学习系统
  • 【LeetCode题解】LeetCode 33. 搜索旋转排序数组
  • Android studio gradle有关设置
  • 一周学会Matplotlib3 Python 数据可视化-多子图及布局实现
  • java之 junit4单元测试Mockito的使用
  • 魔改chromium源码——解除 iframe 的同源策略
  • 《Nursing Research》(护理SCI)LaTeX模板详细教程:从入门到投稿(一)
  • 深度解析 Spring Bean 生命周期
  • Microsoft WebView2
  • SQL详细语法教程(四)约束和多表查询
  • 网络常识-我的电脑啥时安装了证书
  • 【力扣热题100】双指针—— 接雨水
  • 【AI智能体】Dify 搭建发票识别助手操作实战详解
  • 微信小程序 小白gps工具v0.01 使用说明
  • XF 306-2025 阻燃耐火电线电缆检测
  • QUIC浅析