2017-09-27  18:40:47

程序设计的基本概念

1、计算机语言:把人与计算机之间交流的语言叫做计算机语言

1)计算机语言分为高级语言和低级语言

2)高级语言:远离硬件

3)低级语言:贴近硬件

2、指令:是指计算机执行某种操作的命令。它由一串二进制数码组成。

1)一条指令通常由两个部分组成:操作码+地址码。

2)操作码:指明该指令要完成的操作的类型或性质,如取数、做加法或输出数据等。

3)地址码:指明操作对象的内容或所在的存储单元地址。

3、机器语言:计算机本身各个部件之间沟通时所使用的语言

特点:对计算机本身来说,只能识别由0和1代码构成的二进制指令

4、源程序:把由高级语言编写的程序称为源程序

1)源程序————编译程序————目标程序(二进制代码表示的程序,即计算机只识别目标程序)

2)编译程序:如何把源程序转换成机器能够接受的目标程序,软件工作者编制了一系列的软件,通过这些软件可以把用户按规定语法写出的语句一一翻译成二进制的机器指令。这种具有翻译功能的软件称为“编译程序”。

3)C源程序:用C语言构成的指令序列称为C源程序

4)C语言的代码编写:按C语言的语法编写C程序的过程,称C语言的代码编写。

5)C语言源程序文件名的后缀是 .c ,经过编译后,生成文件的后缀是 .obj ,经过连接后,生成文件的后缀是 .exe 。

5、程序设计一般包含以下几个部分:

1)确定数据结构

2)确定算法

3)编码

4)在计算机上调试程序

5)整理并写出文档资料

6、算法:是指为解决某个特定问题而才去的确定且有限的步骤。

一个算法应当具有以下五个特点:

1)有穷性

2)确定性

3)可行性

4)有零个或多个输入

5)有一个或多个输出

算法可以用各种描述方法进行描述,最常用的是伪代码和流程图。

7、C语言为结构化的语言

C语言共有3中结构:

1)顺序结构

2)选择结构

3)循环结构

  • 当型循环:先判断,后执行。最少执行0次
  • 直到型循环:先执行,后判断。最少执行1次

简单C语言的构成和格式

1、命令行

1)命令行必须以“#”开头,最后不能加“;”结尾,因为它不是C语言的语句。

2)一对双引号中间的stdio.h是系统提供的文件名,该文件中包含着有关输入输出函数的 信息。

2、主函数

1)main是主函数名,C语言规定必须用main作为主函数名

2)主函数后的一对括号中间可以是空的,但这一对括号不能省略。

3)一个C程序可以包含任意多个不同名字的函数,但必须有且只有一个主函数。

4)C程序的运行总是从主函数开始执行。

3、函数体

1)在主函数的下方是 函数体部分,函数体总是从“{”开始,到“}”结束。

2)函数体分为定义(说明)部分和执行语句部分。

3)可执行语句数量不限,但必须放在定义语句后面。

4、C语言的简单语法格式

1)C语句必须以“;”结束,“;”是C语句的一部分,而不是语句间的分隔符。

2)注释符号“/*” “*/”必须成对出现,且不允许出现嵌套情况。“/”和“*”之间不允许有空格。

标识符的组成和分类

什么是标识符?

1、组成:由字母、数字、下划线组成。

2、组成规则:标识符不能以“数字”开头

3、特点:

1)区分大小写

2)在C语言中,计算机只识别长度为“8”位以内的标识符。(即标识符最多只能有8位)

标识符的分类

1、关键字

1)系统已经给定含义的,我们不能在用作其他的含义(如:if、while等等)

2)C语言共有39个关键字

2、预定义标识符

1)系统已经定义好的含义,但我们可以用作其他含义的标识符。(如:printf、scanf等等)

2)建议不要更改预定义标识符。

3、用户自定义标识符

1)用户自己定义的标识符。

2)自己定义的标识符要符合标识符的组成规则。

整形数据和实型数据

常量

1、定义:程序运行中,始终不变的量。

2、分类:

1)整形常量(如:123)

2)实型常量(如:12.34)

  1. float
  2. double

3)字符型常量(如:'a')

4)字符串常量(如:''hello'')

5)符号常量(比如:∏ 3.1415926

  1. 语法格式:#define 标识符 常量
  2.  #define PI 3.14159 (其含义是在程序中凡是出现PI时,其值都为3.14159)

变量

1、定义:其值可以改变的量。

2、本质:内存中的存储单元。

3、特性:

1)变量先定义后使用。

2)凡未被事先定义的,不作为变量名。

3)每一变量被指定为一确定类型,在编译时就能为其分配相应的存储单元。

4)指定每一变量类型属于一类型,这就便于在编译时,据此检查该变量所进行的运算是否合法。

4、理解:

1)变量相当于宾馆,存储单元相当于宾馆的房间。

2)宾馆的房间有单人间也有双人间,故变量的存储单元有大有小。

3)只有先给客户分配一个房间才能使用,即变量先定义后使用。

变量名相当于房间号,如101、102等等是不变的,即变量名在使用的过程中是不变的。但是房间里面的房客在不断改变,即变量值在使用的过程中是可以变的。

整形常量

1、表示方法:十进制、八进制、十六进制

2、表示方法的特点

1)十进制:用一连串的数字来表示,中间不允许有空格或其他字符(十进制数“逢十进一”)。

2)八进制:

  1. 八进制数用数字“0”开头(注意,不是字母“o”。八进制数“逢八进一”)。
  2. 八进制只能用合法的八进制数字表示,数字“0~7”,担当输入非法数字时,C程序不会提示,只是得不到正确的结果。

3)十六进制:用数字“0”和字母“x”开头。十六进制只能含有合法的十六进制数字,字母“a-f”数字“0-9”。

注意:比如逢十进一则表示最大的数字是9

3、三种进制之间的转换:

1)八进制和十六进制转换成十进制(用乘法)

  1. 方法:从低位开始逐次让它去乘以以进制数为底,幂数逐渐增加。最后将每位所得的结果相加即可(幂数从0开始)。
  2. 列子:
  • 十进制:123=3*100+2*101+1*102
  • 八进制:0123=3*80+2*81+1*82‘;
  • 十六进制:0xbd=13*160+11*161

2)十进制转换成八进制和十六进制(用除法)

  1. 方法:用短除法进行运算,分别得到余数,直到最后商为0时为止,最后将余数从下到上依次写出来即可。
  2. 列子:

十进制数为256

转八进制:0400                                                        转十六进制:0x100

                          

十进制数为:189

转八进制:0275                 转十六进制:0xbd

       

整型变量:

1、整形变量的定义:

1)基本整形变量用类型名关键字int进行定义。

2)一个定义语句必须用分号“;”结束,在一个定义语句中可同时定义多个变量,变量之间用逗号“,”隔开。

3)当程序中用以上方式定义变量i,j,k时,编译程序会为变量i,j,k都开辟存储单元,但并没有在存储单元中存放任何初值,因此这些存储单元中原有的信息垃圾并没有被清除,这时,变量中的值是无意义的,称变量值“无意义”。-----------------理解:在一个宾馆里我订了3个房间,但是我订下来之后没有去,我准备在下个月1号去。但是在我去之前房间原有的房客还在,知道我住进去之后,这些房间里的房客才出来。所以,在我没有住进去的这段时间里不能说这个房间里面的人是我,所以在没有给变量赋值之前,这些变量都是无意义的。

4)C语言规定,可以在变量定义的同时给变量赋初值,也称为变量初始化。

2、整数在内存中的存储形式

1)存储单位

  1. 在计算机中,内存器的最小存储单位称为“位”,每一个位中只能存放“0”或者“1”,因此称为二进制位,大多计算机把8个二进制位组成一个“字节”。
  2. 最左边的一位称为“最高位”,最右边的一位称为“最低位”。
  3. 若是正整数,最高位是“0”,若是负整数,最高位是‘“1”。

2)存储方式

  1. 正整数:正整数在内存中以正整数的“原码”的方式存放。
  2. 负整数:C语言中,对于负整数,在内存中是以相应正整数的“补码”的方式存放。
  • 原码:以二进制的形式存在的正整数就叫做正整数的原码。
  • 反码:对正整数原码的各位分别进行取反所形成的新的字节就叫做正整数的反码。
  • 补码:对反码的最低位加“1”后形成的新的字节就叫做正整数的补码。故:原码取反得到反码,然后反码再加1就得到补码。

列:-5以一个字节的形式在内存中是如何存放的了?

首先求5的原码为:5=22+1=100+1=101,所以一个字节存放时的原码为00000101

然后求5的反码为:11111010

最后求5的补码为:11111011

所以,5的二进制表示方式是:00000101,-5的二进制表示方式是11111011。

那么如何通过补码求相对应的整数了?

规则为:先求二进制数补码的反码,然后求对应的十进制正整数(求出来之后要给加个负号,因为只有负数才以补码的形式存在),最后减“1”则为所要求的十进制数。

列:已知内存中以补码形式 存放的二进制数11111010,那么它的十进制数为?

补码:11111010,所以反码为:00000101

又00000101=1*20+0*21+1*22=5,所以为-5

故真正的十进制数为:-6

实型常量

表示方法:

1)小数形式:即在数学中常用的实数形式,由数字和小数点组成。

2)指数形式:

  1. 这种形式类似于数学中的指数形式。在数学中,一个数可以用幂的形式来表示。在 C语言中,则以“e”或“E”后跟一个整数来表示以10为底的幂数。列:2.3026=0.2306*101=2.3026*100=23.026*10-1=0.2306E1=2.3026E0=23.026E-1
  2. C语言中规定,字母E或者e之前必须有数字,且e后者E后面的指数必须为整数。字母E或者e前后以及数字之间不得插空格。

实型变量

1、C语言中实型变量分为单精度和双精度两类,分别用类型名“float”和“double”进行定义。

2、单精度与双精度型的区别如下:

1)在一般计算机系统中,为float类型的变量分配4个字节的存储单元,为double类型的变量分配8个字节的存储单元。

2)在一个程序中一个实数可以用小数形式表示,也可以用指数形式表示,但在内存中,实数一律是以指数形式存放的

算术表达式和赋值表达式

基本算术运算符

在C语言中基本的算数运算符是:+、-、*、/、%,分别为加、减、乘、除、求余运算符。

1 、运算符需要两个运算对象,称为双目运算符,除求余外,运算对象可以是整型也可以是实型。

2、求余运算符的运算对象只能是整型,在“%”运算符左侧的运算数为被除数,运算结果是两数相除后所得的余数。当运算为负数时,所得结果的符号与被除数相同。

例如:17%-3=2      -19%4=-3     -15%-7=-1

3、“+”和“-”也可用作单目运算符,运算符必须出现在运算量的左边,运算量可为整型,也可为实型。

4、说明:

1)双目运算符两边的运算类型必须一致才能进行操作。所得结果类型与运算类型一致。

例:1.0/2.0=0.5     1/2=0     1.0/2     1/2.0

2)如果双目运算符两边运算数的类型不一致,系统将自动把两边转换成相同类型后,进行运算:

  1. 如一边是整型数,一边是实型数时,系统将自动把整型转换为实型数。
  2. 如一边是长整型,一边是短整型,系统将自动把短整型转换为长整型。(长整型在内存中占用4个字节,短整型在内存中占用2个字节。长整型更加精确。)
  3. 如一边是有符号型,另一边是无符号型,系统将自动将有符号型转换为无符号型。
  4. 在C语言中,所有实数的运算均以双精度方式进行,若是单精度数,则在尾数部分补0,使之转化为双精度。

算术运算符的优先级

优先级
运算符
名称或含义
使用形式
结合方向
说明
1
[]
数组下标
数组名[常量表达式]
左到右
 
()
圆括号
(表达式)/函数名(形参表)
 
.
成员选择(对象)
对象.成员名
 
->
成员选择(指针)
对象指针->成员名
 
2
-
负号运算符
-表达式
右到左
单目运算符
(类型)
强制类型转换
(数据类型)表达式
 
++
自增运算符
++变量名/变量名++
单目运算符
--
自减运算符
--变量名/变量名--
单目运算符
*
取值运算符
*指针变量
单目运算符
&
取地址运算符
&变量名
单目运算符
!
逻辑非运算符
!表达式
单目运算符
~
按位取反运算符
~表达式
单目运算符
sizeof
长度运算符
sizeof(表达式)
 
3
/
表达式/表达式
左到右
双目运算符
*
表达式*表达式
双目运算符
%
余数(取模)
整型表达式/整型表达式
双目运算符
4
+
表达式+表达式
左到右
双目运算符
-
表达式-表达式
双目运算符
5
<<
左移
变量<<表达式
左到右
双目运算符
>>
右移
变量>>表达式
双目运算符
6
>
大于
表达式>表达式
左到右
双目运算符
>=
大于等于
表达式>=表达式
双目运算符
<
小于
表达式<表达式
双目运算符
<=
小于等于
表达式<=表达式
双目运算符
7
==
等于
表达式==表达式
左到右
双目运算符
!=
不等于
表达式!= 表达式
双目运算符
8
&
按位与
表达式&表达式
左到右
双目运算符
9
^
按位异或
表达式^表达式
左到右
双目运算符
10
|
按位或
表达式|表达式
左到右
双目运算符
11
&&
逻辑与
表达式&&表达式
左到右
双目运算符
12
||
逻辑或
表达式||表达式
左到右
双目运算符
13
?:
条件运算符
表达式1? 表达式2: 表达式3
右到左
三目运算符
14
=
赋值运算符
变量=表达式
右到左
 
/=
除后赋值
变量/=表达式
 
*=
乘后赋值
变量*=表达式
 
%=
取模后赋值
变量%=表达式
 
+=
加后赋值
变量+=表达式
 
-=
减后赋值
变量-=表达式
 
<<=
左移后赋值
变量<<=表达式
 
>>=
右移后赋值
变量>>=表达式
 
&=
按位与后赋值
变量&=表达式
 
^=
按位异或后赋值
变量^=表达式
 
|=
按位或后赋值
变量|=表达式
 
15
,
逗号运算符
表达式,表达式,…
左到右
从左向右顺序运算

说明:

同一优先级的运算符,运算次序由结合方向所决定。

简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符

算术表达式

1、定义:用算数运算符和一对圆括号将运算量连接起来的,符合C语法的表达式称为算术表达式。

2、运算规则和要求:

1)在算术表达式中,可使用很多层括号,但左右括号必须配对。运算时从内层圆括号开始,由内向外,依次计算表达式的值。

2)在算术表达式中,若包含不同优先级的运算符,则按运算的优先级由高到低进行,若表达式中运算符的级别相同,则按运算符的结合方式进行。

强制类型转换表达式

1、强制类型转换表达式形式:(类型名)(表达式)

2、“类型名”为强制类型转换运算符,可以利用强制类型转换运算符,讲一个表达式的值转换成指定的类型。

例:(int)3.324=3    (double)(10%3)=1.0

注:强制类型转换的类型名的“括号”不能省略,明确需要转换的是单个还是整体。

赋值运算符和赋值表达式

1、定义

1)在C语言中,“=”符号称为赋值运算符,有赋值运算组成的表达式称为赋值表达式。

2)复制形式:变量名=表达式。赋值号左边是变量名,右边必须是C语言合法的表达式。

3)自右向左读

  1. a=10 把常量10赋给变量a
  2. b=a   把a中的值赋给变量b,a中的值不变

4)内存中当前的数据就是最后一次所赋的那个数据。

2、说明

1)赋值运算符的优先级别只高于逗号运算符,比其它任何运算符的优先级别都低,且具有自右向左的结合性。

2)赋值运算符不同于数学中的“等于号”,这里不是等同的关系,二是进行“赋予”的操作。

3)赋值表达式x=y的作用是,将变量y所代表的存储单元中的内容赋给变量x所代表的存储单元,x中原有的数据被替换掉;赋给后,y变量中的内容保持不变、此表达式当读作“把右边变量中的值赋予左边的变量”。

4)在赋值表达式x=x中,赋值号右边的x表示变量x所代表的存储单元中的值,赋值号左边的x代表以x为标识的存储单元,该表达式的含义是取变量x中的值放到变量x中去。

5)在赋值表达式n=n+1中,其作用是取变量n中的值加1后,再放入变量n中,使变量n的值增1。

6)赋值运算符的左侧只能是变量,不能是常量或者表达式。

例:a+b=c          是不合法的

7)赋值号右侧的表达式也可以是一个赋值表达式,如a=b=7+1,按照运算符的优先级,以上表达式先计算7+1的值是8;按照赋值运算符自右向左的结合性,将先把8赋给变量b,然后再把变量b的值赋给变量a,而a=7+1=b不合法,因为7+1=b中,赋值号左边不是一个变量。

8)在C语言中,“=”符号被视为一个运算符,a=19是一个表达式,而表达式应该有一个值,C语言规定最左边变量所得到的新值就是赋值表达式的值。

9)C语言赋值表达式可以作为语句中的某个成分出现在众多的语句或表达式中,因而比较难以掌握变量中的数值变化过程。

10)给变量赋常量和赋表达式的值,有不同的结果。

例:r是整型变量

  1. 当赋值号右边是 常量,进行r=6000赋值时,系统把6000转换为60000L,然后赋给r。(60000已经超出了整型常量的范围,会自动转换为长整型)
  2. 当赋值号右边是表达式r=15000+15000时,先计算15000+15000=30000,r=30000。
  3. 当赋值号左边的表达式时r=30000+30000时,先计算30000+30000=60000,表达式的类型与运算符的类型一致,为int类型。但C中,int类型的最大值为32767,占两个字节,60000已超出两个字节,系统只取存于两个字节中的内容进行转换,把它赋给r,因此所赋值已不是60000,而是-32768~32767之间的一个数。

复合的赋值表达式

1、概念:

在赋值运算符之前加上其它运算符可以构成复合赋值运算符。C语言规定可以用10种复合赋值运算符,其中与算术运算符有关的复合运算符是:+=、-=、*=、/=、%=(注意:两个符号之间不可以有空格)。复合赋值运算符的优先级与赋值运算符的优先级别相同。

例:n+=1  n*=m+3

2、例题:已有变量a,其值为9,计算表达式a+=a-=a+a的值。

分析:因为赋值运算符与复合赋值运算符的优先级相同,且结合方向为自右向左,所以:

a+=a-=a+a  计算a+a,因为a初值是9,所以表达式值为18

a+=a-=18         计算a-=18  a=a-18    a=-9

a+=-9     计算a+=-9    a=a+(-9)  a=-18

a=-18

赋值运算符中的类型转换

1、在赋值运算中,只有在赋值号右侧表达式的类型与左侧变量的类型完全一致时,赋值操作才能进行。

2、如果赋值运算符两侧的数据类型不一致,在赋值前,系统将自动先把右侧的表达式求得的数值,按赋值号左边变量的类型进行转换,也可以用强制类型转换的方式,认为的进行转换后赋给赋值号左边的变量。

注:

1)当赋值号左边的变量为短整型,右边的值为长整型时,短整型变量只能接受长整型数最低位上的两个字节中的数据,高位上的两个字节的数据将丢失。

例:

int a;

unsigned long b;

b=98304; a=b;

printf("%d\n",a);

则a的值为-32768。因为98304(11000000000000000)已经超出短整型的数值范围,a截取b中低16位中的值(1000000000000000),由于高位数是1所以为负数,值正好为-32768。

2)当赋值号左边的变量为有符号整型,右边的值为无符号整型时,赋值的机制同上。这时若最高位是1,将按负数处理。

自加自减运算符

1、自加运算符“++”和自减运算符“--”的运算结果是使运算对象的值增1或减1。自加或自减运算符本身也是一种赋值运算符。

i++  i=i+1

i--    i=i-1

2、++、--运算符是单目运算符,运算对象可以是整型变量,也可以是实型变量,不能是常量或表达式,因为不能给常量或表达式赋值;因此,像++3、(i+j)--等都是不合法的。

3、自加、自减运算符既可以作为前缀运算符也可以作为后缀运算符而构成一个表达式。但无论是作为前缀还是后缀运算符,对于变量本身来说自增1或自减1都具有相同效果,但作为表达式来说却有不同的值。

1)++i或--i在使用i之前先使i的值增加或者减少1。

2)i++或i--在使用之后使i的值加或者减1,i变,值不变。

例如:i=2; a=i++;  a=2;i=3;  可以这样理解:先把i的值赋给a然后再给i加1。即(a=i  i=i+1)

   i=2; a=++i;  a=3;i=3;  可以这样理解:先给i的值加1然后再将i的值赋给a。即(i=i+1 a=i)

4、++和--运算符的结合方向是自右向左。

例如:-i++  -(i++)

逗号运算符和逗号表达式

1、“,”是C语言提供的一种特殊运算符,用逗号运算符连接起来的式子称为逗号表达式,逗号表达式的一般形式为:

表达式1,表达式2,..........,表达式n

2、说明:

1)在所有运算符中,逗号运算符的优先级别最低。

2)逗号运算符的结合性为从左到右,因此逗号表达式将从从到右进行运算。最后一个表达式的值就是此逗号表达式的值。

例:i=3,i++,++i,i+5

分析:i=3

   i++  i=i+1  i=4

++i  i=i+1  i=5

i+5

此逗号表达式的值为10,i的值为5。

顺序结构

输出函数(printf)

1、作用:printf函数的作用是在终端设备上按指定的格式输出。

2、printf函数的一般调用形式:

printf("格式控制",输出项表);    -----------格式控制实在双引号里面的,千万不要忘记、格式控制和输出项表一一对应。(类型匹配)

3、格式控制:

1)它总是由“%”开始,进跟其后的是格式描述符。

2)为各输出项提供格式转换说明。

3)提供需要原样输出的文字或字符。

在格式控制内,除格式说明以外的其它字符,一律原样输出。

例:printf("a=%d",a);    "a="原样输出

  printf("%%%",a);    输出%%

4、printf函数常用的格式说明:

1)格式字符:

  1. c————————————输出一个字符
  2. d————————————d是带符号的十进制数
  3. ld————————————十进制长整型
  4. u————————————无符号十进制数
  5. o————————————无符号的八进制数,不带前导0
  6. x或X——————————  无符号的十六进制数,不带前导0X
  7. f————————————单精度实型
  8. lf————————————双精度实型
  9. e或E——————————以指数形式输出实型数
  10. g或G——————————采用最小的宽度输出实型数
  11. s————————————输出字符串,对应的变量必须是地址
  12. p————————————输出内存变量的地址
  13. %————————————打印一个%

5、调用printf的注意事项:

1)格式说明与输出项从左到右,类型必须一一对应,若类型不匹配,系统不会给错误提示。

2)格式说明与输出项个数相同,若不同:格式说明多,输出不定值;输出项多,无用。

3)除格式说明外,其它合法字符“原样照印”。

4)如需输出“%”,则用两个连续的“%”来输出。

5)尽量不要在输出语句中改变变量的值。

输入函数(scanf)

1、作用:scanf函数的作用是在终端设备上输入数据。

2、scanf函数的一般调用形式:

1)scanf(“格式控制”,输出项表);

例:scanf("%d%d",&a,&b);    &求地址运算符----------&不可或缺

2)格式说明:

  1. 格式控制串的作用是指定输入时的数据转换格式;即格式转换说明。
  2. 格式转换说明符是由“%”开始,其后是格式描述符。
  3. 输入项表中的各输入项用逗号隔开,各输入项只能是合法的地址表达式。

3、scanf函数中常用的格式字符:

  1. c————————————字符
  2. d————————————十进制数
  3. i—————————————输入整型数,可以是带前导0的八进制数,也可以是带0x的十六进制数
  4. o—————————————以八进制形式输入整型数,可以带前导0,也可以不带前导0X。
  5. x—————————————以十六进制形式输入整型数,可以带前导0X,也可以不带前导0X。
  6. u—————————————无符号十进制数。
  7. f(lf)————————————输入单精度(双精度)数。
  8. e或(le)——————————-与f(lf)含义相同。
  9. s————————————输出字符串

4、说明:

1)输入long整数时,在%和d之间必须加入“1”;输入double型时,在%和f之间也必须加“1”。

2)在格式控制中,格式说明的类型与输入项的类型,应该一一对应匹配。

3)在scanf函数中的格式字符前可用一个整数指定输入数据所占的宽度。但不可对实型数指定小数宽度。

4)在格式控制串中,格式说明符的个数应该与输入项的个数相同。若格式符个数少于输入项,scanf函数按格式符的数目结束输入,多余的输入项没有得到新的数据;若格符的个数多余输入项,scanf函数按输入项的数目结束输入,多余的格式符不起作用。

5)当输入的数据少于输入项时,程序等待输入,直到满足要求为止;当输入的数据多于输入项时,多余的数据并不消失,而是留做下一个输入操作的输入数据。

6)scanf函数在调用结束后将返回一个函数值,其值等于得到输入值的输入项的个数。

5、通过scanf函数从键盘输入数据:

1)当调用scanf函数从键盘输入数据时,最后一定要按下回车键,scanf函数才能接受键盘输入的数据。

2)输入数据的数值:

  1. 当从键盘输入数值数据时,输入的数值数据之间用间隔符隔开。例:<间隔符>10<间隔符>20<间隔符>30<CR>。
  2. 此处间隔符可以是空格符、制表符(Tab)、回车符。

3)跳过输入数据的方法:

可以在格式字符和%之间加上一个“*”,它的作用是跳过对应的输入数据。例:

int  a1,a2,a3;

scanf("%d*d%d%d",&a1,&a2,&a3);

当输入如下数据时:10  20  30  40<CR>

将把10赋给a1,跳过20,把30赋给a2,把40赋给a3。

4)在格式字符串中插入其它字符:

  1. 如果想在屏幕上输入字符串来提示,应该使用printf函数,如果在scanf的格式控制字符串中插入了其它字符,则在输入时要求按一一对应的位置原样输入这些字符。

例1:

int  a1,a2,a3;

scanf("Input a1,a2,a3:%d%d%d",&a1,&a2,&a3);

要求按以下形式进行输入:

Input  a1,a2,a3:10 20 30

因为这里的“Input  a1,a2,a3:”是用户输入的,字符的大小写,字符间的空格数必须和scanf的格式控制串中插入的字符串完全一致。

  • scanf("%d,%d,%d",&a1,&a2,&a3);

以下方法可正确读入:

10,20,30

10,  20,  30

以下数据不能正确读入,因为逗号没有紧跟在每个输入数据之后

10  ,20  ,30

  • 如果逗号不是紧跟在格式字符之后,如:

scan("%d , %d , %d",&a1,&a2,&a3);

则只要求在输入数据之间插入逗号即可,因此以上各种输入型式都能正确输入。

选择结构————if......else......和switch()语句

关系运算符和关系表达式

C语言中的逻辑值:

  • 关系表达式和逻辑表达式,其运算结果都会得到一个逻辑值。
  • C语言中,没有专门的“逻辑值”。而是用非零来表示“真”,用零来表示“假”,只要值是非零,无论是正数还是负数,都代表一个真值。

1、C语言提供了6种关系运算符,属双目运算符,自左向右的结合性(两字符间不可以有空格)

<小于  <=小于等于  >大于  >=大于等于  ==等于  !=不等于

关系运算符的优先级:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符

2、关系表达式及关系表达式的值

由关系运算符组成的表达式,称为关系表达式。关系运算符两边的运算对象可以是C语言中任意合法的表达式。

1)关系运算的结果是一个整数值:0或者1。用0代表“假”,非零代表“真”。

2)当关系运算符两边的值的类型不一致时:规律为将存储字节少的类型转换为存储字节多的类型。

3)如果x和y都是实型数,应当避免使用x==y这样的关系表达式,因为实型数在存储的时候可能是以指数的形式存储的,所以不可能精确相等,这将导致关系表达式x==y的值总是0。

逻辑运算符和逻辑表达式

1、C语言中提供了3种逻辑运算符

1)&& 逻辑“与”      只有两者都为真,其最后结果才为真

2)|| 逻辑“或”         只要其中有一个为真,其最后结果就为真

3)! 逻辑“非”       不是真就是假(如果!运算符的右边的值为真,则最后结果为假)

2、逻辑运算符中逻辑与和逻辑或是双目运算符,逻辑非是单目运算符,位于运算符对象的左侧。

3、优先级:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符

4、逻辑表达式:由逻辑运算符和逻辑对象组成的表达式称为逻辑表达式。

5、逻辑表达式的结果是0(假)或1(真)。

例:判断闰年的条件是符合下面两者之一即可:

  1. 能被4整除,但不能被100整除。
  2. 能被400整除。

可用一个逻辑表达式来表示:

(year%4==0&&year%!=0)||(year%400==0)

条件表达式构成的选择结构

1、条件运算符

条件运算符由两个运算符组成,他们是“?:”。这是C语言提供的唯一的三目运算符,即要求有三个运算对象。

2、条件表达式形式

表达式1?表达式2:表达式3

3、执行说明

表达式1为“非零”的时候执行表达式2的值,表达式1为“零”的时候执行表达式3的值。

4、条件运算符的优先级

条件运算符优先于复制运算符,但低于逻辑运算符、关系运算符和算数运算符。

5、条件运算符的结合方式是“自右向左”

例:a>b?a:c>d?c:d相当于a>b?a:(c>d?c:d)

如果a=1,b=2,c=3,d=4则条件表达式的值为4

6、条件表达式中,表达式1的类型可以与表达式2和表达式3的类型不同,如:x?‘a’:‘b’

循环结构

while语句和do-while语句的组成

基本概念:C语言中有三种可以构成循环的循环语句:while、do-while、for语句。

while语句和while语句构成的循环结构

while语句构成的循环也称“当”循环,即先进行判断,然后执行循环体。一般形式如下:

while(表达式)循环体

注:

1)while是C语言的关键字

2)表达式可以是C语言任意合法的表达式

3)循环体部分可以是一条简单语句或复合语句

注意:if和while的区别:

if后表达式为非0时,语句执行依次,while后表达式为非0时,语句重复执行。

do-while语句和用do-while语句构成的循环结构

1、do-while循环是先执行循环体,后判断表达式的“直到型”循环,形式如下:

do

循环体

while(表达式);

注:

1)do是关键字

2)循环体可以由一条简单的语句组成也可以是复合语句

3)while后面的表达式可以是任意合法的C语言表达式

4)while表达式后面的分号不能丢

2、do-while循环的执行过程

注意:

1)do-while语句总是先执行一次循环体,再求表达式的值。

2)与while语句相同,必须有能使while表达式为0的操作。

while和do-while循环的比较

当型循环:最少执行次数0

直到型循环:最少执行次数1

for语句和累加累乘算法

1、for语句和用for语句构成的循环结构。形式如下:

1)for(表达式1;表达式2;表达式3)循环体

注:

  • for是C语言的关键字
  • 每个表达式之间用分号隔开
  • 表达式可以是C语言任意合法的表达式
  • 循环体可以是一条简答的语句,也可以是复合语句。
  • 表达式3后面没有分号。

2)也可以写作

for(循环变量赋初值;循环条件;循环变量增值)循环体

3)改写成while语句。

表达式1;

while(表达式2)

{

  语句;

  表达式3;

}

2、说明

1)“表达式1”可省略,但分号不能省略,在for语句前为变量赋初值。

i=3;

for(;i<=100;i++)

  printf("%d",i);

2)“表达式2”省略后,则for语句将无限循环下去。

例:for(i=0; ;i++)

{

  sum=sum+i;

  if(i>=100)

  break;

}

3)“表达式3”可省略,但应把其放入循环体中,否则for循环无法正常结束。

for(i=1,s=0;i<=100;) {s=s+i;i++;}

4)只有“表达式2”时,完全等同于while语句。

i=1;sum=0;

for(;i<=100;)  {sum=sum+i;i++;}

i=1;sum=0;

while(i<=100) {sum=sum+i;i++;}

5)三个表达式全省略,无终止执行循环体,分号不能省略。

例:for(;;) {........}

i=1;s=0;

for(; ;)

{

  s=s+i;

  i++;

  if(i>100)

  break;

}

6)表达式1和表达式3可以是一个简单的表达式,也可以是一个逗号表达式,表达式1和表达式3也可以是与循环无关的任意表达式。

例:i=1;s=0;

for(p=0;i<=100;p=p+1)

{

  s+=i;

  i++;

}

i=1;s=0;p=0;

while(i<=1)

{

  s=s+i;

  i++;

  p++;

}

7)表达式可以是关系、逻辑、数值、字符表达式。

关系:for(i=0;i<100;i++) {......}

逻辑:for(i=3,j=4;i&&j;i--,j--) {......}

数值:for(i=3;5;i++) {......}

字符:for(i=4;'a';i++) {,,,,,,}

8)把循环体内容放到表达式3,循环体为空语句,作用一样。

例:for(i=1,s=0;i<=100;s+=i,i++) ;     空语句的分号不能省略

  for(i=1,s=0;i<=100;i++) s+=i;

三个循环的区别和特点

1、while语句和do-while语句的区别

1)while当型循环:先判断,后执行。  do-while直到型循环:先执行,后判断。

2)while最少执行次数0.   do-while最少执行次数1。

2、for语句与while、do-while语句的区别

1)while和do-while语句在循环体之前赋初值。  for在表达式(也相当于的循环体前赋初值)

2)while和do-while使循环趋于结束的语句位于循环体内,而for循环位于表达式3(也可位于循环体内)。

3、共同点

1)三个循环体解决同一问题时条件相同。

2)三个循环都必须有使循环趋于结束的语句,否则为死循环。

循环嵌套的实例

1、素数问题

1)素数的概念:除了1和本身之外不能被任何数整除。

2)素数的判断:以下三个方法都可以(x为输入要判断的数)

  1. x从2到x-1都不能被整除。
  2. x从2到x/2都不能被整除。
  3. x从2到x的平方根都不能被整除。

3)例题:

例1:判断x是否为素数

程序如下:

#include<stdio.h>
int main(void)
{
int i,x;
scanf("%d",&x);
for(i=2;i<x;i++)
{
if(x%i==0)
break;

}

if(i>=x) printf("Yes!\n");
else
printf("No!\n");

return 0;
}

例2:输出所有的三为素数

程序如下:

#include<stdio.h>
int main(void)
{
int i,x,n=0;

for(x=100;x<=999;x++) //遍历100-999之间的每个数字
{
for(i=2;i<x;i++)
if(x%i==0) break;

if(i>=x)
{
printf("%d ",x);
n++;
if(n%10==0) printf("\n"); //用n来计算是素数的个数,当每一行有10个素数输出时,就换行
}
}

return 0;
}

例3:输出大于m的最小的k个素数

#include<stdio.h>
int main(void)
{
int x,i,n,k,m;

scanf("%d%d",&m,&k);
n=0;

for(x=m+1;n<k;x++)
{
for(i=2;i<x;i++)
if(x%i==0) break;
if(i>=x)
{
printf("%d ",x);
n++;
}
}

return 0;
}

例4:输出小于m的最大的k个素数

#include<stdio.h>
int main(void)
{
int x,i,n,k,m;

scanf("%d%d",&m,&k);
n=0;

for(x=m-1;n<k;x--)
{
for(i=2;i<x;i++)
if(x%i==0) break;
if(i>=x)
{
printf("%d ",x);
n++;
}
}

return 0;
}

2、求斐波那契数列的前40项

1、1、2、3、5、8、13、21、34、55、89...........

程序如下:

#include<stdio.h>
main()
{
int a,b,c,i,n;
a=1;
b=1;
n=0;

for(i=3;i<=40;i++)
{
c=a+b;
a=b;
b=c;
printf("%d ",c);
n++;
if(n%5==0)
printf("\n");
}

return 0;

}

3、阶乘:1*2*3*4*5*............*n

程序如下:

#include<stdio.h>
int main(void)
{
int i,n;
double s;
i=1;
s=1;

scanf("%d",&n);
while(i<=n)
{
s=s*i;
i++;
}
printf("%d!=%lf\n",n,s);

return 0;
}

4、编程1+1/2+1/6+1/12+......+1/n(n+1)

程序如下:

#include<stdio.h>
int main(void)
{
int i,n;
double t,s;
s=1;

scanf("%d",&n);
for(i=1;i<=n;i++)
{
t=1.0/(i*(i+1));  //注意:必须是1.0  否则求出的t是int型,即在本题中t永远是“0”
s=s+t;
}
printf("%lf\n",s);

return 0;
}

5、编写程序:求1-3+5-7+......-99+101

程序如下:

#include<stdio.h>
int main(void)
{
int s,i,t;
s=0;
t=1;
for(i=1;i<=101;i+=2)
{
s+=i*t;
t=-t;        //注意:改变符号
}
printf("s=%d\n",s);

return 0;
}

6、图形问题

1)分析:凡是图形问题都是变相考数学——————判断依据是对图形的行列分别进行控制,即用循环语句来实现。

2)列题:

例1:

*

**

***

.............(正的三角形行列一一对应)

程序如下:

#include<stdio.h>
int main(void)
{
int i,j,n;

scanf("%d",&n);
for(i=1;i<=n;i++)    //i控制行数
{
for(j=1;j<=i;j++)    //j控制列数
{
printf("*");
}

printf("\n");
}

return 0;
}

例2:

........(倒着的行列不一一对应,所以应采用其他的方法)当前的列数=总行数+1-当前行数

***

**

*

程序如下:

#include<stdio.h>
int main(void)
{
int i,j,n;

scanf("%d",&n); //n代表行数
for(i=1;i<=n;i++)
{
for(j=1;j<=n+1-i;j++)
{
printf("*");
}

printf("\n");
}

return 0;
}

例3:

*

***

*****

*******

...........(当前的列数=当前的行数*2-1)

程序如下:

#include<stdio.h>
int main(void)
{
int i,j,n;

scanf("%d",&n); //n代表行数
printf("\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n-i;j++)
printf(" "); //该for循环代表对应列数输出的空格
for(j=1;j<=i*2-1;j++)
printf("*"); //该for循环代表对应列数输出的*,并且j<=i*2-1代表列数输的*与输入行数的关系
printf("\n");
}

return 0;
}

例4:

..........(当前的列数=总行数*2-(当前的行数*2-1)

*******

*****

***

*

程序如下:

#include<stdio.h>
int main(void)
{
int i,j,n;
scanf("%d",&n);
printf("\n");

for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
printf(" ");
for(j=1;j<=n*2-(i*2-1);j++)
printf("*");

printf("\n");
}

return 0;
}

例5:输出菱形

程序如下:

#include<stdio.h>
int main(void)
{
int i,j,n;
scanf("%d",&n);
printf("\n");

for(i=1;i<=(n+1)/2;i++)
{
for(j=1;j<=((n+1)/2)+1-i;j++)
printf(" ");
for(j=1;j<=2*i-1;j++)
printf("*");

printf("\n");
}
for(i=1;i<=n/2;i++)
{
for(j=1;j<=i+1;j++)
printf(" ");
for(j=1;j<=((n/2)*2-(i*2-1));j++)
printf("*");

printf("\n");
}

return 0;
}

break语句和continue语句的使用方法

1、break语句只能在循环体内和switch语句内容使用,作用只是跳出该switch语句体或本层循环体。

2、continue语句其作用是为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。

3、区别:continue语句只是结束本次循环,而不是终止整个循环的执行,而break语句则是结束整个循环过程,不再判断执行循环条件是否成立。

字符型数据

字符常量和字符型变量

1、C语言中,一个字符常量代表ASCII字符集中的一个字符,在程序中有单引号把一个字符括起来作为字符常量。(一个字符对应一个ASCII码,ASCII码相当于学号)。

2、说明:

1)单引号中大、小写字母代表不同的字符常量。

2)‘ ’也是一个字符常量,但不能写成两个连续的单引号。

3)字符常量只能包含一个字符。

4)字符常量在内存中占一个字节,作为整型常量来处理,对红的整数值就是ASCII字符集中该符号的序号。

3、转义字符常量

1)转义字符常量只代表一个字符。

2)反斜线后的八进制数可不用0开头,十六进制可由小写x开头,但不允许大写X或0x开头。

3)注意:转义字符在输出的时候不会把原意输出,会输出该转义字符相对应的功能。

字符串常量

1、字符常量是由双引号括起来的一串字符。

2、在C语言中,系统在每个字符串的最后自动加入一个字符' \0'作为字符串的结束标志,' \0'占一个字节,在写字符串时不必加,系统会自动添加。

3、两个连续的双引号:""也是字符串常量,称作“空串”,但要占一个字节存放' \0'。

4、各类数值型数据之间的混合运算。

1)“=”代表等价的意思。

2)运算作用

  • 大小写字母转换:(即大写字母加32可以化为相对应的小写字母。小写字母减32可以化为相对应的大写字母)

' A ' + 32=65+32=97=’ a ‘

’ b ‘ - 32=98-32=66 =’ B ‘

  • 数字字符和整数之间的相互转换:(只要把字符型的数字字符减去字符字符0就可以化为相对应的数字。同理只要把数字加字符0就可以转化为相对应的数字字符)

’9‘ - ’0‘=57-48=9

9 + ’0‘=9+48=57=’9‘

  • 关系运算和逻辑运算

’a‘ < ’b‘  ’a‘&&’b‘

3)运算方法

在整型、实型、字符型数据混合运算时,字符型和整型可以通用,它们之间可以转换成相同类型。

字符变量

1、字符变量用关键字char定义,在定义同时赋初值。

例:char  ch1=‘a’ , ch2='b';

2、字符变量在内存中占一个字节,其中只能存放一个字符,把字符放入该变量后,字符变量的值就是该字符所对应的ASCII代码值。

scanf()函数

1、当用%c格式输入字符,无需间隔符,在这里,回车、空格、Tab、转义字符都是有效字符。以下例外:

scanf("%c    %c    %c",&c1,&c2,&c3);

此时,空格、Tab、回车都作为间隔符不能被读入。

2、使用putchar和getchar函数时,必须用包含头文件“stdio.h”的命令行

3、putchar函数的作用是向终端输出一个字符(即每次只能输出一个字符)

4、getchar函数的作用是从终端输入一个字符

函数

函数的定义和返回值

注:函数有两类(一是系统定义好的,为库函数,而是我们自己定义的,即自定义函数)

1、一个C语言程序无论包含了多少函数,C程序总是从main函数开始执行。

2、调用C语言标准库函数时要求的include命令:

1)用户在源程序include命令中应该包含头文件:例:#include<stdio.h>

include命令必须用#开头,系统提供的头文件以.h作为文件的后缀,文件名用" "或<>括起来。

2)include命令不是C语句,因此不能在最后加分号。

3、标准库函数的调用:

1)一般调用形式为:函数名(参数表)

例:scanf("%d",&a);    ch=getchar();

2)库函数的调用可以以两种形式出现:

  1. 出现在表达式中  例:y=pow(x,2.5) + 3;
  2. 作为独立语句完成某种操作:  例:printf("******\n");

4、常见的库函数:

1)数学函数:#include<math.h>

2)字符函数:#include<ctype.h>

3)字符串函数:#include<string.h>

5、函数定义的语法

1)C语言函数定义的一般形式如下:

函数返回值的类型名    函数名(类型名  形式参数1,  类型名  形式参数2,......)  //函数首部

{                               //函数体                                                               

  说明部分

  语句部分

}

2)函数名和形式参数都是由用户命名的标识符。在同一程序中,函数名必须唯一;形式参数名只要同一函数中唯一即可,可以与其它函数中的变量同名。

3)C语言规定,不能在一个函数的内部再定义函数。

4)若在函数的首部省略了函数返回值的类型名,函数首部写成:

函数名(类型名  形式参数1,  类型名  形式参数2,.....)

则C语言默认返回值类型为int类型。

5)函数体中,除形参外,用到的其它变量必须在说明部分进行定义,这些变量(包括形参),只在函数被调用时才临时开辟存储单元,当推出函数时,这些临时开辟的存储单元全部被释放掉,因此,这种变量只在函数体内部其作用,与其它函数中的变量互不相关,它们可以和其它函数中的变量同名。

6、函数的返回值

1)函数的值通过return语句返回,return语句的形式如下;

  • return  表达式;
  • return(表达式);
  • return;

2)说明:

  1. return语句中的表达式的值就是所求的函数值,此表达式值的类型必须与函数首部所说明的类型一致。若类型不一致,则以函数值的类型为标准,由系统自动进行转换。
  2. 当程序执行到return语句时,程序的流程式就返回到调用该函数的地方,

    

 

 

编程语言——C----细节的更多相关文章

  1. C#中的问号

    本人转载自: ①http://msdn.microsoft.com/zh-cn/practices/dd391752.aspx ②http://jhxk.iteye.com/blog/439888 在 ...

  2. 在C#程序中实现插件架构

    阅读提示:这篇文章将讲述如何利用C#奇妙的特性,实现插件架构,用插件(plug-ins)机制建立可扩展的解决方案. 在.NET框架下的C#语言,和其他.NET语言一样提供了很多强大的特性和机制.其中一 ...

  3. 如何在Android上编写高效的Java代码

    转自:http://www.ituring.com.cn/article/177180 作者/ Erik Hellman Factor10咨询公司资深移动开发顾问,曾任索尼公司Android团队首席架 ...

  4. 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 2 章 答案

    判断对错1.编写程序的好方法是立即键入一些代码,然后调试它,直到它工作.2.可以在不使用编程语言的情况下编写算法.3.程序在写入和调试后不再需要修改.4.Python 标识符必须以字母或下划线开头.5 ...

  5. 2017 Summary

    几门课 基础电路与电子学 知道了一些二极管三极管的基本基本很基本的那种物理知识吧,但是毕竟我是从电信转专业过来的,所以说我内心就是逃避模电这样的课的.上课基本没听,后面只是死命复习了一周,考的还可以. ...

  6. Vue.js 和 MVVM 小细节

    MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...

  7. Lyft押重注于苹果编程语言Swift

    Lyft押重注于苹果编程语言Swift 1年后获得丰厚回报BI中文站 8月22日报道 一年多以前,打车应用Lyft做出重大决定,决心押重注于苹果开发的编程语言Swift,用这种编程语言重写其所有iPh ...

  8. Scalaz(18)- Monad: ReaderWriterState-可以是一种简单的编程语言

    说道FP,我们马上会联想到Monad.我们说过Monad的代表函数flatMap可以把两个运算F[A],F[B]连续起来,这样就可以从程序的意义上形成一种串型的流程(workflow).更直白的讲法是 ...

  9. php课程---Json格式规范需要注意的小细节

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...

  10. atitit.编程语言 程序语言 的 工具性 和 材料性 双重性 and 语言无关性 本质

    atitit.编程语言 程序语言 的 工具性 和 材料性 双重性 and 语言无关性 本质 #---语言的 工具和材料双重性 有的人说语言是个工具,有的人说语言是个材料..实际上语言同时属于两个属性. ...

随机推荐

  1. JavaScript设计模式-15.适配器模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. python pip 安装OpenCV

    cmd pip install opencv-contrib-python -i https://pypi.mirrors.ustc.edu.cn/simple/

  3. C 扩展库 - mysql API general outline

    Application programs should use this general outline for interacting with MySQL Initialize the MySQL ...

  4. JVM的类加载时机

    类加载过程中每个步骤的顺序 我们已经知道,类加载的过程包括:加载.连接.初始化,连接又分为:验证.准备.解析,所以说类加载一共分为5步:加载.验证.准备.解析.初始化. 其中加载.验证.准备.初始化的 ...

  5. [中英对照]The sysfs Filesystem | sysfs文件系统

    The sysfs Filesystem | sysfs文件系统 Abstract | 摘要 sysfs is a feature of the Linux 2.6 kernel that allow ...

  6. fgets()函数读取键盘,去掉换行符或丢弃多余的字符

    在上一遍随笔中,我们知道可以用fgets()函数来代替不安全的gets()函数.fgets函数中的第二个参数限制了读取的个数. 上篇文章也提到,fgets是会读取回车换行符的.有时候我们并不希望在字符 ...

  7. 利用keepalived构建高可用MySQL-HA

    关于MySQL-HA,目前有多种解决方案,比如heartbeat.drbd.mmm.共享存储,但是它们各有优缺点.heartbeat.drbd配置较为复杂,需要自己写脚本才能实现MySQL自动切换,对 ...

  8. cordova程序加载pdf文件的2种方法(ios/android)

    前言 公司目前的前端架构是微信端由vue全家桶负责h5网站的单页应用,android端和ios端则选择cordova打包成apk和app.其中,有一个业务逻辑是点击某个链接进入pdf的展示,h5的方案 ...

  9. web弹出对话框

    Page.ClientScript.RegisterStartupScript(this.GetType(), "", "<script>alert('请输入 ...

  10. [转] 如何让代码可测试化(C#)

    让代码可测试化 本篇介绍如何把我们目前最常见的代码转换为可以单元测试的代码,针对业务逻辑层来实现可测试性,我们以银行转账为例,通常代码如下: public class TransferControll ...