C语言:函数
C语言:函数
- 函数的概念
- 库函数
- 自定义函数
- 实参与形参
- return语句
- 数组做参数
- 声明与定义
- extern
- static
- 嵌套调用
函数的概念
在C语言中,存在一个函数的概念,有人也将其翻译为子程序。
在数学中,函数是一个完成特定功能的公式,比如传入x的值,就能输出满足函数的y值。C语言函数也同理,C语言的函数是一个完成某项特定任务的代码段。
而我们常见的函数,分为库函数与自定义函数,接下来我一一为大家介绍。
库函数
C语言标准中,规定了一系列常用的函数标准,称为标准库。编译器厂商就会根据这个标准来实现一系列函数,供用户使用,这些函数就称之为库函数。
要注意,库函数不是C语言官方实现的,C语言只制定标准,具体实现是编译器的厂商来完成的,所以不同的编译器下,库函数的实现可能不同,但是用法是一致的。
库函数是在标准库对应的头文件中声明的,所以库函数的使用需要包含对应的头文件。
自定义函数
顾名思义,自定义函数就是用户可以自己设计函数。
语法:
返回类型 函数名(参数)
{//代码
}
返回类型:就是函数结束时返回什么样类型的值,比如我们调用rand函数,其会返回一个整数给我们,那么rand函数的返回类型就是int。
参数:就是用户使用这个函数,需要传入的值。
比如这样一个加法函数:
int add(int x, int y)
{int z = x + y;return z;
}
函数名就是add,而add左侧的int就是函数的返回类型,说明add函数最后会返回一个int类型的数据。
(int x, int y)就是函数的参数,这说明使用这个函数需要传入两个int类型的数据。
在需要使用函数时,可以这样:
add(3, 5);
也就是函数名(参数)的形式。
实参与形参
含函数使用的过程中,我们把参数分为形参和实参。
实参:
在以上的add函数中,我们在调用时add(3, 5)中的3和5就是实参,它们是传入函数的数据。
形参:
在定义函数时,add函数名后面的(int x, int y)中的x和y就是形参。
为什么叫做形参呢?实际上,如果只是定义了add函数而不去调用的话,x和y只是形式上存在的,它们并不会向内存申请空间,不会真实存在,所以叫做形参。
而形参是实参的一份临时拷贝,对形参的改动不会影响实参。
比如下面的函数:
void func(int x)
{x++;
}int main()
{int a = 0;func(a);printf("%d", a);return 0;
}
上述函数中,a就是一个实参,起初a = 0,当我们把a传给函数func,形参x得到a的值。在函数内部对形参进行了x++,此时x = 1,当函数结束时,输出a的值。
最后输出的a = 0,因为x作为形参,x++对a没有影响。
return语句
当我们的函数需要返回值的时候,就需要return语句,return后面接着的值,就是函数最后返回给外界的值。
- return后面可以是数值,也可以是表达式。
- return后面也可以什么都没有,直接写return;,这种形式适合返回值为void类型。
- return后面的值类型如果与返回类型不一致,编译器则会将其隐式转化。
- 如果函数中有分支语句,要保证每种情况都有返回值。
数组做参数
数组也可以做函数的参数,比如这样:
void func(int arr[])
{
}
其中int arr[]就是一个数组类型的参数,其可以接收一个数组。
数组传参时,直接传入数组名即可:
int main()
{int arr[5] = {1, 2, 3, 4, 5};func(arr);return 0;
}
- 当一维数组做形参时,数组的长度是可以省略的。
- 当二位数组做形参时,行可以省略,列不可以省略。
- 当数组做参数,实参和形参是同一个数组,修改形参会对实参造成影响。
声明与定义
C语言的函数声明和定义是定义函数的两个主要部分。
函数定义是指在函数声明的基础上,给出函数的具体实现。函数定义包含函数的返回值类型、函数名、函数的参数列表和函数体。函数定义的目的是为了给出函数的具体实现,也就是函数体中要执行的代码。
函数定义的语法格式如下:
返回类型 函数名(参数)
{// 函数体
}
也就是我们先前讲的基本格式,我们实现函数的功能,就是在函数定义时完成的。
函数声明是指在函数被调用之前,在代码的某个地方提前声明函数的存在。函数声明告诉编译器函数的名称、函数参数的类型和返回值类型。函数声明的目的是为了让编译器在编译过程中能够正确地解析函数的调用。
函数声明的语法格式如下:
返回值类型 函数名(参数类型1 参数名1, 参数类型2 参数名2, ...)
比如:
int sum(int a, int b);
这就是一个函数的声明,可以理解为函数声明就是函数定义去掉了{}内部的内容。
不过函数声明也可以只有类型,没有形参名称,比如这样:
int sum(int, int);
函数声明和定义的关系是:函数声明是对函数定义的提前声明,函数定义是对函数的具体实现。在实际使用中,通常将函数的声明放在头文件中,将函数的定义放在源文件中。这样做的好处是可以将函数的声明和定义进行分离,方便代码的管理和维护。
需要注意的是,在C语言中,函数的声明和定义可以放在任意顺序,只要在函数被调用之前可以访问到函数的声明即可。
extern
在C语言中,extern关键字用于声明一个全局变量或者函数,但不进行定义。它可以被用于多个源文件中,用于告诉编译器该变量或函数是在其他源文件中定义的。
在C语言中,变量的声明和定义是不同的。声明告知编译器该变量的类型和名称,而定义则为该变量分配存储空间并初始化它。如果在一个源文件中声明一个全局变量,那么在其他源文件中访问该全局变量就需要使用extern关键字。
这里是一个例子来说明extern关键字的使用:
假设我们有两个源文件:main.c和helpers.c。我们希望在main.c中使用helpers.c中定义的全局变量count和函数increment()。
首先,我们在helpers.c中定义全局变量:
int count = 0;void increment() {count++;
}
然后,在main.c中声明这些全局变量和函数,并使用extern关键字告诉编译器它们是在其他源文件中定义的:
#include <stdio.h>extern int count; // 声明count变量
extern void increment(); //声明increment函数int main() {increment(); // 调用increment函数printf("count: %d\n", count); // 访问count变量return 0;
}
注意,在main.c中,我们需要包含helpers.c中定义的函数的头文件,以便在编译过程中编译器可以知道函数的签名。
编译并运行这些代码,输出将会是count: 1。这是因为我们在increment函数中增加了count变量的值,并在main函数中访问了它。
总结一下,extern关键字是用于在一个源文件中访问另一个源文件中定义的全局变量和函数。它将变量或函数的声明与定义分离,使得代码更加模块化和可扩展。
static
在C语言中,"static"是一个关键字,用于修饰变量和函数。它的行为和作用会根据修饰的对象不同而有所不同。下面分别介绍"static"关键字在变量和函数中的作用,并给出相关案例。
-
"static"修饰变量:
-
在函数内部,"static"修饰的局部变量会被赋予静态的存储持续时间。这意味着变量的生命周期将持续到程序结束,而不是在函数执行完后销毁。此外,静态局部变量的作用域仍然是局部的,只能在定义它的函数内部使用。
-
例子:
#include <stdio.h>void example() {static int count = 0;count++;printf("Count: %d\n", count); }int main() {for (int i = 0; i < 5; i++) {example();}return 0; }输出结果:
Count: 1 Count: 2 Count: 3 Count: 4 Count: 5在上面的例子中,静态变量"count"被定义为函数"example()"的局部变量。每次调用"example()"函数时,"count"值递增并打印。由于静态变量的存储持续时间为整个程序,因此每次调用"example()"函数时,"count"的值会保留。
-
在全局范围内,"static"修饰的全局变量具有内部链接,即只能在当前源文件中访问,其他源文件中不可见。
-
例子:
// File1.c static int global_var = 10;// File2.c #include <stdio.h>extern int global_var;int main() {printf("Global Variable: %d\n", global_var);return 0; }输出结果:
Global Variable: 10在上面的例子中,我们在File1.c中声明了一个静态全局变量"global_var"。由于它是静态的,所以只能在同一源文件中访问。然后,在File2.c中通过extern关键字声明"global_var",确保在其他源文件中可见,从而在main函数中进行访问。
-
-
"static"修饰函数:
- 在函数声明前,"static"修饰的函数具有内部链接。这意味着该函数只能在当前源文件中访问,其他源文件中不可见。
- 例子:
输出结果:// File1.c static void static_function() {printf("This is a static function.\n"); }// File2.c extern void static_function();int main() {static_function();return 0; }
在上面的例子中,我们在File1.c中定义了一个静态函数"static_function()“。由于它是静态的,所以只能在同一源文件中访问。然后,在File2.c中通过extern关键字声明"static_function()”,确保在其他源文件中可见,从而在main函数中进行访问。This is a static function.
总结:
- 在C语言中,"static"关键字的作用取决于其修饰的对象。它可以用于修饰局部变量和全局变量,以及函数声明。
- 对于局部变量,"static"赋予了它们静态存储持续时间和保留其值的能力。
- 对于全局变量,"static"给予了它们内部链接特性,使其只能在同一源文件中访问。
- 对于函数声明,"static"使其具有内部链接特性,使其只能在同一源文件中访问。
嵌套调用
在C语言中,函数的嵌套调用指的是在一个函数中调用另一个函数,而被调用的函数又可以继续调用其他函数。这种嵌套调用的方式可以实现代码的模块化,提高代码的可读性和可维护性。
下面以一个简单的例子来说明函数的嵌套调用:
#include <stdio.h>int func2(int num)
{printf("In func2\n");return num * num;
}int func1(int num)
{printf("In func1\n");int result = func2(num);return result + 1;
}int main()
{int number = 3;int result = func1(number);printf("Result: %d\n", result);return 0;
}
在上面的例子中,有三个函数:main、func1和func2。main函数是程序的入口,func1和func2是被调用的函数。
main函数中定义了一个整型变量number,并将其赋值为3。然后调用func1函数,将number作为参数传递给func1。在func1函数中,可以看到它调用了func2函数,并将num作为参数传递给func2。func2函数执行完毕后,返回结果给func1,最后func1将其结果加1并返回给main函数。
运行上述代码,输出结果如下:
In func1
In func2
Result: 10
从结果可以看出,main函数调用func1函数,func1函数又调用了func2函数,实现了函数的嵌套调用。通过函数的嵌套调用,可以将代码按照功能划分为若干个小模块,提高代码的可读性和可维护性。
相关文章:
C语言:函数
C语言:函数 函数的概念库函数自定义函数实参与形参return语句数组做参数声明与定义externstatic 嵌套调用 函数的概念 在C语言中,存在一个函数的概念,有人也将其翻译为子程序。 在数学中,函数是一个完成特定功能的公式࿰…...
jmeter-问题一:关于线程组,线程数,用户数详解
文章目录 jmeter参数介绍1.线程数2.准备时长(Ramp-up)3.循环次数4.same user on each iteratio5.调度器 场景一:当你的线程组中线程数为1,循环为1场景二:当你的线程组中线程数为2,循环为1场景三:当你的线程组中线程数为1ÿ…...
golang 通过 cgo 调用 C++ 库
思路 将 C 库包装成 C 库 -> golang 通过 cgo 调用 C 库 C 相关文件 目录列表 include/ some.h C 库头文件some_wrapper.h < 用于将 C 库包装成 C 库的头文件 lib/ libsome.a C 库 src/ some_wrapper.cpp < 用于将 C 库包装成 C 库的源码文件 源码示例 some.h…...
使用 IDEA 开发一个简单易用的 SDK
目录 一、什么是 SDK 二、为什么要开发 SDK 三、开发 SDK 的详细步骤 四、导入 SDK 进行测试 附:ConfigurationProperties 注解的介绍及使用 一、什么是 SDK 1. 定义:软件开发工具包 Software Development Kit 2. 用于开发特定软件或应用程序的工…...
CSS transition(过渡效果)详解
CSS过渡效果(Transition)是一种在CSS3中引入的动画效果,它允许开发者在元素状态变化时(如鼠标悬停、类更改等)平滑地改变CSS属性值,从而创建出平滑的动画效果。过渡效果可以应用于多种CSS属性,如…...
Android13多媒体框架概览
Android13多媒体框架概览 Android 多媒体框架 Android 多媒体框架旨在为 Java 服务提供可靠的接口。它是一个系统,包括多媒体应用程序、框架、OpenCore 引擎、音频/视频/输入的硬件设备,输出设备以及一些核心动态库,比如 libmedia、libmedi…...
一文读懂:MybatisPlus从入门到进阶
快速入门 简介 在项目开发中,Mybatis已经为我们简化了代码编写。 但是我们仍需要编写很多单表CURD语句,MybatisPlus可以进一步简化Mybatis。 MybatisPlus官方文档:https://www.baomidou.com/,感谢苞米豆和黑马程序员。 Mybat…...
C语言--------指针(1)
0.指针&指针变量 32位平台,指针变量是4个字节(32bit/84)--------x86 64位平台,指针变量是8个字节(64bit/88)--------x64 编号指针地址;我们平常讲的p是指针就是说p是一个指针变量; ************只要…...
Vite 下一代的前端工具链,前端开发与构建工具
一、Vite 简介 官方中文网站:Vite | 下一代的前端工具链 官方定义: Vite,下一代的前端工具链,为开发提供极速响应。 Vue3.4版本,Vue新版本使用Vite构建、开发、调试、编译。 Vite的优势 极速的服务启动 使用原生…...
【SpringBoot】FreeMarker视图渲染
目录 一、FreeMarker 简介 1.1 什么是FreeMarker? 1.2 Freemarker模板组成部分 1.3 为什么要使用FreeMarker 二、Springboot集成FreeMarker 2.1 配置 2.2 数据类型 2.2.1 字符串 2.2.2 数值 2.2.3 布尔值 2.2.4 日期 2.3 常见指令 2.3.2 assign 2.3…...
巴尔加瓦算法图解:算法运用。
树 如果能将用户名插入到数组的正确位置就好了,这样就无需在插入后再排序。为此,有人设计了一种名为二叉查找树(binary search tree)的数据结构。 每个node的children 都不大于两个。对于其中的每个节点,左子节点的值都比它小,…...
Docker的镜像和容器的区别
1 Docker镜像 假设Linux内核是第0层,那么无论怎么运行Docker,它都是运行于内核层之上的。这个Docker镜像,是一个只读的镜像,位于第1层,它不能被修改或不能保存状态。 一个Docker镜像可以构建于另一个Docker镜像之上&…...
忘记 RAG:拥抱Agent设计,让 ChatGPT 更智能更贴近实际
RAG(检索增强生成)设计模式通常用于开发特定数据领域的基于实际情况的ChatGPT。 然而,重点主要是改进检索工具的效率,如嵌入式搜索、混合搜索和微调嵌入,而不是智能搜索。 这篇文章介绍了一种新的方法,灵感…...
利用路由懒加载和CDN分发策略,对Vue项目进行性能优化
目录 一、Vue项目 二、路由懒加载 三、CDN分发策略 四、如何对Vue项目进行性能优化 一、Vue项目 Vue是一种用于构建用户界面的JavaScript框架,它是一种渐进式框架,可以用于构建单页应用(SPA)和多页应用。Vue具有简单易学、灵…...
【Scala】1. 变量和数据类型
1. 变量和数据类型 1.1 for begining —— hello world 新建hello.scala文件,注意object名字与文件名一致。 object hello { def main(args:Array[String]): Unit { println("hello world!") } }运行后打印结果如下: hello world!Pr…...
何时以及如何选择制动电阻
制动电阻的选择是优化变频器应用的关键因素 制动电阻器在变频器中是如何工作的? 制动电阻器在 VFD 应用中的工作原理是将电机减速到驱动器设定的精确速度。它们对于电机的快速减速特别有用。制动电阻还可以将任何多余的能量馈入 VFD,以提升直流母线上的…...
消息中间件:Puslar、Kafka、RabbigMQ、ActiveMQ
消息队列 消息队列:它主要用来暂存生产者生产的消息,供后续其他消费者来消费。 它的功能主要有两个: 暂存(存储)队列(有序:先进先出 从目前互联网应用中使用消息队列的场景来看,…...
Rust开发WASM,浏览器运行WASM
首先需要安装wasm-pack cargo install wasm-pack 使用cargo创建工程 cargo new --lib mywasm 编辑Cargo.toml文件,修改lib的类型为cdylib,并且添加依赖wasm-bindgen [package] name "mywasm" version "0.1.0" edition "…...
Vue3编写简单的App组件(二)
一、Vue3页面渲染基本流程 1、入口文件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><link rel"icon" href"/favicon.ico"><meta name"viewport" content"widthde…...
java Servlet 云平台教学系统myeclipse定制开发SQLServer数据库网页模式java编程jdbc
一、源码特点 JSP 云平台教学系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助 系统采用serlvet dao bean,系统具有完整的源代码和数据库 ,系统主要采用B/S模式开发。开发 环境为TOMCAT7.0,Myeclipse8.5开发,数据…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
