【C语言】C语言期末突击/考研--函数

目录

一、函数的声明与定义-嵌套调用

1.1.函数的声明与定义

1.2.函数的分类与调用

二、函数的递归调用

三、局部变量与全局变量

3.1.全局变量解析形参实参解析

3.2.局部变量与全局变量

四、练习题及解析


一、函数的声明与定义-嵌套调用

1.1.函数的声明与定义

    函数间的调用关系是,由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意次。如图1.1 所示.    下面来看例1.1例中有两个c文件,func.c 是子函数printstar和print message的实现,也称定义;main.c 是main函数,func.h 中存放的是标准头文件的声明和main函数中调用的两个子函数的声明,如果不在头文件中对使用的函数进行声明,那么在编译时会出现警告。
【例1.1】函数嵌套调用:

/*func.h*/
#include <stdio.h>
#include <stdlib.h>
int printstar(int i); //函数声明
void print_message();
/*func.c*/
#include "func.h"
int printstar(inti) //i即为形式参数
{printf("********************\n");printf("printstar %d\n", i);return i + 3;
}
void print_message() //可以调用printstar
{printf("how do you do\n");printstar(3);
}
/*
main.c
*/
#include "func.h"
int main()
{int a=10;a=printstar(a);print_message();printstar(a);return 0;
}

 C语言的编译和执行具有以下特点:
   (1) 一个C程序由一个或多个程序模块组成,每个程序模块作为一个源程序文件。对于较大的程序,通常将程序内容分别放在若干源文件中,再由若干源程序文件组成一个C程序。这样处理便于分别编写、分别编译,进而提高调试效率。一个源程序文件可以为多个C程序共用。
   (2)一个源程序文件由一个或多个函数及其他有关内容(如命令行、数据定义等)组成。一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位而不是以函数为单位进行编译的。main.c 和func.c分别单独编译,在链接成为可执行文件时,main中调用的函数printstar和print_message才会通过链接去找到函数定义的位置。
   (3) C程序的执行是从main函数开始的,如果在main函数中调用其他函数,那么在调用后会返回到main函数中,在main函数中结束整个程序的运行
   (4)所有函数都是平行的,即在定义函数时是分别进行的,并且是互相独立的。一个函数并不从属于另一函数,即函数不能嵌套定义函数间可以互相调用但不能调用main函数。main函数是由系统调用的,例1.1的main函数中调用print message函数,而print message函数中又调用printstar 函数,我们把这种调用称为嵌套调用。

函数的声明与定义的差异如下:
   (1)函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型、函数体等,它是一一个完整的、独立的函数单位。
   (2) 函数的声明的作用是把函数的名字、函数类型及形参的类型、个数和顺序通知编译系统,以便在调用该函数时编译系统能正确识别函数并检查调用是否合法。


隐式声明: C语言中有几种声明的类型名可以省略。例如,函数如果不显式地声明返回值的类型,那么它默认返回整型;使用旧风格声明函数的形式参数时,如果省略参数的类型,那么编译器默认它们为整型。然而,依赖隐式声明并不是好的习惯,因为隐式声明容易让代码的读者产生疑问:编写者是否是有意遗漏了类型名?还是不小心忘记了?显式声明能够清楚地表达意图!


1.2.函数的分类与调用

从用户角度来看,函数分为如下两种:
   (1) 标准函数:即库函数,这是由系统提供的,用户不必自己定义的函数,可以直接使用它们,如printf函数、scanf函数。不同的C系统提供的库函数的数量和功能会有一些不同,但许多基本的函数是相同的。
   (2)用户自己定义的函数:用以解决用户的专门需要。


从函数的形式看,函数分为如下两类:
   (1) 无参函数:一般用来执行指定的一组操作。在调用无参函数时,主调函数不向被调用函数传递数据。在例1.1 中,print_message就是无参函数。无参函数的定义形式如下:

类型标识符  函数名()

{
        声明部分
        语句部分

}

   (2)有参函数:主调函数在调用被调用函数时,通过参数向被调用函数传递数据。有参函数的定义形式如下:

类型标识符  函数名(形式参数表列)

{
        声明部分
        语句部分

}

在例1.1中, printstar 就是有参函数,int i对应的i为形式参数,主调函数和被调用函数之间存在数据传递关系。

二、函数的递归调用

    我们把函数自身调用自身的操作,称为递归函数, 递归函数一定要 有结束条件,否则会产
生死循环!

    假设现在要求读者写一个程序来求数字n的阶乘。读者可能会觉得这很简单吗,写个for循环就可以实现,然而,使用递归来实现更好一些,因为使用递归在解决一些问题时,可以让问题变得简单,降低编程的难度.比如接下来的题目:假如有n个台阶,一次只能上比1个台阶或2个台阶,请问走到第n个台阶有几种走法?为便于读者理解题意,这里举例说明如下:假如有3个台阶,那么总计就有3种走法:第一种为每次上1个台阶,上3次;第二种为先上2个台阶,再上1个台阶;第三种为先上1个台阶,再上2个台阶。具体实现请看例2.1
【例2.1】n的阶乘的递归调用实现:

#include <stdio.h>
//求n的阶乘
int f(int n)
{if(1==n){return 1;}return n*f(n-1);
}//走楼梯
int step(int n){if(1==n){return 1;}if(2==n){return 2;}return step(n- 1)+step(n- -2);
}
int main(){int n;int ret;scanf(" %d" ,&n); //请输入数字的大小ret=f(n);printf(" %d\n",ret);scanf("%d" ,&n); //请输入台阶数ret=step(n);printf("%d\n",ret);return 0;
}

 

三、局部变量与全局变量

3.1.全局变量解析形参实参解析

不同的函数之间传递数据时,可以使用的方法如下:

(1) 参数:通过形式参数和实际参数。
(2)返回值:用return语句返回计算结果。
(3)全局变量:外部变量。

下面来看一个全局变量的实例,如例3.1所示。
【例3.1】全局变量的使用:

#include <stdio.h>
int i=10; //全局变量
void print(int a)
{printf("print i=%d\n",i);
}
int main()
{{int j=5;} //局部变量的有效范围是离自已最近的花括号printf( "main i=%d\n",i);i=5;print(i);return 0;
}

    全局变量存储在哪里?如图3.1所示,全局变量i存储在数据段,所以main函数和print函数都是可见的。全局变量不会因为某个函数执行结束而消失,在整个进程的执行过程中始终有效,因此工作中应尽量避免使用全局变量!在前面中,我们在函数内定义的变量都称为局部变量,局部变量存储在自己的函数对应的栈空间内,函数执行结束后,函数内的局部变量所分配的空间将会得到释放。如果局部变量与全局变量重名,那么将采取就近原则,即实际获取和修改的值是局部变量的值

练习:如果把print(int a)改为print(int i),那么print函数的打印结果会是多少?

关于形参与实参的一些说明如下。
   (1)定义函数中指定的形参,如果没有函数调用,那么它们并不占用内存中的存储单元。
有在发生函数调用时,函数print中的形参才被分配内存单元。在调用结束后,形参所占的内存
单元也会被释放。
   (2)实参可以是常量、变量或表达式,但要求它们有确定的值,例如,print(i+3)在 调用时
将实参的值i+3赋给形参。print 函数可以有两个形参,如print(int a,int b)
   (3)在被定义的函数中,必须指定形参的类型。如果实参列表中包含多个实参,那么各参数
间用逗号隔开.实参与形参的个数应相等,类型应匹配,且实参与形参应按顺序对应,- - - 传递
数据.
   (4)实参与形参的类型应相同或赋值应兼容。
   (5)实参向形参的数据传递是单向“ 值传递”,只能由实参传给形参,而不能由形参传回给
实参。
在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参
单元被释放,实参单元仍保留并维持原值.
   (6)形参相当于局部变量,因此不能再定义局部变量与形参同名,否则会造成编译不通。

3.2.局部变量与全局变量

3.2.1. 内部变量

    在一个函数内部定义的变量称为内部变量。它只在本函数范围内有效,即只有在本函数内才
能使用这些变量,故也称局部变量。

关于局部变量需要注意如下几点:
   (1)主函数中定义的变量只在主函数中有效,而不因为在主函数中定义而在整个文件或程序
中有效.主函数也不能使用其他函数中定义的变量。
   (2)不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。
   (3)形式参数也是局部变量。
   (4)在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这种
复合语句也称“分程序"或“程序块”。例3.1中的int j=5就是如此,只在离自己最近的花括号内有效,若离开花括号,则在其下面使用该变量会造成编译不通。
   (5)注意一个细节,for 循环的小括号内定义的inti,在离开for循环后,是不可以再次使用

3.2.2.外部变量

    函数之外定义的变量称为外部变量。外部变量可以为本文件中的其他函数共用,它的有效范
围是从定义变量的位置开始到本源文件结束,所以也称全程变量。

关于全局变量需要注意如下几点:
   (1)全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。
   (2) 使用全局变量过多会降低程序的清晰性。在各个函数执行时都可能改变外部变量的值,程序容易出错,因此要有限制地使用全局变量(初试时尽量不用)。
   (3)因为函数在执行时依赖于其所在的外部变量,如果将一个函数移到另一个文件中,那么还要将有关的外部变量及其值一起移过去。然而,如果该外部变量与其他文件的变量同名,那么就会出现问题,即会降低程序的可靠性和通用性. C语言一般要求把程序中的函数做成一个封闭体,除可以通过“实参-→形参”的渠道与外界发生联系外,没有其他渠道。

四、练习题及解析

1、程序的人口函数是main函数,因此每个项目中都必须含有一个main函数
        A正确        B错误

2、一个项目中可以有多个.c文件,多个.h 文件
        A正确        B错误

3、在程序中,main 函数调用a函数,a函数调用b函数,这样的调用就是嵌套调用,b函
数执行完毕会返回a函数, a函数执行完毕再返回main函数
        A正确        B错误

4、从函数的形式看,函数分为有参函数和无参函数,有参函数我们可以传递参数给函数,调用时
我们传递的参数叫实参,函数定义位置,小括号内的参数是形参
        A正确        B错误
 

5、函数自身调用自身的操作,称为递归函数,递归函数一定要有结束条件,否则会产生死
循环
        A正确        B错误

6、能用递归实现的,循环也可以实现,但是递归编写降低了难度
        A正确        B错误

7、我们只能给递归函数传一一个函数,不能写两个形参
        A正确        B错误
 

8、定义在函数外部的变量称为外部变量,也叫全局变量,是从定义位置开始,到文件结尾
一致有效
        A正确        B错误

9、定义函数中指淀的形参,如果没有函数调用,那么它们会占用内存中的存储单元
        A正确        B错误

10、实参与形参的个数应相等,类型应匹配,且实参与形参应按顺序对应
        A正确        B错误

11、局部变量在函数内有效
        A正确        B错误
 

解析:

1、A        解释:这个需要记住,程序从main函数开始执行,因此每个项目必须有main函数,当然只
能有一个main函数

2、A        解释:项目中采用多个c文件,可以起到分别编写、分别编译,进而提高调试效率,我们往往用一个c文件,是为了咱们自己学习方便,编写方便

3、A        解释:嵌套调用以及它的执行过程,我们要掌握

4、A        解释:我们往往使的都是有参函数,无参函数使用的比较少,但是对于它们的区别我们要清晰掌握

5、A        解释:递归函数的定义要非常清楚,考研初试大题多次考过递归,一定要熟练掌握,同时自
已编写递归是要注意有结束条件

6、A        解释:我们通过递归来解决某个问题,是因为使用循环的难度不好解决

7、B        解释:递归函数可以有多个形参

8、A        解释:这个需要记住,很多人会认为全局变量是在整个代码文件有效,实际是不正确的

9、B        解释:定义函数中指定的形参,如果没有 函数调用,那么它们并不占用内存中的存储单,当发生调用时,才分配内存

10、A        解释:这个需要记住,很重要,考研大题一定涉 及到写子函数,同时是有参数的

11、B        解释:局部变量是离自己最近的大括号内有效,并不是在整个函数内有效

下一期:

【C语言】C语言期末突击/考研--结构体与C++引用

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统原理:程序、进程、线程的概念

文章目录 程序、进程、线程的概念程序&#xff08;Program&#xff09;进程&#xff08;Process&#xff09;线程&#xff08;Thread&#xff09;关系总结 在日常对操作系统的使用中&#xff0c;大家肯定对程序、进程和线程多少有所耳闻。作为操作系统的重要一部分&#xff0c;…

R 语言学习教程,从入门到精通,R的安装与环境的配置(3)

1、R 基础语法 一门新的语言学习一般是从输出 “Hello, World!” 程序开始&#xff0c;R 语言的 “Hello, World!” 程序代码如下&#xff1a; myString <- "Hello, World!" print ( myString )以上示例将字符串 “Hello, World!” 赋值给 myString 变量&#x…

# mongodb_基础到进阶 -- MongoDB 高级--MongoDB 集群部署与安全性(四)

mongodb_基础到进阶 – MongoDB 高级–MongoDB 集群部署与安全性&#xff08;四&#xff09; 一、mongodb 第一个路由节点创建 1、分片集群架构目标 两个分片节点副本集&#xff08;33&#xff09;一个配置节点副本集&#xff08;3&#xff09;两个路由节点&#xff08;2&am…

day17 Java流程控制——用户交互Scanner

day17 Java流程控制——用户交互Scanner 目录 day17 Java流程控制——用户交互Scanner1. 什么是Scanner对象&#xff1f;2. 实操 1. 什么是Scanner对象&#xff1f; Scanner对象是Java编程语言中的一个类&#xff0c;存在于java.util包中。它用于获取输入&#xff0c;可以是各…

【letcode-c++】242有效的字母异位词与49字母异位词分组

一、242 有效的字母异位词 &#xff08;1&#xff09;题目 &#xff08;2&#xff09;知识点–哈希 【这一段总结来自于代码随想录的讲解学透哈希表 哈希的优势是可以实现快速查找&#xff0c;它非常适合应用与查找某一个元素是否在一个集合中出现。 哈希有三种实现形式&…

C++篇:入门(2)

引用 引用的概念以及定义&#xff1a; 在C中&#xff0c;引用&#xff08;Reference&#xff09;是一个非常重要的概念又可以称之为取别名&#xff0c;它允许我们创建一个已存在对象的别名。引用提供了一种机制&#xff0c;通过它可以直接访问另一个变量、对象或函数的值&#…

【Python 逆向滑块】(实战五)逆向滑块,并实现用Python+Node.js 生成滑块、识别滑块、验证滑块、发送短信

逆向日期&#xff1a;2024.08.03 使用工具&#xff1a;Python&#xff0c;Node.js 本章知识&#xff1a;滑块距离识别&#xff0c;滑块轨迹生成&#xff0c;验证滑块并获取【validate】参数 文章难度&#xff1a;中等&#xff08;没耐心的请离开&#xff09; 文章全程已做去敏处…

【时时三省】(C语言基础)函数递归练习

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 求字符串长度 求的是arr里面字符串的长度 abc后面还有一个\0为结束标志 在结算字符串长度的时候不算\0 所以它的长度是3 模拟实现一个strlen函数 str等于\0的时候就会结束返回count 如果…

一款简单且强大的免费开源图片压缩软件

图压是一款简单易用且功能强大的图片压缩工具&#xff0c;适用于Windows和macOS两大操作系统。它能够在几乎不损害图片清晰度的情况下&#xff0c;显著减小图片的体积&#xff0c;特别适合需要在网页、PPT、Word、PDF中使用的图片压缩。图压的操作界面简洁&#xff0c;用户可以…

2024智慧农场土地租赁家禽认养众筹实时监控商品溯源农业积分商城秒杀助农小程序源码

后端&#xff1a;系统后端使用PHP语言开发 前端&#xff1a;前端使用uniapp进行前后端分离开发 功能简介&#xff1a;土地种植、农业认养、积分商城、农场活动、视频监控、农场商城、实时数据监控、限时秒杀、农业众筹、送货上门、一键分销、农场入驻、全部店铺 运行环境&am…

PyMongo

什么是PyMongo PyMongo 是一个 Python 库&#xff0c;用于与 MongoDB 数据库进行交互。MongoDB 是一个基于文档的 NoSQL 数据库&#xff0c;提供高性能、可扩展性和灵活的架构。PyMongo 提供了一套工具&#xff0c;使得在 Python 程序中操作 MongoDB 变得简单和高效。 安装PyMo…

SpringBoot配置文件高级用法实战

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

u盘数据丢失怎么办?以下这四招教你轻松找回!

重要的文件资料要是不小心手滑删除了&#xff0c;轻则遭受领导的责骂&#xff0c;重则就是直接受到老板的警告了&#xff0c;所以打工人应该要人手必备数据找回的技巧&#xff0c;尤其是在针对已经拷贝好了数据在u盘当中时&#xff0c;更是需要快速去找到数据恢复的技巧&#x…

ARM 架构与技术综述

目录 认识 ARM ARM 发展历史 指令集 ARM 公司产品分类 ARM 体系结构 数据类型约定 处理器的 32 位和 64 位含义 指令集 ARM 处理器的工作模式 CPU (内核) 组成 寄存器 时钟 认识 ARM ARM 可以指&#xff1a; 一家公司。一种技术。一系列处理器。 架构&#xff1a;A…

Python数据结构实战:列表、字典与集合的高效使用

前言 在编程中&#xff0c;选择合适的数据结构对于提高程序效率至关重要。本文将介绍Python中最常用的数据结构——列表&#xff08;list&#xff09;、字典&#xff08;dict&#xff09;和集合&#xff08;set&#xff09;&#xff0c;并探讨它们的内部实现以及如何高效地使用…

量化金融人都在看哪些顶刊

精选了 7 种量化金融人都在看的顶刊&#xff0c;从最经典的有效市场假说理论&#xff0c;到最新的关于加密货币的研究&#xff0c;都发表在这些期刊上。 Journal of Finance 应该是毫无争议的 No.1。 创刊于1946年&#xff0c;是由美国金融协会&#xff08;American Finance A…

fastjson-1.2.24利用

参考视频&#xff1a;fastjson反序列化漏洞2-1.2.24利用 参考博客&#xff1a;Fastjson系列二——1.2.22-1.2.24反序列化漏洞 分析版本 fastjson1.2.24 JDK 8u141 fastjson反序列化特点 不需要实现Serializable 因为对于找不到符合条件的反序列化器&#xff0c;就把类当作…

华为的流程体系

缘由 2010年&#xff0c;华为销售额为1850亿元&#xff0c;其中国际市场占65%&#xff0c;净利润238亿元。当时&#xff0c;公司员工达11万人&#xff0c;公司处理合同达5万多个&#xff0c;290万个订单&#xff0c;大量的工作是手工处理&#xff0c;没有统一的流程支持&#…

机器学习流程图

第一部分&#xff1a;课程使用的技术栈 &#xff08;1&#xff09;Numpy 科学计算基础库&#xff0c;矩阵运算&#xff0c;线性代数 &#xff08;2&#xff09;matplotlib 绘图库&#xff0c;数据可视化 &#xff08;3&#xff09;Scikit 封装了各种分类&#xff0c;回归…

释放群众的创造力:打赢网络犯罪战争

关注公众号网络研究观获取更多内容。 企业业非但没有享受到技术带来的好处&#xff0c;反而承受着高昂的成本。 事情不应该是这样的。 企业投资 IT 是因为相信它可以改变他们与客户的关系、供应链和业务敏捷性。在过去 12 个月中&#xff0c;我们还看到人们对 AI 如何增强…