第八章 函数


函数的基本概念

定义:函数由函数名、参数和函数体组成。

函数定义的一般形式:

类型说明符  函数名(形式参数声明)
{
    [说明与定义部分]
    语句;
}

说明:

1、类型说明符用来说明函数的返回值的类型

2、函数名是用户自定义的用于标识函数的名称,命名规则与变量的命名规则相同

3、形式参数声明(简称形参表)用于指明调用函数和被调用函数之间的数据传递,传递给函数的参数可以有多个,也可以没有。

函数的调用:

函数的调用,是指一个函数(调用函数)暂时中断本函数的运行,转去执行另一个(被调用函数)的过程。被调用函数执行完后,返回到调用函数中断处继续调用函数的运行。函数的一次调用必定伴随一个返回过程。

一般形式:

函数名(实际参数表列);

或

函数名(实际参数表列)

说明:

1)第一种调用格式是以语句的形式调用函数,用于调用无返回值的函数。第二种调用格式是以表达式的形式调用函数,用于调用有返回值的函数,通过调用函数的表达式接收被调用函数送回的返回值。

2)实际参数表列(简称实参表)中实参的类型与形参的类型相对应,必须符合赋值兼容的规则,实参个数必须与形参个数相同,并且顺序一致,当有多个实参时,参数之间用逗号隔开。

3)实参可以是常量、有确定值的变量或表达式及函数调用。

4)实参可以是常量、有确定值的变量或表达式及函数调用。当函数调用时,系统计算出实参的值,然后按顺序传给相应的形参。

函数的传递方式:

1、值传递:在函数调用时,实参将其值传递给形参,这种传递方式即为值传递。C语言规定,实参对形参的数据传递是“值传递”,即单向传递,只能由实参传递给形参,而不能由形参传递给实参。

注:在执行一个被调用函数时,形参的值如果发生变化,并不会改变调用函数中实参的值。

函数的返回值:

return语句的一般形式:return (表达式);

说明:
return语句有双重作用:从函数中退出,返回到调用函数中并向调动函数返回一个确定的值。return语句也可以没有表达式,此时它的作用仅是使执行的流程返回到调用函数的调用位置继续执行调用函数。

return语句后表达式两边的圆括号可以省略。

当函数有返回值时,凡是允许表达式出现的地方,都可以调用该函数。

一个函数中可以有多个return语句,执行到哪一个return语句,哪一个语句起作用

若函数中无return语句,函数也并非没有返回值,而是返回一个不确定的值。

数组作为函数参数

一维数组作为函数参数时,形参的写法为:

类型说明符 形参数组名[数组长度]

一维形参数组说明时可以不指定数组长度,但方括号不能省略。通常,为了使程序能了解当前处理的数组的平均长度,往往需要另一个参数来表示数组的长度。

二维数组作为函数参数时,形参的写法为:

类型说明符 形参数组名[数组长度1][数组长度2]

二维数组作为函数参数时,可以不指定第一维的长度,但是第二维长度不能省略。

数组作为函数参数进行函数调用时,实参应采用数组名。

说明:

1)数组作为函数参数时,实参和形参数组应在调用函数和被调用函数中分别定义。

2)实参数组和形参数组类型应一致,行数可不一致,列数必须一致。

函数的嵌套调用和递归调用

一个函数在执行过程中可以调用其他函数,这就是函数的嵌套调用。

函数的递归调用

函数的递归调用是C语言的重要特点之一,即在调用一个函数的过程中又直接或间接地调用该函数本身。

变量的作用域和存储方法

局部变量和全局变量:在函数内部或复合语句中定义的变量称为局部变量。局部变量的作用域仅仅局限于定义它的函数和复合语句。

说明:

1)在一个函数内部定义的变量只在本函数范围内有效,只有本函数内才能应用,在该函数外是不能使用这些变量的。

2)形式参数也是局部变量,只在定义它的函数中有效,其他函数不能使用。

3)不同函数中定义的变量可以同名,它们代表不同的对象。

4)在复合语句中定义的变量的作用域为本复合语句,在复合语句之外也不能使用。

在函数体外定义的变量称为全局变量。全局变量的作用域是从它的定义点开始到本源文件结束,即位于全局变量定义后面的所有函数可以使用此变量。

变量的存储方法:变量的存储属性就是数据在内存中的存储方法。存储方法可分为两大类:动态存储和静态存储,具体分为四种:自动型(auto)、静态型(static)、寄存器型(register)、外部性(extern)

局部变量的存储方法:局部变量有三种存储类型:自动型、静态型和寄存器型

(1)自动变量:函数中的局部变量,如不进行专门的说明,则对它们分配和释放存储空间的工作由系统自动处理,这类局部变量称为自动变量。

(2)局部静态变量:如果希望在函数结束之后仍然保留着其中定义的局部变量的值,则可以将局部变量定义为局部静态变量

局部静态变量定义的一般形式为:

static  类型说明符  变量名

说明:

局部静态变量是在静态存储区分配存储单元的,在整个程序运行期间都不释放。因此函数调用结束后,它的值并不消失

局部静态变量是在编译过程中赋初值的,且只赋一次初值,在程序运行时其初值已定

局部静态变量的默认初值为0(对数值型变量)或空字符(对字符变量)

寄存器变量:

register char ch

使用寄存器变量可以缩短存取时间,通常将使用频率较高的变量设定为寄存器变量

全局变量的存储方法:全局变量是在静态存储区分配存储单元,其默认的初值为0.全局变量的存储类型有两种,即外部(extern)类型和静态(static)类型。

内部函数和外部函数

内部函数又称静态函数,它只能被本文件中的其他函数所调用。

内部函数定义的一般形式:

static 类型说明符 函数名(形式参数声明)
例如:
static float sum(float x, float y)
{

}

使用内部函数,可以使函数的使用范围仅局限于本文件,如果在不同文件中有同名的内部函数,也互不干扰。

外部函数:在定义函数时,如果使用关键字extern,表明此函数是外部函数。例如:

extern char compare(char s1, char s2)
{

}

由于函数都是外部性质的,因此在定义函数时,关键字extern可以省略。

编译预处理

编译预处理是C语言编译程序的组成部分,用于解释处理C语言源程序中的各种预处理命令。如 #include#define命令

C提供的预处理功能主要有宏定义、文件包含和条件编译3种,为了与其他语句相区别,所有的预处理命令均已 # 开头,语句和结尾不实用分号 ";",每条预处理命令需要单独占一行。

宏定义

宏定义是指用一个指定的标识符来定义一个字符序列。宏定义是由源程序中的宏定义命令完成的,宏替换是由预处理程序完成的。

宏定义分为无参宏定义和有参宏定义两种

无参宏定义的一般形式:

#define 宏名 替换文本

如果程序中使用了宏定义,在对源程序进行编译预处理时,自动将所有出现的“宏名”用宏定义中的替换文本来替换,通常称为宏替换或宏展开。宏替换是纯文本替换。

说明:

1、宏名按标识符书写规定进行命名,为区别于变量名,宏名一般习惯用大写字母表示。无参宏定义用来定义符号常量。

2、替换文本是一个字符序列,也可以是常量、表达式、格式串等。

3、宏名与替换文本之间用空格分隔。

4、宏定义可以出现在程序的任何位置,但必须是引用宏名之前。

5、在进行宏定义时,可以引用之前已定义过的宏名。

宏定义通常放在程序的开头,函数定义之外,其有效范围是从宏定义语句开始至源程序文件结束。

带参数的宏定义
带参数的宏定义的一般形式:

#define 宏名(形参表) 替换文本

文件包含:一种预处理语句,作用是使一个源程序文件将另一个源程序文件全部包含进来,一般形式为:

#include 或 #include "文件名"

说明:一个#include只能包含一个指定文件。

《C语言程序设计》学习笔记(二)的更多相关文章

  1. Stealth视频教程学习笔记(第二章)

    Stealth视频教程学习笔记(第二章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...

  2. Stealth视频教程学习笔记(第一章)

    Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...

  3. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  4. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  5. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  6. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  7. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  8. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  9. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  10. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

随机推荐

  1. Spring事务管理器

    1.创建实体和接口 public class Bank { private Integer id; private String name; private String manay; public ...

  2. $("xxx"); 使用jQuery获得对象

    $("xxx"); 使用jQuery获得对象 console.log( $ ( $ ( $ ( '.dropdown' ) ) ) );  与下面返回的结果都是一毛一样的. con ...

  3. vuex的使用介绍

    1.vuex是什么? vuex是一个专为vue.js应用程序开发的状态管理模式(它采用集中式存贮管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化). 2.vuex的核心概念? ...

  4. 使用quickstart方式快速搭建maven工程

    通常idea 创建maven工程,初始化会比较慢,针对这种现象.我们可以使用一些巧妙的方式来帮助快速搭建 废话不多说直接上图! 图1 使用 archetype-quickstart  选择 图二 点击 ...

  5. Appium自动化测试教程-自学网-monkey自定义脚本实践

    自定义脚本的稳定性测试 常规Monkey测试执行的是随机的事件流,但如果只是想让Monkey测试某个特定场景这时候就需要用到自定义脚本了,Monkey支持执行用户自定义脚本的测试,用户只需要按照Mon ...

  6. php面向对象之数据隐藏

    什么是数据隐藏? 看到这个有的人会觉得挺不理解的.在前面的文章中,介绍类的时候,我们说定义变量用的关键词是public,但是不止这一个,还有public.private.protected.stati ...

  7. 浅谈"$fake$树"——虚树

    树形$dp$利器——"$fake$"树(虚树$qwq$)  前置知识: $1.$$dfs$序 $2.$倍增法或者树链剖分求$lca$  问题引入: 在许多的树形动规中,很多时候点特 ...

  8. parted分区命令

    Parted是一个比fdisk更高级的工具,它支持多种分区表格式,包括MS-DOS和GPT.它允许用户创建,删除,调整大小,缩小,移动和复制分区,重新组织磁盘使用,以及将数据复制到新硬盘,但在缩小分区 ...

  9. 通过时间戳批量删除hbase的数据

    如何通过时间戳批量删除hbase的数据 我们使用hive关联hbase插入数据时,有时会写错数据,此时hbase中的数据量已经很大很大了(上亿).此时,我们要修改错误的数据,只需要删除写错的那部分数据 ...

  10. 2018-2019-2 20165234 《网络对抗技术》 Exp9 Web安全基础

    Exp9 Web安全基础 一. 实践内容 1. 安装JDK.Webgoat 2. SQL注入攻击 数字型注入(Numeric SQL Injection) 日志欺骗(Log Spoofing) 字符串 ...