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

news2024/9/25 13:19:56

目录

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

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.coloradmin.cn/o/1975830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Code Review 这件事,AI 比人类强 10 倍

1.引言 代码审查&#xff0c;也就是 Code Review&#xff08;以下简称 CR&#xff09;&#xff0c;一直是 IT 行业讨论的热门话题&#xff0c;因为它在很大程度上决定了公司的工程质量。 但是&#xff0c;人工 CR 的成本的是很高的&#xff0c;所以在实际落地场景&#xff0c…

latex换行\left[和\right]编译报错-解决方案

简而言之&#xff1a;\\ 换成 \right.\\ , & 换成 &\left. 来个例子就知道了&#xff1a; 原本的公式是&#xff1a; \begin{align}\label{up_critic} L_Q(\theta) & \mathbb{E}\left[\frac{1}{2}(Q_\theta(\mathcal{S}_{k,t}^m, {A}_{k,t}^m) - ({R}_{k,t}^m …

07030405复杂可编程逻辑器件CPLD现场可编程阵列FPGA

复杂可编程逻辑器件CPLD&现场可编程阵列FPGA 7.3 复杂可编程逻辑器件CPLD7.3.1CPLD的结构 7.4现场可编程门阵列FPGA7.4.1FPGA实现逻辑功能的基本原理7.4.2FPGA结构简介1.可编程逻辑块2.I/O块3.可编程连线资源CPLD与FPGA的区别 7.5可编程逻辑器件开发过程简介编程条件 7.3 复…

细说文件操作

你好&#xff01;感谢支持孔乙己的新作&#xff0c;本文就结构体与大家分析我的思路。 希望能大佬们多多纠正及支持 &#xff01;&#xff01;&#xff01; 个人主页&#xff1a;爱摸鱼的孔乙己-CSDN博客 目录 1.什么是文件 1.1.程序设计文件 1.1.1.程序文件 1.1.2.数据文件…

使用EntityFramework8的学习和开发过程中一些经验

前言&#xff1a; 本篇文章主要记录自己在EF8的学习和使用过程中的碰到一些坑和自己琢磨的一些解决问题的方法以及过程。 问题汇总&#xff1a; 一、Code First 模式下生成表中字段的没有按照我们想要的次序排列 实体上增加注解 [Column(Order 0)] 可以通过Order来控制字段…

[CISCN2019 华北赛区 Day1 Web1]Dropbox 1

目录 题目分析功能测试代码读取index.phpdownload.phpdelete.phpclass.php 关键代码审计user类FileList类File类思路 解题步骤php脚本解题 题目分析 功能测试 注册登录后来到上传文件界面&#xff0c;通过改后缀&#xff0c;改文件头&#xff0c;改content-type&#xff0c;上…

如何养护我们的头发一

正常头发含水量10-13% 头发含水量低 头发就会干燥 受到损伤 头发保水能力弱 保养头发,最重要的是防止头发头发的流水. 正确的洗涤方法 干性头发,一般3天洗一次 油性头发,一般1天洗一次 中性头发,一般2天洗一次 (2)正确的洗发步骤 选择好梳子建议选用木梳或牛角梳 按摩头皮…

释疑 803-(2)物理层 整理总结

目录 2-01 物理层要解决哪些问题?物理层的主要特点是什么? 2-02 规程与协议有什么区别? 2-03 试给出数据通信系统的模型并说明其主要组成构件的作用。 2-04 试解释以下名词&#xff1a;数据、信号、模拟数据、模拟信号、基带信号、带通信号、数字数据、数字信号、码元、…

PHP智能问诊导诊平台-计算机毕业设计源码75056

摘 要 智能问诊导诊平台作为一种智能化医疗服务工具&#xff0c;利用PHP语言开发&#xff0c;旨在为用户提供便捷的在线问诊和导诊服务。该平台集成了智能算法和医疗数据&#xff0c;实现了智能化的病情诊断和治疗建议&#xff0c;帮助用户更快速地获取医疗信息和建议。用户可…

未授权访问

一、Redis 未授权访问 redis-cli -h 192.168.4.176-p6379 &#xff08;使用这个连接&#xff09; 连接成功后使用info测试 二、MongDB 未授权访问 使用fofa搜mongdb端口复制ip到Navicat,连接 】 三、Zookeeper未授权访问漏洞 使用fofa 搜索2181端口使用下面命令在kali在…

5、SystemC行为级建模

1、sc_port关联sc_interface和channel。sc_module聚合sc_module、var、process和sc_port。sc_cthread和sc_method继承sc_thread。 sc_interface中声明很多虚函数&#xff0c;作为接口函数实现接口功能&#xff0c;如send()、recv()等。可以通过发送和接收模块的端口调用(sc_in…

CCF编程能力等级认证GESP—C++3级—20240629

CCF编程能力等级认证GESP—C3级—20240629 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)移位寻找倍数 单选题&#xff08;每题 2 分&#xff0c;共 30 分…

【基础篇】MySQL数据库详解:基础知识详解

一、SQL分类 1.DDL2.DML3.DQL4.DCL二、函数 1.字符串函数2.数值函数3.日期函数4.流程函数三、约束 1.概述2.约束演示3.外键约束四、多表查询 1.多表关系2.多表查询表述3.内连接4.外连接5.自连接6.子查询五、事务 1.事务简介2.事务操作3.事务四大特性4.并发事务问题5.事务隔离级…

C语言——求阶乘的两种方法

第一种方法使用了递归思想 #include <stdio.h> int fun(int N) {if (N 0){return 1;}else{return (fun(N - 1) * N);} } int main() {int N 0;scanf_s("%d", &N);printf("%d",fun(N)); } 第二种方法用的for循环 #include <stdio.h> i…

如何开启idea中的断言功能?

目录 一、什么是断言&#xff1f; 二、Java断言的语法 三、开启断言 一、什么是断言&#xff1f; 断言&#xff08;assert&#xff09;是 Java 中的一条语句&#xff0c;一种在程序中的逻辑&#xff08;如一个结果为真或假的逻辑判断式&#xff09;&#xff0c;目的是验证软…

Unity Shader unity文档学习笔记(十八):unity雾效原理

看很多文章用近平面远平面组成矩阵后转到裁剪空间下通过Z值来解&#xff0c;实际更简单的方式可以直接通过判断距离来实现 FogMgr控制远近面 public class TestFog : MonoBehaviour {public int startDis 0;public int endDis 50;public Vector4 fogParam;public void Awak…

springboot宠物宿舍管理系统-计算机毕业设计源码74795

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1系统开发流程 2.2.2 用户登录流程 2.2.3 系统操作流程 2.2.4 添加信息流程 2.2.5 修改信息流程 2.2.6 删除信息流程 2.3 系统功能…

javascript:判断输入值是数字还是字母

1 代码示例 要判断输入值是数字还是字母&#xff0c;我们可以通过JavaScript获取输入框的值&#xff0c;然后使用isNaN函数来检查输入值是否为数字。 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><s…

第一阶段面试问题(后半部分)

1. c语言中const *p的用法 &#xff08;1&#xff09;const int *p; 或 int const *p; 指向常量整数的指针&#xff0c;通过这个指针不能修改它所指向的整数值&#xff0c;但可以修改指针本身来指向其他地址 const int a 10; const int *p &a; // *p 20; // 错误&…

商家拒单业务

文章目录 概要整体架构流程技术细节小结 概要 商家拒单是电子商务、外卖平台、在线零售等多个行业中可能出现的情况&#xff0c;指的是商家拒绝接受或完成某个订单。这种情况的发生可能由多种原因引起&#xff0c;同时也涉及到商家、平台和消费者的利益平衡。 需求分析以及接…