1-03 C++起步: 用函数组织语句 —— 代码封装初步
C语言的语句不多, 归纳起来只有以下几种:
1) 表达式语句 |
在表达式后添上分号就是表达式语句, 例如下面的语句: |
2) 说明语句 |
如: 变量的说明、函数的说明、对象的说明等。例如: |
3) 空语句(仅一个分号) |
在语法规定必须写语句的地方, 实际没有任何操作, 可使用空语句。例如for语句的格式为: |
4) 复合语句(块语句) |
用花括号 { } 括起来的一组语句, 它被视为一条语句。 |
5) 流程控制语句 |
控制流程的语句主要有: |
程序主要用上面这五类语句来编写, 但仅有这些语句是不够的。以复数的加法为例, 完成该功能需要以下两条语句:
z.rpart = x.rpart + y.rpart; // 将x的实部与y的实部相加, 结果存入z的实部 z.ipart = x.ipart + y.ipart; // 将x的虚部与y的虚部相加, 结果存入z的虚部 |
如果程序中有大量的复数运算, 我们在需要做加法的地方, 都得写这样的语句, 极不方便。C语言提供了将一组语句包装起来, 为其命名的方法, 这就是函数。有了函数, 可以大大丰富语句的功能。我们可以把一些常用的操作以函数的形式包装起来, 需要的时候就调用, 这样, 一系列的小零件组装到一起, 就构成了一部机器或一个组件。以前的大程序大都是以这种方式设计出来的。
复数的加法是常用的操作, 我们将这个功能编写成一个函数, 命名为Add。显然, 每次用到它时, 参与运算的复数是变化的, 但做加法的动作是相同的。这些变化的数据, 写在形式参数表中, 相同的操作写函数体里面, 函数的计算结果(即函数值)通过return语句反馈给调用者。下面是该函数的原型:
COMPLEX Add(COMPLEX x, COMPLEX y);
函数的定义如下:
COMPLEX Add(COMPLEX x, COMPLEX y) { |
有了函数的定义, 需要时就可以像下面这样来调用:
c = Add(a, b);
调用时, 复数a的具体值将传递给x(即a复制到x), 复数b的具体值将传递给y(即b复制到y), 进入函数后, x和y里装的的内容分别与a和b的值相同, 计算完成以后, 计算结果在z中, 函数通过return语句把它复制到一个临时的区域中, 函数执行完毕, 三个局部变量x, y和z全部销毁? 氐降饔玫牡胤? 这个临时区域中的数据(即函数值)赋给变量c。
值得初学者注意的是: x, y, z虽然都是局部变量, 但他们的区别在于: z是一般的局部变量, 而x和y是特殊的局部变量——函数的形式参数。所以进入函数时, z的初值是不确定的(通常称为乱码), 而x和y的却已经自动装入了用户调用时给出的实际值, 它们分别是a和b的值。
复数的加、减、乘、除, 以及设置、输入、输出都是常用的操作, 编写六个函数来完成这些功能。这样, 用户使用复数时, 可直接调用有关的函数即可, 非常方便。例如复数的输出函数:
void Output(COMPLEX x) { |
类似地, 可以写出复数的输入函数:
void Input(COMPLEX x) { |
这个函数虽然能以通过编译, 但它却不能达到预期的目的, 所以是错误的。例如当用户调用它时写下:
Input(a);
它会怎样工作呢? 它首先把a的内容复制给x, 然后从键盘输入的数据装入x的实部和虚部, 等函数执行完毕, x被销毁, 而a仍然是原来的内容, 没有任何变化。在C语言里要解决这个问题, 只能使用指针, 通过间接操作修改变量的值来完成该功能。下面是用指针编写的函数:
void Input(COMPLEX *p) { |
这程序虽然正确, 但调用时得写成下面的样子:
Input(&a);
即将变量a的地址传递给指针p, 进入函数后, 把输入的数据装进指针p所指示的变量的实部和虚部, 等函数执行完毕, 指针p销毁, 但结果已经存入了变量a中。虽然这程序是正确的, 但使用时要使用取地址的运算符"&", 这和scanf("%d", &x)中的取地址符号的效用相当。如下图所示:
C++对C进行了改进, 提供了一种被称为“引用”的隐式指针, 但在逻辑上可以将其理解为代名词。下面是用引用编写的函数:
void Input(COMPLEX &x) { |
调用时不必写取地址的运算符, 而是简单地写为:
Input(a);
这里传递的不是a的值, 而是a的引用(实质就是地址), 因此x是对a的引用, 函数中所有的x都代表a, 对x的操作其实都是对a进行的。所以, 输入的数据装入了变量a的实部和虚部。函数执行完毕, 引用变量x销毁, 但结果已经存入变量a。
在函数的形式参数中使用引用, 可以对实在参数进行修改, 利用这种方法可以把信息反馈给调用者:
Input(a); // 调用Input函数时, 形参x是对a的引用, 对x的操作都是对a进行的, 从键盘输入的信息被装入a Input(b); // 调用Input函数时, 形参y是对b的引用, 对y的操作都是对b进行的, 从键盘输入的信息被装入b |
通过两次调用输入函数, 分别对a和b进行操作, 从键盘上输入的两个复数分别被装入了a和b。
引用除可以传回信息外, 它的另一个作用是提高程序的效率。以上面的输出函数为例:
void Output(COMPLEX x) { |
如果写下Output(c), 调用时先把c的内容(一共16字节)复制到x中, 然后输出x的内容。函数执行完毕, 销毁局部变量x。换句话说, 我们不是输出变量c的内容, 而是输出c的复制品x的内容。如果我们直接输出变量c的内容, 那么速度可以加快, 方法就是使用引用:
void Output(COMPLEX &x) { |
如果写下Output(c), 调用时传递的不是c的值, 而是c的引用(2或4字节的地址), x是对c的引用, 输出的是c的内容。这样做, 效率虽然提高了, 但危险性也增大了。如果程序员不小心, 在Output函数错误地对x进行了修改, 那将是对c进行的修改。为了保证c的内容不被修改, 可将x定义为常量的引用:
void Output(const COMPLEX &x) { |
这样, 当你在输出函数Output中写下修改x值的代码时, 编译器会认为你在试图修改一个常量, 报告编译错误。同样, 复数的加法函数也可以在形式参数表中使用常量引用的形式以提高效率:
COMPLEX Add(const COMPLEX &x, const COMPLEX &y) { |
下面是完整的程序, 包括所有这些功能: 输入、输出、设置、加、减、乘、除等。一共有三个文件, 分别是头文件、程序文件和主程序文件:
COMPLEX.H
#ifndef _COMPLEX_H_ struct COMPLEX { void Input(COMPLEX &x); #endif |
COMPLEX.CPP
#include <iostream> #include "complex.h" void Input(COMPLEX &x) { void Output(const COMPLEX &x) { void Set(COMPLEX &x, double r, double i) { COMPLEX Add(const COMPLEX &x, const COMPLEX &y) { COMPLEX Sub(const COMPLEX &x, const COMPLEX &y) { COMPLEX Mul(const COMPLEX &x, const COMPLEX &y) { COMPLEX Div(const COMPLEX &x, const COMPLEX &y) { |
MAIN.CPP
#include <iostream> #include "complex.h" int main() { |
假设用户输入的第一复数 3+4i, 第二个复数是 2-5i, 则程序的运行结果如下:
a = ? 3 4 |
请您仔细看看主函数, 您就能从中体会出函数带来的好处! 这还不是最好的版本, 我们将在后面逐步实现1-01中提到的最终效果。
1-03 C++起步: 用函数组织语句 —— 代码封装初步相关推荐
- Python(13)-函数,lambda语句
函数 1 函数定义 2 函数调用 3 函数注释文档 4 函数参数 4.1 参数列表,默认参数,任意参数 4.1.1 无缺省值参数 4.1.2(部分)缺省值参数 4.1.3 数量不定形参数 4.2 可变 ...
- 读书笔记_代码大全_第14章_组织直线型代码_第15章_使用条件语句
组织直线型代码 + 使用条件语句 希望我的读书笔试能带你翻过18页的书 http://www.cnblogs.com/jerry19880126/ <代码大全>第14章和第15章的内容比较 ...
- C++ Primer 5th笔记(chap 18 大型程序工具)函数 try 语句块与构造函数
1. 问题 构造函数在进入函数体之前首先执行初始化列表.因为在初始值列表抛出异常时构造函数体内的try语句块还未生效 1.1 解决方法 {// 这是处理构造函数初始值错误的唯一方法template & ...
- mfc formview中的关闭视图函数_VC|API消息处理(回调函数+分支语句)与MFC中的消息映射函数...
Windows程序不同于控制台程序,因为输入输出不再是scanf和printf那么简单了,而是通过窗口(包括对话框和控件)作为输入.输出的界面以及键盘.鼠标的各类输入事件. 用户在操作系统中的任何操作 ...
- python查函数用法语句_Python-17 (函数的基本使用)
# 1. 函数的说明 这里要明确函数的基本使用/函数的参数/函数的返回值/函数的嵌套调用/函数在模块中的定义 基本概念: 函数就是把 具有独立功能的代码块 封装成模块,在需要时调用即可: 1&g ...
- SQL注入-常用函数和语句
文章目录 前言 0x01 常用函数 0x02 常用语句 总结 前言 SQL的函数很多,这里简单介绍一下在SQL注入中比较常用到的一些函数,如果你SQL学的不是很好,又想练一练SQL手工注入的话,可以优 ...
- Go函数--defer语句
1 defer语句 该语句用于延迟调用指定的函数,它只能出现在函数或方法的内部,由defer 关键字以及针对某个函数的调用表达式组成.这里被调用的函数称为延迟函数.简单的示例如下 func outer ...
- 【C语言】结构组成(函数、语句、注释)
C语言结构组成 一.相关基础知识 二.具体内容 C语言由函数.语句和注释三部分组成: (1)函数与主函数: 一个C语言源程序可以由一个或多个源文件组成,每个源文件可由一个或多个函数组成,一个源 ...
- 03、Flutter FFI 函数
Flutter FFI 学习笔记系列 <Flutter FFI 最简示例> <Flutter FFI 基础数据类型> <Flutter FFI 函数> <Fl ...
最新文章
- ROS中Remap标签详解
- 如何编写YARN应用程序
- Sprinig Boot + Redis 实现接口幂等性,写得太好了!
- Unity3d与android通信
- [Umbraco] 创建第一个页面
- android 紧急号码没记录,android – 当呼叫被隐瞒/未知时,来电号码是...
- symbol(s) not found for architecture i386
- SQL(一)- 数据库介绍与基础操作
- 思科命令 service password-encryption
- 从PHPer到Gopher要经历的一些转变
- 获取目录文件.bat
- pc端和移动端抓包工具
- 赶超磁盘的磁带备份技术
- 计算机故障含义,宕机是什么意思(电脑宕机的读法与含义)
- linux pcf8563开发文档,linux下的i2c与时钟芯片pcf8563通信
- Plantuml类图用法
- 【ORACLE】ORA-01653: unable to extend table XXXX by 128 in tablespace XXX
- 数据结构与算法——从零开始学习(五)树和二叉树
- 教育:构造主义和机能主义
- linux中安装redis报错
热门文章
- 在Linux服务器上安装horovod安装
- 小知识:Access端口和Trunk端口
- 免费个人网页制作指南Dreamweaver教程
- js实现,点击侧边导航栏,可以平缓的跳到界面指定位置,同时当界面某个元素在浏览器可视范围的时候,相应的导航栏也显示相应的样式
- 人生值得一看-观念,关键在观念 !
- SQL窗口函数-截止至某天的累计值
- python日期处理、groupby聚合、求最大值、方差
- c语言 快速筛质数,快速筛素数(埃式筛+线性筛+Miller_Rabin算法)
- compact mysql_PHP compact() 函数
- http-https数据包的基本知识