【C语言__函数__复习篇1】

目录

前言:

一、C语言中函数的概念

二、库函数

        2.1 库函数的概念

        2.2 怎样自学库函数——以sqrt函数为例 

三、自定义函数

        3.1 自定义函数的概念

        3.2 自定义函数的语法形式 

        3.3 函数的实参

        3.4 函数的形参

        3.5 实参与形参的关系

        3.6 return语句

        3.7 数组传参

四、函数的其他方面

        4.1 函数的嵌套调用

        4.2 函数的链式访问

        4.3 函数的定义和声明

                4.3.1 单文件中

                4.3.2 多文件中

        4.4 关键字static和extern

                4.4.1 static修饰局部变量

                4.4.2 static修饰全局变量

                4.4.3 static修饰函数

                4.4.4 关于函数声明的小总结


前言:

本篇主要讨论以下问题:

关于函数概念部分:

1. C语言中的函数是什么,在C语言中使用函数有哪些好处,C语言中的函数分为哪两大类

2. 标准库是什么,C语言中的头文件通常用于存放什么的

关于库函数部分:

3. 什么是库函数,我们应该怎样自学库函数

关于自定义函数部分:

4. 自定义函数的语法形式是怎样的,它的返回类型和形参部分有什么需要注意的地方

5. 如何区分实参和形参,实参和形参的关系是怎样的

6. 在自定义函数中写return语句需要注意哪5点

7. 当数组作为函数的参数时,我们该如何传参,定义函数时形参部分该怎样去接收数组

关于函数的其他方面:

8. 什么是函数的嵌套调用和链式访问,能否举个例子来说明一下

9. 函数在单个文件和多个文件中如何定义和声明

10. 模块化划分有哪些好处 

11.关键字static和extern的功能分别是什么

12.关于函数的声明能否总结一下

一、C语言中函数的概念

1. C语言中的函数又被称为子程序,是完成特定任务的一小段代码。

2. 使用函数的好处:①逻辑清晰,方便拆分任务 ②可以重复使用,提高开发效率。

3. C语言中的函数分为两大类:库函数、自定义函数。

4. C语言规定了一系列标准,这些标准构成了标准库。

5. C语言的头文件(.h)通常用于存放函数的声明、符号的声明。

二、库函数

2.1 库函数的概念

1. 库函数是一系列程序员可直接调用的现成函数,调用这些函数前要在当前(.c)文件的头部用#include包含相关的头文件。(C语言标准只规定了有关库函数的一些语法规则,并没有提供现成的库函数,这些库函数的实现需要由不同的编译器厂商根据库函数相关的语法来实现,虽然各厂商实现的细节可能会有所差异,但对程序员使用来说没什么影响。)

2. C语言图书馆(查询库函数的地方):C library - C++ Reference (cplusplus.com)

2.2 怎样自学库函数——以sqrt函数为例 

在自学库函数时需要观察的方面:

1. 函数的名称

2. 函数的语法形式

3. 函数的功能

4. 函数的形参

5. 函数的返回类型

6. 函数使用的代码举例,(可观察该函数所需包含的头文件),代码运行的结果

7. 与该函数有关联的其他库函数

 

三、自定义函数

3.1 自定义函数的概念

1. 自定义函数可用于提供程序员根据需要,自定义函数的参数和实现过程,达到实现某一特定功能函数的效果。

3.2 自定义函数的语法形式 

//语法形式:ret_type fun_name(形式参数)
            {

            }

1. ret_type:函数的返回类型。(什么类型都行,也可以什么也不返回写上void,如果返回类型不写则会默认返回类型为int类型。)

2. fun_name:函数的名称。

3. (形式参数):形式参数个数可以为0~n个。(各形参的类型可以各不相同,且什么类型都行。当函数形参个数为0时,形式参数部分有两种不同的写法,写法一:写void,明确表示函数不需要任何参数,如果在函数调用时强制传参,则会报错;写法二:什么都不写,这种写法如果在函数调用时强制传参,函数会被正常调用,所以不推荐这种写法。)

4. { } 代码块里的函数体部分,用于写自定义函数实现的过程。

3.3 函数的实参

1. 在函数调用时,传递给函数的参数被称为实参,传参时不用注明变量的类型。

3.4 函数的形参

1. 在函数定义时( )中的参数被称为形参,形参在函数定义时要注明各参数是什么类型的。

3.5 实参与形参的关系

1. 形参是实参的一份临时拷贝。

2. 对形参的修改不会影响到实参。

3. 形参和实参可同名。

4. 只有在函数被调用后才会为形参向内存申请空间用于存放复制过来实参的值。

3.6 return语句

1. return语句后面可以是一个数值,也可以是一个表达式,如果是表达式则会先执行表达式再返回表达式的值。

2. return语句后面可以什么也没有写成return;适合函数返回类型为void的情况。

3. return返回的值与自定义函数的返回类型相冲突时,以自定义函数返回类型为尊,返回值将会被隐形强制转换。

4. return语句执行后,自定义函数中return语句后面的代码将不会再被执行。

5. 如果自定义函数的返回类型不为空,函数中存在分支语句,且分支语句中的某个分支中有return语句,那么自定函数所能执行的其他情况都要有return语句来保证函数逻辑的完整性,否则会出现编译错误。如果自定义函数返回类型为空,那么该函数可以有return;来提前终止代码,也可以没有,且函数即使存在分支语句,分支语句中的某个分支中有return语句,此时也不需要去考虑函数执行的其他情况下函数的返回结果的逻辑是否完整了。

3.7 数组传参

1.数组传参,函数调用时实参的部分写数组名和数组的大小即可,接收数组名的形参部分可以用数组的形式,也可以用指针的形式。

2. 如果接收数组名的形参部分用的是数组的形式,无论实参和形参部分的数组名是否相同,我们操作的数组始终都是实参的那个数组。

3. 形参如果是⼀维数组,数组⼤⼩可以省略不写。

4. 形参如果是⼆维数组,⾏的大小可以省略,但列的大小不能省略。

//采用数组传参,用Print函数分装打印数组的功能
#include <stdio.h>

void Print(int arr[], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}

int main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	Print(arr, sz);
	return 0;
}

四、函数的其他方面

4.1 函数的嵌套调用

1. 函数的嵌套调用就是函数中调用函数。

2. 函数之间可以嵌套调用,但不可以嵌套定义

//【计算某年某⽉有多少天】
#incluide <stdio.h>

//判断是否是闰年
int is_leap_year(int y)
{
	if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
		return 1;
	else
		return 0;
}

//判断某月有多少天
int get_days_of_month(int y, int m)
{
	int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	int day = days[m];
	if (is_leap_year(y) && m == 2)//函数调用
		day += 1;
	return day;
}

int main()
{
	int y = 0;
	int m = 0;
	scanf("%d %d", &y, &m);
	int d = get_days_of_month(y, m);//函数调用
	printf("%d\n", d);
	return 0;
}

4.2 函数的链式访问

1. 函数的链式访问就是将一个函数的返回值作为另一个函数的参数,实现像链条一样将函数串起来的效果。

#include <stdio.h>
#include <string.h>

int main()
{
     printf("%zd\n", strlen("abcdef"));//6,strlen不计算\0
     printf("%d", printf("%d\n", printf("%d", printf("%d", 43))));//4321\n2
     return 0;
}

4.3 函数的定义和声明

4.3.1 单文件中

1. 只用到单个文件写代码时,一般会将每定义的一个新的自定义函数向上累加,即实现默认将函数定义写在调用函数之前的效果,这样在调用自定义函数时,就可以不需要对调用的自定义函数进行额外的声明了,因为函数的定义是一种特殊的函数声明形式。

2. 如果把函数定义写在调用函数之后了,这样在调用自定义函数时,和上面的写法相比会多一步,我们需要额外对被调用的自定义函数进行声明,函数的声明写在当前(.c)文件的头部即可,声明的格式是函数定义的第一行后面加一个封号。(总之,函数必须先声明后使用)

//【判断⼀年是不是闰年】
#include <stido.h>

//示例1:定义在前
int is_leap_year(int y)//声明
{
     if(((y%4==0)&&(y%100!=0)) || (y%400==0))
         return 1;
     else
         return 0;
}

int main()
{
     int y = 0;
     scanf("%d", &y);
     int r = is_leap_year(y);//调用
     if(r == 1)
         printf("闰年\n");
     else
         printf("⾮闰年\n");
     return 0;
}
//【判断⼀年是不是闰年】
#include <stido.h>

//示例2:定义在后
int is_leap_year(int y);//声明
int main()
{
     int y = 0;
     scanf("%d", &y);
     int r = is_leap_year(y);//调用
     if(r == 1)
         printf("闰年\n");
     else
         printf("⾮闰年\n");
     return 0;
}
//判断⼀年是不是闰年
int is_leap_year(int y)//声明
{
     if(((y%4==0)&&(y%100!=0)) || (y%400==0))
         return 1;
     else
         return 0;
}

4.3.2 多文件中

1. ⼀般在企业中写代码时候,代码可能⽐较多,不会将所有的代码都放在⼀个⽂件中;我们往往会根据程序的功能,将代码进行模块化拆分,每个模块都有着自己的(.h)和(.c)⽂件

2. 头⽂件(.h)中会存放每个模块中的函数的声明、符号的声明源⽂件(.c)中是每个模块写函数的定义的地方。

3. 如下图中所示,假设企业要完成一个计算器的实现程序,分为了4个模块,每个模块又有对应的(.c)和(.h)文件,(.c)文件中实现函数的定义,(.h)文件中实现函数的声明,在有main函数的(.c)文件中如果想要调用这些不同模块的函数的话,在文件开头用#include包含对应的头文件即可,但要注意包含自己的头文件时< >得换为" ",例如,#include "Add.h"。(头文件的包含本质是将头文件中的内容拷贝到当前的(.c)文件中,实现对相关函数的声明。

4. 使用模块化划分的好处:①逻辑清晰 ②方便协作 ③把一个模块分为(.c)和(.h)文件,方便代码的隐藏(未来可以只给别人看(.h)文件)

 

4.4 关键字static和extern

概念:

① static是“静态的”意思,可以用来修饰局部变量、全局变量、函数。

② extern是用来修饰外部符号的,这里的外部指的是一个程序中不同(.c)文件(extern可以声明外部全局变量,也可以声明外部定义的自定义函数,格式例如,extern int arr;extern int Add (int a, int b); 声明外部的自定义函数时也可以直接写成例如,int Add (int a, int b); 因为函数的声明本身就自带extern,但最好还是写上)

补充:

① 作用域:⼀段程序代码中所⽤到的名字并不总是有效的,⽽限定这个名字的可⽤性的代码范围就是这个名字的作⽤域。

1. 局部变量的作⽤域是变量所在的局部范围 

2. 全局变量的作⽤域是整个⼯程(项⽬)

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

1. 局部变量的⽣命周期是:进⼊作⽤域变量创建,⽣命周期开始,出作⽤域⽣命周期结束。 2. 全局变量的⽣命周期是:整个程序的⽣命周期。

 4.4.1 static修饰局部变量

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

使⽤建议:未来⼀个变量出了作用域后,我们还想保留它的值,等下次进⼊函数继续使⽤,就可以使⽤static 修饰,通常情况static修饰的局部变量都是自定义函数中的局部变量,main函数中的局部变量用static修饰一般没什么意义,代码是不断向下编程的。

总之,static修饰局部变量,这个局部变量的生命周期与全局变量的生命周期一样了,但作用域还是原来的作用域。

 4.4.2 static修饰全局变量

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

使⽤建议:如果⼀个全局变量,只想在所在的源⽂件内部使⽤,不想被其他⽂件发现,就可以使⽤ static修饰。

总之,static修饰全局变量,这个全局变量本来可以在整个程序的所有文件(.c)中用extern声明一下就可以自由使用了,但被static修饰后只能在自己所在的(.c)文件中使用,其他的(.c)文件中即使声明了也没用。

4.4.3 static修饰函数

概念:static 修饰函数和 static 修饰全局变量是⼀模⼀样的,⼀个函数在整个⼯程想使用都可以使⽤,只需要适当声明就可以,但被static修饰后,只能在本⽂件内部使⽤,其他⽂件⽆法正常的链接使⽤了。本质是因为函数默认是具有外部链接属性,具有外部链接属性,使得函数在整个⼯程中只要适当的声 明就可以被使⽤。但是被 static 修饰后变成了内部链接属性,使得函数只能在⾃⼰所在源⽂件内部 使⽤。

使⽤建议:⼀个函数只想在所在的源⽂件内部使⽤,不想被其他源⽂件使⽤,就可以使⽤ static 修饰。

总之,static修饰函数,函数和全局变量一样本来可以只需要进行相关的声明或extern即可在整个程序的所有(.c)文件中自由使用的,但被static修饰后只能在自己所在的(.c)文件中使用,在其他的(.c)文件中即使声明了也没用。

4.4.4 关于函数声明的小总结

1. 如果只用到一个(.c)文件写代码,函数的定义采用向上累加的方式。

2. 如果用到多个文件写代码,想调用其他(.c)文件中的函数时,方法一:如果有包含该函数声明的头文件,直接用#include包含对应的头文件即可;方法二:如果没有包含该函数声明的头文件,采用extern的形式声明一下该函数即可(也可以直接声明不写extern)。注意,如果该函数已被static修饰过,即使采用上面的方法实现函数的声明,函数也是无法被正常调用的。

本篇文章已完结,谢谢支持!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

O2OA开发平台如何查看数据表结构?

在访问后端api地址&#xff0c;页面最下方有列示平台的各个服务&#xff0c;点击进入可查看具体的表内容 后端api地址&#xff1a; http://{hostIP}/x_program_center/jest/list.html 其中&#xff1a;{hostIP}为中心服务器所在域名或者IP地址 如下图&#xff1a;

RA4000CE为汽车动力传动系统提供解决方案

目前汽车电气化的水平越来越高&#xff0c;其中比较显著的一个发展方向就是将发动机管理系统和自动变速器控制系统&#xff0c;集成为动力传动系统的综合控制(PCM)。作为汽车动力的核心部件&#xff0c;通过电子系统的运用&#xff0c;将外部多个传感器和执行环节的数据进行统一…

Go 自定义14位时间类型 yyyyMMddHHmmss

目录 功能 代码 功能 数据库或者接口时间类型&#xff0c;经常会使用14位的时间格式。每次都转换有点麻烦。可以自定义一个时间类型。 自定义类型需要实现json接口中的MarshalJSON与UnmarshalJSON两个函数&#xff0c;这样在做json编码解码时就会自动转为14位的时间格式了。…

基于flutter3.x+window_manager+getx桌面端仿macOS系统

flutter3_macui桌面端仿macOS系统实战项目完结啦&#xff01; 原创研发flutter3.19dart3.3window_managergetx等技术构建桌面版macOS系统。支持自定义毛玻璃虚化背景、Dock菜单多级嵌套自由拖拽排序、可拖拽弹窗等功能。 支持macOS和windows11两种风格。 使用技术 编辑器&…

【c++】优先级队列|反向迭代器(vector|list)

优先级队列的常用函数的使用 #include<iostream> #include<queue> using namespace std;int main() {priority_queue<int>st;st.push(1);st.push(7);st.push(5);st.push(2);st.push(3);st.push(9);while (!st.empty()){cout << st.top() << &qu…

【vue】watch 侦听器

watch&#xff1a;可监听值的变化&#xff0c;旧值和新值 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…

openstack之neutron介绍

核心组件 neutron-server&#xff1a;提供API接口&#xff0c;把对应的api请求传给plugin进&#xff1b; neutron-plugin&#xff1a;管理逻辑网络状态&#xff0c;调用agent&#xff1b; neutron-agent&#xff1a;在provider network上创建网络对象&#xff1b; neutron-…

【Vue】实现仿微信输入@出现选择框

<div style"padding: 10px 10px" class"editor"><el-inputresizetype"textarea":rows"4"clearableplaceholder"请输入您的问题.."v-model"requestParams.prompt"input"handleInput"keydown.na…

C# WinForm —— 项目目录结构

1. WinForm 应用程序项目 Properties&#xff1a;属性文件夹存放了一个自动生成的类文件AssemblyInfo.cs&#xff0c;保存了一些应用程序集的一些信息引用存放了一些为应用程序提供所需的&#xff0c;某些功能的一些程序集&#xff08;dll文件&#xff09;等添加引用&#xff…

Html网页小游戏源代码

Html网页小游戏源代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Jello Jumping Game</title><meta name"viewport" content"widthdevice-width, initial-scale1"&…

【安全】挖矿木马自助清理手册

一、什么是挖矿木马 挖矿木马会占用CPU进行超频运算&#xff0c;从而占用主机大量的CPU资源&#xff0c;严重影响服务器上的其他应用的正常运行。黑客为了得到更多的算力资源&#xff0c;一般都会对全网进行无差别扫描&#xff0c;同时利用SSH爆破和漏洞利用等手段攻击主机。 …

【AR】使用深度API实现虚实遮挡

遮挡效果 本段描述摘自 https://developers.google.cn/ar/develop/depth 遮挡是深度API的应用之一。 遮挡&#xff08;即准确渲染虚拟物体在现实物体后面&#xff09;对于沉浸式 AR 体验至关重要。 参考下图&#xff0c;假设场景中有一个Andy&#xff0c;用户可能需要放置在包含…

2024年蓝桥杯40天打卡总结

2024蓝桥杯40天打卡总结 真题题解其它预估考点重点复习考点时间复杂度前缀和二分的两个模板字符串相关 String和StringBuilderArrayList HashSet HashMap相关蓝桥杯Java常用算法大数类BigInteger的存储与运算日期相关考点及函数质数最小公倍数和最大公约数排序库的使用栈Math类…

牛客周赛 Round 39(A,B,C,D,E,F,G)

比赛链接 官方题解&#xff08;视频&#xff09; B题是个贪心。CD用同余最短路&#xff0c;预处理的完全背包&#xff0c;多重背包都能做&#xff0c;比较典型。E是个诈骗&#xff0c;暴力就完事了。F是个线段树。G是个分类大讨论&#xff0c;出题人钦定的本年度最佳最粪 题目…

14届蓝桥杯 C/C++ B组 T6 岛屿个数 (BFS,FloodFill,填色)

首先拿到这道题不要想着去直接判断环里面的岛屿&#xff0c;这样太困难了&#xff0c;我们可以使用之前做过的题的经验&#xff0c;在输入加入一圈海水&#xff0c;然后从(0,0)点开始BFS&#xff0c;这里进行八向搜索&#xff0c;搜到的0全部都染色成2&#xff0c;假如2能够蔓延…

GD32 HID键盘矩阵键盘发送数据时,一直发送数据问题处理

这个问题找了两三天,开始并不认为是示例程序的问题,只是感觉是自己代码问题。 这个解决流程大概是: 先调好矩阵键盘=> 调用发送函数。 就是因为调用时,一直发送数据,我也在按键抬起做了操作,始终不行。 最后,发现时示例代码中有个 空闲中断 引起的。 udev->reg…

数学建模-最优包衣厚度终点判别法-三(Bayes判别分析法和梯度下降算法)

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是viperrrrrrr~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff…

【算法】bfs解决FloodFill问题

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 FloodFill算法1. 733. 图像渲染1.1 分析1.2 代码 2. 200. 岛屿数量2.1 分析2.2 代码 3. 695. 岛屿的最大面积3.1 分析3.2 代码 4. 130. 被围绕的区域4.1 分析4.2 代码 FloodFill算法 FloodFill就是洪水灌溉&#xff0c;解…

minio-docker单节点部署SDK测试文件上传下载

目录 一&#xff0c;docker部署minio单节点单磁盘 二&#xff0c;SDK测试上传下载 一&#xff0c;docker部署minio单节点单磁盘 1.拉取镜像 # 下载镜像 docker pull minio/minio 2.查看镜像 docker images 3.启动minio(新版本) 创建本机上的挂载目录&#xff0c;这个可以…

蓝桥杯备赛(C/C++组)

README&#xff1a; 本笔记是自己的备考笔记&#xff0c;按照官网提纲进行复习&#xff01;适合有基础&#xff0c;复习用。 一、总考点 试题考查选手解决实际问题的能力&#xff0c;对于结果填空题&#xff0c;选手可以使用手算、软件、编程等方法解决&#xff0c;对于编程大…