news 2026/4/23 19:08:51

C 语言学习历程:(第六章)函数・程序中的逻辑封装艺术

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C 语言学习历程:(第六章)函数・程序中的逻辑封装艺术

第六章:函数

文章目录

  • 第六章:函数
    • 1. 库函数
    • 2. 自定义函数
      • 2.1 形参和实参
      • 2.2 return 语句
      • 2.3 数组做函数参数
    • 3. 嵌套调用和链式访问
      • 3.1 嵌套调用
      • 3.2 链式访问
    • 4. 函数声明和定义
      • 4.1 单个文件
      • 4.2 多个文件
      • 4.3 关键字使用
        • 4.3.1 extern
        • 4.3.2 static
  • 声明

C 语言中的函数就是一个完成某项特定任务的一小段代码。

1. 库函数

不同编译器提供的一系列函数的实现,就被称为库函数。这些库函数根据功能的划分,都在不同的头文件中进行声明。

库函数相关头文件:C Standard Library headers - cppreference.com

2. 自定义函数

语法形式

函数返回类型 函数名(形式参数){}

2.1 形参和实参

  • 形参:在自定义函数的括号中写的参数,称为形式参数
  • 实参:真是传递给函数的参数
  • 函数的形式参数要和和实参个数匹配

只有在函数被调用的过程中存放实参传递过来的值,才会向内存申请空间

加法函数,完成两个整形变量的加法操作:

#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdbool.h>//第六章:函数//此时是形参,在不调用此函数时,不会分配内存空间,//当调用函数时,形参便会分配内存空间(和实参各自有独立的空间)intadd(inta,intb){returna+b;//将a+b的值返回出去}intmain(){inta=0;intb=0;intc=add(a,b);//调用函数,将变量传递进去,此时是实参scanf("%d",&c);printf("两个数之和是:%d",c);return0;}

2.2 return 语句

  • return后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执⾏表达式,再返回表达式 的结果。
  • return后边也可以什么都没有,直接写 return; 这种写法适合函数返回类型是void的情况。
  • return语句执⾏后,函数就彻底返回,后边的代码不再执⾏。
  • return返回的值和函数返回类型不⼀致,系统会⾃动将返回的值隐式转换为函数的返回类型。
  • 如果函数中存在if等分⽀的语句,则要保证每种情况下都有return返回,否则会出现编译错误。
  • 函数的返回类型如果不写,编译器会默认函数的返回类型是int。
  • 函数写了返回类型,但是函数中没有使⽤return返回值,那么函数的返回值是未知的。

2.3 数组做函数参数

  • 函数的实参是数组,形参也是可以写成数组形式的
  • 形参如果是⼀维数组,数组⼤⼩可以省略不写
  • 形参如果是⼆维数组,⾏可以省略,但是列不能省略
  • 数组传参,形参是不会创建新的数组的
  • 形参操作的数组和实参的数组是同⼀个数组

写一个函数将一个整形数组的内容,全部置为 -1,再写一个函数打印数组内容

#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdbool.h>//数组做函数参数,数组的实参和形参是同一块内存空间//将数组内容全部置换为 -1voidset_arr(intarr[],intsz)//此时不设置长度,根据传过来的大小底层自动推断{for(inti=0;i<sz;i++){arr[i]=-1;}}//打印数组voidprint_arr(intarr[],intsz){for(inti=0;i<sz;i++){printf("%d ",arr[i]);}}intmain(){//定义数组intarr[]={1,2,3,4,5,6,7,8,9,10};//计算数组长度intsz=sizeof(arr)/sizeof(arr[0]);//调用置换数组函数set_arr(arr,sz);//调用打印数组函数print_arr(arr,sz);return0;}

3. 嵌套调用和链式访问

3.1 嵌套调用

函数之间的互相调用称为嵌套调用。

实现计算某年某月有多少天:

#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdbool.h>//嵌套调用//定义函数判断是否为闰年boolis_leap_year(intyear){if((year%4==0&&year%100!=0)||year%400==0){returntrue;}returnfalse;}//定义函数计算某年某月有多少天intget_days(intyear,intmonth){// 0 1 2 3 4 5 6 7 8 9 10 11 12intdays[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//前面补0,方便月份和下标对应if(is_leap_year(year)&&month==2)//嵌套调用判断是否是闰年和2月{days[month]+=1;//如果是闰年2月,则天数加1returndays[month];}returndays[month];//不是闰年,则直接返回对应月份的天数}intmain(){intyear=0;intmonth=0;scanf("%d%d",&year,&month);intdays=get_days(year,month);printf("%d年%d月有%d天\n",year,month,days);return0;}

3.2 链式访问

谓链式访问就是将⼀个函数的返回值作为另外⼀个函数的参数,像链条⼀样将函数串起来就是函数 的链式访问

//链式访问#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>intmain(){//printf的返回值是输出字符的个数,包括换行符和空格//输出 43 3 2printf("%d ",printf("%d ",printf("%d ",43)));return0;}

4. 函数声明和定义

4.1 单个文件

当我们将自定义的函数放在 main 函数后,也就是调用此函数之后,需要在函数调用前声明一下此函数。函数的调用要满足先声明后使用,函数的定义是一种特殊的声明。

  • 函数声明:函数返回类型 函数名(函数参数)
#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdbool.h>boolis_leap_year(intyear);//函数声明intmain(){intyear=0;intmonth=0;scanf("%d%d",&year,&month);intdays=get_days(year,month);printf("%d年%d月有%d天\n",year,month,days);return0;}//定义函数判断是否为闰年boolis_leap_year(intyear){if((year%4==0&&year%100!=0)||year%400==0){returntrue;}returnfalse;}

4.2 多个文件

函数的声明和类型的声明放在头文件中 (.h) ,函数的实现放在其他源文件中 (.c) ,此时 main 函数所在的源文件要包括自定义的头文件。

add.h

#pragmaonce//头文件用于声明函数、类、变量等,防止重复包含intadd(inta,intb);

add.c

#define_CRT_SECURE_NO_WARNINGS//函数的定义intadd(inta,intb){//将a+b的值返回出去returna+b;}

test.c

#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>//包含自定义头文件,注意使用双引号#include"add.h"intmain(){inta=0;intb=0;scanf("%d%d",&a,&b);intc=add(a,b);printf("和是:%d\n",c);}

4.3 关键字使用

作用域:一段程序中所用到的名字并不是总有效,可用性的代码范围称为作用域

  • 局部变量:变量所在的局部范围
  • 全局变量:整个项目

生命周期:变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段

  • 局部变量:进入作用域变量创建,生命周期开始,出作用域生命周期结束
  • 全局变量:整个程序的声明周期
4.3.1 extern

用于声明外部符号,如果一个全局的符号在A文件中定义,在B文件中想使用,就需要使用extern进行声明。

4.3.2 static

修饰局部变量

static 修饰局部变量改变了变量的⽣命周期,⽣命周期改变的本质是改变了变量的存储类型,本来⼀个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。存储在静态区的变量和全局变量是⼀样的,⽣命周期就和程序的⽣命周期⼀样了,只有程序结束,变量才销毁,内存才 回收。但是作用域不变的。

修饰全局变量或函数

⼀个全局变量被static修饰,使得这个全局变量只能在本源⽂件内使⽤,不能在其他源⽂件内使⽤。 本质原因是全局变量默认是具有外部链接属性的,在外部的⽂件中想使⽤,只要适当的声明就可以使⽤;但是全局变量被 static 修饰之后,外部链接属性就变成了内部链接属性,只能在⾃⼰所在的源⽂件内部使⽤了,其他源⽂件,即使声明了,也是无法正常使⽤的。函数同理

test2.c

#define_CRT_SECURE_NO_WARNINGS//定义全局变量//全局变量默认具有链接属性,其他文件可以通过extern进行访问//如果此时加上static,则变为内部链接属性,其他源文件无法访问//函数原理同上intnum=10;

test.c

#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>//static 和 extern关键字的使用voidtest();//函数声明externintnum;//声明外部变量intmain(){for(inti=0;i<5;i++){test();}printf("num = %d\n",num);return0;}voidtest(){//静态变量,只初始化一次(在程序编译时),仅改变生命周期,生命周期为整个程序运行期间//如果不加入static关键字,则每次调用变量时,变量都会重新初始化,即局部变量staticinta=0;a++;printf("%d\n",a);}

声明

本文是在鹏哥 C 语言集训营学习过程中所记录的学习笔记,梳理了核心知识点,同时也记录了本人实操验证的代码案例,供后续学习复盘使用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:50:20

颠覆式资源获取工具:Res-Downloader全平台高效下载解决方案

颠覆式资源获取工具&#xff1a;Res-Downloader全平台高效下载解决方案 【免费下载链接】res-downloader 资源下载器、网络资源嗅探&#xff0c;支持微信视频号下载、网页抖音无水印下载、网页快手无水印视频下载、酷狗音乐下载等网络资源拦截下载! 项目地址: https://gitcod…

作者头像 李华
网站建设 2026/4/23 10:31:30

3大突破!MediaCrawler让跨平台数据采集效率提升90%的实战指南

3大突破&#xff01;MediaCrawler让跨平台数据采集效率提升90%的实战指南 【免费下载链接】MediaCrawler-new 项目地址: https://gitcode.com/GitHub_Trending/me/MediaCrawler-new MediaCrawler作为一款开源多媒体数据采集工具&#xff0c;专为高效整合多平台信息而设…

作者头像 李华
网站建设 2026/4/23 13:25:42

歌词工具提升音乐播放器体验:ESLyric-LyricsSource全功能指南

歌词工具提升音乐播放器体验&#xff1a;ESLyric-LyricsSource全功能指南 【免费下载链接】ESLyric-LyricsSource Advanced lyrics source for ESLyric in foobar2000 项目地址: https://gitcode.com/gh_mirrors/es/ESLyric-LyricsSource ESLyric-LyricsSource是一款专为…

作者头像 李华
网站建设 2026/4/23 11:53:04

Z-Image-Turbo推理时间优化:TensorRT加速部署可行性分析

Z-Image-Turbo推理时间优化&#xff1a;TensorRT加速部署可行性分析 1. 为什么Z-Image-Turbo需要更快的推理速度&#xff1f; 你有没有遇到过这样的情况&#xff1a;在WebUI里输入提示词&#xff0c;点击生成&#xff0c;然后盯着进度条等上半分钟&#xff1f;明明标榜“Turb…

作者头像 李华
网站建设 2026/4/23 11:51:02

Unsloth镜像安装失败?这些关键点一定要注意

Unsloth镜像安装失败&#xff1f;这些关键点一定要注意 你是不是也遇到过这样的情况&#xff1a;兴冲冲下载了Unsloth镜像&#xff0c;一运行就报错——conda环境找不到、Python模块导入失败、GPU识别异常&#xff0c;甚至卡在pip install unsloth这一步就再也动不了&#xff…

作者头像 李华