【C语言_函数_复习篇】

目录

一、C语言中函数的概念

二、库函数

        2.1 库函数的概念

        2.2 怎样自己学习库函数_以sqrt函数为例

三、自定义函数

        3.1 自定义函数的语法形式

        3.2 自定义函数的举例

        3.3 自定义函数的实参

        3.4 自定义函数的形参

        3.5 自定义函数的实参和形参的关系

        3.6 自定义函数中的return语句

        3.7 数组做自定义函数的参数

        3.8 函数的嵌套调用

        3.9 函数的链式访问

四、函数的定义、声明和使用

        4.1 单文件中

        4.2 多文件中

五、关键字static和extern

        5.1 static修饰局部变量

        5.2 static修饰全局变量

        5.3 static修饰函数


一、C语言中函数的概念

1. C语言是由一个个函数构成的,每一个函数用于完成程序中某个特定的任务。

2. 采用函数的好处:①可以拆分任务 ②可以重复使用。

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

二、库函数

2.1 库函数的概念

1. 库函数是一些可以现成使用的函数,在使用库函数时要提前对该库函数所包含的头文件进行声明。

2. 补充:C语言规定了库函数的语法标准,这些标准组成了标准库,但C语言并不提供现成的库函数,这些库函数的实现由不同的编译器厂商实现,函数的实现细节可能有差异,但程序员在使用时基本不影响。

3. 库函数的官网:C library - C++ Reference (cplusplus.com)

2.2 怎样自己学习库函数_以sqrt函数为例

从上至下:

① 函数的语法形式

② 函数的功能、

③ 函数的参数说明

④ 函数返回值说明

⑤ 函数使用时的代码举例(含所需包含的头文件)

⑥ 与之类型的其他库函数

三、自定义函数

3.1 自定义函数的语法形式

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


            }

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

2. fun_name:函数的名称。

3. (形式参数):形式参数可以没有(空或void),也可以有1个或多个,这些形参采用什么类型都可以(如果形参为空,在函数调用时强制传参,该函数也会被正常调用)。

4. { } 代码块里写自定义函数实现的过程。

3.2 自定义函数的举例

//用Add函数分装加法功能
#include <stdio.h>

int Add(int x, int y)//x y为形参
{
	return x + y;
}

int main()
{
	int a = 0, b = 0;
	scanf("%d %d", &a, &b);
	int ret = Add(a, b);//a b为形参
	printf("%d\n", ret);
	return 0;
}

3.3 自定义函数的实参

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

3.4 自定义函数的形参

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

2. 补充:函数在没有被调用时,自定义函数的形参变量并没有在内存中申请空间,只有在自定义函数被调用后为了复制实参的值才会向内存申请空间。

3.5 自定义函数的实参和形参的关系

1. 形参是实参的一份临时拷贝,对形参的修改并不会改变实参的数值,形参和实参可同名。

3.6 自定义函数中的return语句

1. 自定义函数中如果返回类型为void可以省略return语句,也可以写成void;

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

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

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

5. 如果自定义函数中存在分支语句,则要保证每个分支下都有return语句,否则会出现编译错误。

3.7 数组做自定义函数的参数

1. 数组传参,形参是不会创建新数组的,形参操作的数组和实参的数组是同⼀个数组

2. 函数的形参个数要和函数的实参个数匹配,在传参时把数组的大小一并传过去

3. 数组传参时,实参部分写成数组名,形参写成数组的形式即可(数组名其实是数组首元素的地址,数组传参的本质是传址调用而不是传值调用)。

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

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

//用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;
}

3.8 函数的嵌套调用

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;
}

3.9 函数的链式访问

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

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

//示例1
int main()
{
     printf("%zd\n", strlen("abcdef"));
     return 0;
}
#include <stdio.h>
#include <string.h>

//示例2
int main()
{
     printf("%d", printf("%d", printf("%d", 43)));
     return 0;
}

四、函数的定义、声明和使用

4.1 单文件中

1. 只需用到.c单个文件写代码时,一般将自定义函数的函数定义写在被调用时所在的函数之前,这样在调用自定义函数时,就可以不需要对调用的自定义函数进行声明,因为函数的定义是一种特殊的函数声明形式。

2. 如果把自定义函数的函数定义写在被调用时所在的函数之后了,这样在调用自定义函数时,就必须要对调用的自定义函数进行声明,在整个文件开头声明就行,声明的格式是函数定义的第一行后面加一个封号

//【判断⼀年是不是闰年】
#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.2 多文件中

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

2. ⼀般情况下,函数的声明、类型的声明放在头⽂件(.h)中函数的定义是放在源⽂件(.c)

⽂件中。

3. 如下图中所示,假设企业要完成一个计算器的实现程序,分为了4个模块,每个模块又有对应的(.c)和(.h)文件,(.c)文件中实现函数的定义,(.h)文件中实现函数的声明,在有main函数的(.c)文件中如果想要调用这些不同模块的函数的话,在文件开头写上包含对应的头文件即可,但< >要换为" ",例如,#include "Add.h",头文件的包含本质上也是一种函数的声明

4. 优点:①逻辑清晰 ②方便协作 ③把一个模块又分为(.c)和(.h)文件后也方便代码的隐藏(未来可以只给别人看(.h)文件)

 

五、关键字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. 全局变量的⽣命周期是:整个程序的⽣命周期。

5.1 static修饰局部变量

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

使⽤建议:未来⼀个变量出了函数后,我们还想保留值,等下次进⼊函数继续使⽤,就可以使⽤static 修饰。

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

5.2 static修饰全局变量

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

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

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

5.3 static修饰函数

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

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

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

本篇已完结。。。。。。 

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

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

相关文章

javaweb-配置优先级、bean管理和SpringBoot原理

javaweb原理&#xff01; 配置优先级 命令行参数的优先级要高于java系统属性 Bean管理 第三方bean SpringBoot原理 起步依赖的原理就是依赖传递 后端开发总结 原来SSM是这三个&#xff01;&#xff01;&#xff01; Maven高级 maven构建和管理ja…

浅谈电商网络爬虫技术

摘 要 目前网络上存在着海量的数据资料&#xff0c;将这些数据爬取保存下来&#xff0c;并进行进一步操作&#xff0c;即可挖掘出数据的潜在价值。如今的互联网存在的缺陷是用户很难获得有用的数据资料&#xff0c;虽然传统的搜索引擎可以为用户返回大量信息&#xff0c;但是…

会话式AI定制化营销的力量

智能革命&#xff1a;如何用会话式AI提高品牌影响力&#xff1f; 在人工智能时代&#xff0c;营销活动计划应充分利用AI技术&#xff0c;比如数据分析、个性化推荐、智能客服等&#xff0c;以提高营销活动的针对性和效率。同时&#xff0c;创意和用户体验依然是吸引用户的关键&…

【Linux实践室】Linux用户管理实战指南:用户密码管理操作详解

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;用户密码存放地及方式2.2 &#x1f514;使用…

【数据分享】1929-2023年全球站点的逐日平均海平面压力(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全球气象站…

solr-lucene的解释

什么是solr-lucene Solr是一个基于Apache Lucene的开源搜索平台。Lucene是一个开源的全文搜索引擎库&#xff0c;它提供了一个简单而强大的API&#xff0c;用于索引和搜索文档。Solr通过在Lucene的基础上构建一个更高级的搜索平台&#xff0c;为用户提供了更丰富的功能和易于使…

代码随想录——在排序数组中查找元素的第一个和最后一个位置(Leetcode34)需要回顾

题目链接 class Solution {public int[] searchRange(int[] nums, int target) {// count记录数组中与target相等的个数int count 0;// index记录最后一个与target相等的数组下标&#xff0c;先赋值-1证明没有与之相等的数组元素int index -1;// 返回数组arrint[] arr new…

行业分析:2024年全球CRM九大发展趋势预测,洞悉未来!

2024年全球CRM行业发展九大预测&#xff1a;以客户为中心、重视CRM采用率、与业务深度融合的AI、一体化平台、行业垂类解决方案CRM、集中数据&#xff0c;驱动业务、低代码PaaS、在客户服务中寻求人机平衡、不同规模企业应用特点区别明显。 每到年初&#xff0c;作为Gartner魔力…

Netty学习——源码篇7 Pipeline的事件传播机制1 备份

上篇&#xff1a;Netty学习——源码篇6 Pipeline设计原理 已经知道AbstractChannelHandlerContext中有Inbound和Outbound两个boolean变量&#xff0c;分别用于识别Context所对应的Handler的类型。 1、Inbound为true时&#xff0c;表示其对应的ChannelHandler是ChannelInboundHa…

考了PMP证后工资大概是多少 ?

PMP自1999年引入国内以来&#xff0c;大家对这个证书的了解并不深&#xff0c;每年考试的人数也不多。但随着越来越多的企业认可PMP认证&#xff0c;目前考证的人数不断增加&#xff0c;几乎所有与项目管理相关的人都知道这个证书的重要性。这个证书在招聘要求中出现频率较高&a…

小红的炸砖块

题目描述 小红正在玩一个“炸砖块”游戏&#xff0c;游戏的规则如下&#xff1a; 初始有一个n∗m的砖块矩阵。小红会炸k次&#xff0c;每次会向一个位置投炸弹&#xff0c;如果这个位置有一个砖块&#xff0c;则砖块消失&#xff0c;上方的砖块向下落。 小红希望你画出最终砖块…

StringBuffer和大数值

读取 import java.util.Scanner;public class index{public static void main(String[] args){Scanner in new Scanner(System.in);System.out.println("Whats your name?");String name in.nextLine();Scanner inage new Scanner(System.in);System.out.printl…

Linux虚拟机环境搭建spark

Linux环境搭建Spark分为两个版本&#xff0c;分别是Scala版本和Python版本。 一、 安装Pyspark 本环境以 Python 环境为例。 1、下载spark 下载网址&#xff1a;https://archive.apache.org/dist/spark 下载安装包&#xff1a;根据自己环境选择合适版本&#xff0c;本环境…

详细分析Linux中的core dump异常(附 Demo排查)

目录 1. 基本知识2. 进阶知识3. Demo4. 彩蛋 1. 基本知识 Core dump 是指在程序异常终止时&#xff0c;操作系统将程序的内存映像保存到磁盘上的一种机制。 在 Linux 系统中&#xff0c;core dump 提供了一种调试程序错误的重要方式&#xff0c;它记录了程序在崩溃时的内存状态…

同城双活:交易链路的稳定性与可靠性探索

知易行难&#xff0c;双活过程中遇到了非常多的问题&#xff0c;但是回过头看很难完美的表述出来&#xff0c;之所以这么久才行文也是这个原因&#xff0c;总是希望可以尽可能的复现当时的思考、问题细节及解决方案&#xff0c;但是写出来才发现能给出的都是多次打磨、摸索之后…

大数据开发(日志离线分析项目)

大数据开发&#xff08;日志离线分析项目&#xff09; 一、项目需求1、使用jqueryecharts的方式调用程序后台提供的rest api接口&#xff0c;获取json数据&#xff0c;然后通过jquerycss的方式进行数据展示。工作流程如下&#xff1a;2、七大角度1、用户基本信息分析模块2、浏览…

秋招刷题2

1.字符串分割 public static void main(String[] args) {Scanner scnew Scanner(System.in);while(sc.hasNext()){String strsc.nextLine();StringBuilder sbnew StringBuilder();sb.append(str);int sizestr.length();int addZero8-size%8;while((addZero>0&&(addZ…

【数据结构】受限制的线性表——队列

&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;个人主页&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388; &#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;数据结构专栏&#x1f388;&#x1f388;&#x1f388;&…

机器学习——神经网络简单了解

一、神经网络基本概念 神经网络可以分为生物神经网络和人工神经网络 (1)生物神经网络,指的是生物脑内的神经元、突触等构成的神经网络&#xff0c;可以使生物体产生意识&#xff0c;并协助生物体思考、行动和管理各机体活动。 (2)人工神经网络,是目前热门的深度学习的研究…

C++初阶:反向迭代器模板,dequeue与模板进阶

目录 1. 反向迭代器的实现2. 容器deque的数据结构&#xff08;双端队列&#xff09;3. 模板的进阶知识与使用3.1 非类型模板参数3.2 模板特化3.2.1 全特化3.2.2 偏特化&#xff08;半特化&#xff09; 3.3 模板的分离编译 1. 反向迭代器的实现 反向迭代器与正向迭代器的行为与定…