《C语言程序设计》·第3章·最简单的C程序设计 您所在的位置:网站首页 c语言输入操作数运算符操作数的四则运算表达式 《C语言程序设计》·第3章·最简单的C程序设计

《C语言程序设计》·第3章·最简单的C程序设计

2023-03-27 23:25| 来源: 网络整理| 查看: 265

3.1:顺序程序设计举例 ——例3.1有人用温度计测量出用华氏法表示的温度(如64°F),今要求把它转换为以摄氏法表示的温度(如17.8℃)。 #include int main () { float f,c; f=64.0; c=(5.0/9)*(f-32); printf("f=%f\nc=%f\n",f,c); return 0; }——例3.2计算存款利息。有1000元,想存一年。有3种方法可选:(1)活期,年利率为r1;(2)一年期定期,年利率为r2;(3)存两次半年定期,年利率为r3。请分别计算出一年后按3种方法所得到的本息和。

画出N-S流程图,见图3.2。

#include int main() { float p0=1000,rl=0.0036,r2=0.0225,r3=0.0198,p1,p2,p3; p1=p0*(1+rl); p2=p0*(1+r2); p3=p0*(1+r3/2)*(1+r3/2); printf("pl=%f\np2=%f\np3=%f\n",p1,p2,p3); return 0; }3.2:数据的表现形式及其运算3.2.1:常量和变量

在计算机高级语言中,数据有两种表现形式:常量和变量

——1、常量

在程序运行过程中,其值不能被改变的量称为常量。数值常量就是数学中的常数。

常用的常量有以下几类:

(1)整型常量(2)实型常量(3)字符常量(4)字符串常量(5)符号常量(1)整型常量

如1000,12345,0,-345等都是整型常量。

(2)实型常量

有两种表示形式:

十进制小数形式

由数字和小数点组成。如123.456,0.345,-56.79,0.0,12.0等。

指数形式

如12.34e3(代表 12.34×10^{3} ),-346.87e-25(代表 -346.87×10^{-25} )等。由于在计算机输入或输出时无法表示上角或下角,故规定以字母e或E代表以10为底的指数。但应注意:e或E之前必须有数字,且e或E后面必须为整数。如不能写成e4,12e2.5。

(3)字符常量

有两种形式的字符常量:

①普通字符

单撇号括起来的一个字符,如:'a',Z','3','?','#'。不能写成'ab'或 '12'。请注意:单撇号只是界限符,字符常量只能是一个字符,不包括单撇号。'a'和'A'是不同的字符常量。

字符常量存储在计算机存储单元中时,并不是存储字符(如a,z,#等)本身,而是以其代码(一般采用ASCⅡ代码)存储的,例如字符'a'的ASCII代码是97,因此,在存储单元中存放的是97(以二进制形式存放)。

补充十进制与十六进制的转换②转义字符

除了以上形式的字符常量外,C语言还允许用一种特殊形式的字符常量,就是以字符“\”开头的字符序列。例如,前面已经遇到过的,在printf函数中的'\n'代表一个“换行”符。这是一种在屏幕上无法显示的“控制字符”,在程序中也无法用一个一般形式的字符来表示,只能采用这样的特殊形式来表示。

常用的以“\”开头的特殊字符见表3.1。

(4)字符串常量

如”boy","123"等,用双撇号把若干个字符括起来,字符串常量是双撇号中的全部字符(但不包括双撇号本身)。注意不能错写成'CHINA','boy','123'。单撇号内只能包含一个字符,双撇号内可以包含一个字符串。

(5)符号常量

用#define指令,指定用一个符号名称代表一个常量。如:

#define PI 3.1416 //注意行末没有分号

经过以上的指定后,本文件中从此行开始所有的PI都代表3.1416。在对程序进行编译前,预处理器先对PI进行处理,把所有PI全部置换为3.1416。这种用一个符号名代表一个常量的,称为符号常量。在预编译后,符号常量已全部变成字面常量(3.1416)。

——2、变量

变量代表一个有名字的、具有特定属性的一个存储单元。它用来存放数据,也就是存放变量的值。在程序运行期间,变量的值是可以改变的。

变量必须先定义,后使用。在定义时指定该变量的名字和类型,以便被引用。

请注意区分变量名和变量值这两个不同的概念,图3.3中a是变量名,3是变量a的值,即存放在变量a的内存单元中的数据。变量名实际上是以一个名字代表的一个存储地址。在对程序编译连接时由编译系统给每一个变量名分配 对应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据

——3、常变量

C99允许使用常变量,方法是在定义变量时,前面加一个关键字const,如:

const int a=3;

定义a为一个整型变量,指定其值为3,而且在变量存在期间其值不能改变

常变量与常量的异同是:常变量具有变量的基本属性:有类型,占存储单元,只是不允许改变其值。可以说,常变量是有名字的不变量,而常量是没有名字的不变量。有名字就便于在程序中被引用。

请思考:常变量与符号常量有什么不同?如:

#define Pi 3.1415926 //定义符号常量

const float pi=3.1415926; //定义常变量

符号常量Pi和常变量pi都代表3.1415926,在程序中都能使用。但二者性质不同:定义符号常量用#define指令,它是预编译指令,它只是用符号常量代表一个字符串,在预编译时仅进行字符替换,在预编译后,符号常量就不存在了(全置换成3.1415926了),对符号常量的名字是不分配存储单元的。而常变量要占用存储单元,有变量值,只是该值不改变而已。

从使用的角度看,常变量具有符号常量的优点,而且使用更方便。有了常变量以后,可以不必多用符号常量

——4、标识符

在计算机高级语言中,用来对变量、符号常量名、函数、数组、类型等命名的有效字符序列统称为标识符(identifier)。简单地说,标识符就是一个对象的名字

C语言规定标识符只能由字母、数字和下画线3种字符组成,且第1个字符必须为字母或下画线

注意

编译系统认为大写字母和小写字母是两个不同的字符。因此,sum和SUM是两个不同的变量名,同样,Class和class也是两个不同的变量名。一般而言,变量名用小写字母表示,与人们日常习惯一致,以提高可读性。

3.2.2:数据类型

在例3.1和例3.2中可以看到:在定义变量时需要指定变量的类型。如例3.1中变量f和c被定义为单精度(float)型。C语言要求在定义所有的变量时都要指定变量的类型。 常量也是区分类型的。

为什么在用计算机运算时要指定数据的类型呢?因为在计算机中,数据是存放在存储单元中的,而存储单元又是由有限的字节构成的,因此每一个存储单元所能存放的数据也是有限的,无法存放“无穷大”的数,也不能存放循环小数。

例如1/3的值是0.33333333…(循环小数),用C程序计算和输出1/3: #include int main() { printf("%f",1.0/3.0); }

得到的结果是0.333333,只能得到6位小数,而不是无穷位的小数。

所谓类型,就是对数据分配存储单元的安排,包括存储单元的长度(占多少字节)以及数据的存储形式不同的类型分配不同的长度和存储形式。 C语言允许使用的类型见图3.4。

不同类型的数据在内存中占用的存储单元长度是不同的,例如,Visual C++为char型 (字符型)数据分配1个字节,为int型(基本整型)数据分配4个字节,存储不同类型数据的方法也是不同的。

3.2.3:整型数据 ——1、整型数据的分类

本节介绍最基本的整型类型。

(1)基本整型(int型)

编译系统分配给int型数据2个字节或4个字节(由具体的C编译系统自行决定)。如Turbo C2.0为每一个整型数据分配2个字节(16个二进位),而Visual C++为每一个整型数据分配4个字节(32位)。

在存储单元中的存储方式是:用整数的补码(complement)形式存放。一个正数的补码是此数的二进制形式,如5的二进制形式是101,如果用两个字节存放一个整数,则在存储单元中数据形式如图3.5所示。

如果是一个负数,则应先求出负数的补码。求负数的补码的方法是:先将此数的绝对值写成二进制形式,然后对其所有二进位按位取反,再加1。如-5的补码见图3.6。

在存放整数的存储单元中,最左面一位是用来表示符号的。如果该位为0,表示数值为正;如果该位为1,表示数值为负。

(2)短整型(short int)

类型名为short int或short。如用Visual C++,编译系统分配给int数据4个字节,短整型2个字节

(3)长整型(long int)

类型名为long int或long。Visual C++对一个long型数据分配4个字节(即32位)

(4)双长整型(long long int)

类型名为long long int或long long,一般分配8个字节。这是C99新增的类型,但许多C编译系统尚未实现。

——2、整型变量的符号属性

以上介绍的几种类型,变量值在存储单元中都是以补码形式存储的,存储单元中的第1个二进位制代表符号。整型变量的值的范围包括负数到正数(见表3.2)。

在实际应用中,有的数据的范围常常只有正值(如学号、年龄、库存量、存款额等)。为了充分利用变量的值的范围,可以将变量定义为“无符号”类型。可以在类型符号前面加上修饰符unsigned,表示指定该变量是“无符号整数”类型。如果加上修饰符signed,则是“有符号类型”。

因此,在以上4种整型数据的基础上可以扩展为以下8种整型数据:

如果既未指定为signed也未指定为unsigned的,默认为“有符号类型”。如signed int a 和int a等价。

有符号整型数据存储单元中最高位代表数值的符号(0为正,1为负)。如果指定unsigned(为无符号)型,存储单元中全部二进位(b)都用作存放数值本身,而没有符号。无符号型变量只能存放不带符号的整数,如123,4687等,而不能存放负数,如-123,-3。

由于左面最高位不再用来表示符号,而用来表示数值,因此无符号整型变量中可以存放的正数的范围比一般整型变量中正数的范围扩大一倍。

3.2.4:字符型数据

由于字符是按其代码(整数)形式存储的,因此C99把字符型数据作为整数类型的一种。但是,字符型数据在使用上有自己的特点,因此把它单独列为一节来介绍。

——1、字符与字符代码

字符与字符代码并不是任意写一个字符,程序都能识别的。例如代表圆周率的π在程序中是不能识别的,只能使用系统的字符集中的字符,目前大多数系统采用ASCⅡ字符集。 各种字符集(包括ASCⅡ字符集)的基本集都包括了127个字符。其中包括:

前已说明,字符是以整数形式(字符的ASCI代码)存放在内存单元中的。例如:

可以看到,以上字符的ASCII代码最多用7个二进位就可以表示。所有127个字符都可以用7个二进位表示(ASCⅡ代码为127时,二进制形式为1111111,7位全1)。所以在C语言中,指定用一个字节(8位)存储一个字符(所有系统都不例外)。此时,字节中的第1位置为0。

如小写字母'a'在内存中的存储情况见图3.9('a'ASCⅡ代码是十进制数97,二进制数为01100001)。

——2、字符变量

字符变量是用类型符char定义字符变量。char是英文character(字符)的缩写,见名即可知义。如:

char c='?';

定义c为字符型变量并使初值为字符'?'。'?'的ASCⅡ代码是63,系统把整数63赋给变量c。

c是字符变量,实质上是一个字节的整型变量,由于它常用来存放字符,所以称为字符变量。可以把0~127之间的整数赋给一个字符变量。

输出字符变量的值时,可以选择以十进制整数形式输出,或以字符形式输出。如:

#include int main() { char c='?'; printf("%d %c\n",c,c); }

前面介绍了整型变量可以用signed和unsigned修饰符表示符号属性。字符类型也属于整型,也可以用signed和unsigned修饰符

字符型数据的存储空间和值的范围见表3.3。

3.2.5:浮点型数据

浮点型数据是用来表示具有小数点的实数的。为什么在C中把实数称为浮点数呢?

在C语言中,实数是以指数形式存放在存储单元中的。一个实数表示为指数可以有不止一种形式,如3.14159可以表示为 3.14159×10^{0} , 0.314159×10^{1} , 0.0314159×10^{2} 等,它们代表同一个值。可以看到:小数点的位置是可以在314159几个数字之间、之前或之后(加0)浮动的,只要在小数点位置浮动的同时改变指数的值,就可 以保证它的值不会改变。由于小数点位置可以浮动,所以实数的指数形式称为浮点数

浮点数类型包括

floatdoublelong double单精度浮点型双精度浮点型长双精度浮点型——1、float型(单精度浮点型)

编译系统为每一个float型变量分配4个字节,数值以规范化的二进制数指数形式存放在存储单元中。

在存储时,系统将实型数据分成小数部分和指数部分两个部分,分别存放。小数部分的小数点前面的数为0。如3.14159在内存中的存放形式可以用图3.11表示。

图3.11是用十进制数来示意的,实际上在计算机中是用二进制数来表示小数部分以及用2的幂次来表示指数部分的。由于用二进制形式表示一个实数以及存储单元的长度是有限的,因此不可能得到完全精确的值,只能存储成有限的精确度。小数部分占的位(bit)数愈多,数的有效数字愈多,精度也就愈高。指数部分占的位数愈多,则能表示的数值范围愈大

float型数据能得到6位有效数字。

——2、double型(双精度浮点型)

为了扩大能表示的数值范围,用8个字节存储一个double型数据,可以得到15位有效数字。

为了提高运算精度,在C语言中进行浮点数的算术运算时,将float型数据都自动转换为double型,然后进行运算。

——3、long double型(长双精度)型

不同的编译系统对long double型的处理方法不同,Turbo C对long double型分配16个字节。而Visual C++则对long double型和double型一样处理,分配8个字节。请读者在使用不同的编译系统时注意其差别。

表3.4列出实型数据的有关情况(Visual C++环境下)。

3.2.6:怎样确定常量的类型

在C语言中,不仅变量有类型,常量也有类型。为什么要把常量分为不同的类型呢? 以及我们怎样来确定常量的类型呢?很简单,我们从常量的表示形式就可以判断它对应的类型。

对于字符常量,只要看到由单撇号括起来的单个字符或转义字符就可以知道它是字符常量。

对于数值常量按以下规律判断:

——1、整型常量

不带小数点的数值是整型常量,但应注意其有效范围。在一个整数的末尾加大写字母L或小写字母l,表示它是长整型(long int)。但在Visual C++中由于对int和long int型数据都分配4个字节,因此没有必要用long int型。

——2、浮点型常量

凡以小数形式或指数形式出现的实数均是浮点型常量,在内存中都以指数形式存储。如,10是整型常量,10.0是浮点型常量。那么对浮点型常量是按单精度处理还是按双精度处理呢?

我们前面介绍了,C编译系统把浮点型常量都按双精度处理,分配8个字节

3.3:运算符和表达式

几乎每一个程序都需要进行运算,对数据进行加工处理,否则程序就没有意义了。要进行运算,就需规定可以使用的运算符。C语言的运算符范围很宽,把除了控制语句和输入输出以外几乎所有的基本操作都作为运算符处理。

3.3.1:C运算符

C语言提供了以下运算符:

本章先介绍算术运算符和赋值运算符,其余的在以后各章中陆续介绍。

3.3.2:基本的算术运算符

最常用的算术运算符见表3.5。

说明 由于键盘无×号,运算符×以代替;由于键盘无÷号,运算符÷以/代替。两个实数相除的结果是双精度实数,两个整数相除的结果为整数,如5/3的结果值为1,舍去小数部分;%算符要求参加运算的运算对象(即操作数)为整数,结果也是整数。如8%3的结果为2;除%外的运算符的操作数都可以是任何算术类型。 3.3.3:自增(++)、自减(--)运算符

自增(++)、自减(--)运算符的作用是使变量的值加1或减1,例如:

粗略地看,++i和i++的作用相当于i=i+1。但++i和i++的不同之处在于:++i是先执行i=i+1,再使用i的值;而i++是先使用i的值,再执行i=i+1。如果i的原值等于3,请分析下面的赋值语句:

自增(减)运算符常用于循环语句中,使循环变量自动加1;也用于指针变量,使指针指向下一个地址。这些将在以后的章节中介绍。

有些专业人员喜欢在使用++或--运算符时采用一些技巧,但是注往会出现意想不到的副作用,例如i+++j,是理解为(i++)+j还是i+(++j)呢?程序应当清晰易读,不致引起歧义。建议谨慎使用++和--运算符,只用最简单的形式,即i++,i--。而且把它们作为单独的表达式,而不要在一个复杂的表达式中使用++或--运算符。

3.3.4:算术表达式和运算符的优先级与结合性

用算术运算符和括号将运算对象(也称操作数)连接起来的、符合C语法规则的式子称为C算术表达式。运算对象包括常量、变量、函数等。例如,下面是一个合法的C算术表达式:

a*b/c-1.5+'a'

C语言规定了运算符的优先级(例如先乘除后加减),还规定了运算符的结合性。在表达式求值时,先按运算符的优先级别顺序执行,如表达式a-b*c,b的左侧为减号,右侧为乘号,而乘号优先级高于减号,因此,相当于a-(b*c)。

如果在一个运算对象两侧的运算符的优先级别相同,如a-b+c,则按规定的“结合方向”处理。C语言规定了各种运算符的结合方向(结合性),算术运算符的结合方向都是“自左至右”,即先左后右,因此b先与减号结合,执行a—b的运算,然后再执行加c的运算。

“自左至右的结合方向”又称“左结合性”,即运算对象先与左面的运算符结合。以后可以看到有些运算符的结合方向为“自右至左”,即右结合性(例如,赋值运算符,若有a=b=c,按从右到左顺序,先把变量c的值赋给变量b,然后把变量b的值赋给变量a)。

注意,不必死记,只要知道:算术运算符是自左至右(左结合性),赋值运算符是自右至左(右结合性),其他复杂的遇到时查一下即可

3.3.5:不同类型数据间的混合运算

在程序中经常会遇到不同类型的数据进行运算,如5*4.5。如果一个运算符两侧的数据类型不同,则先自动进行类型转换,使二者成为同一种类型,然后进行运算

整型、实型、字符型数据间可以进行混合运算。规律为:

(1)+、-、*、/运算的两个数中有一个数为float或double型,结果是double型,因为系统将所有float型数据都先转换为double型,然后进行运算。

(2)如果int型与float或double型数据进行运算,先把int型和float型数据转换为double型,然后进行运算,结果是double型。

(3)字符(char)型数据与整型数据进行运算,就是把字符的ASCⅡ代码与整型数据进行运算。如:12+'A',由于字符A的ASCⅡ代码是65,相当于12+65,等于77。如果字符型数据与实型数据进行运算,则将字符的ASCⅡ代码转换为double型数据,然后进行运算

以上的转换是编译系统自动完成的,用户不必过问。

——例3.3给定一个大写字母,要求用小写字母输出。

解题思路:前已介绍,字符数据以ASCⅡ码存储在内存中,形式与整数的存储形式相同。所以字符型数据和其他算术型数据之间可以互相赋值和运算。

要进行大小写字母之间的转换,首先要明白字母的大写形式与小写形式之间如何转换——同一个字母,用小写表示的字符的ASCII代码比用大写表示的字符的ASCI代码大32。例如字符'a'的ASCII代码为97,而'A'的ASCII代码为65。将'A'的ASCI代码加32,就能得到'a'的ASCⅡI代码。有此思路就可以编写程序了。

#include int main() { char c1,c2; c1='A'; c2=c1+32; printf("%c\n",c2); printf("%d\n",c2); return 0; }3.3.6:强制类型转换运算符

可以利用强制类型转换运算符将一个表达式转换成所需类型。例如:

其一般形式为——(类型名)(表达式)

注意,表达式应该用括号括起来。如果写成(int)x+y ,则只将x转换成整型,然后与y相加。

需要说明的是,在强制类型转换时,得到一个所需类型的中间数据,而原来变量的类型未发生变化。例如:a=(int)x 如果已定义x为float型变量,a为整型变量,进行强制类型运算(int)x后得到一个int类型的临时值,它的值等于x的整数部分,把它赋给a,注意x的值和类型都未变化,仍为float型。该临时值在赋值后就不再存在了。

从上可知,有两种类型转换。一种是在运算时不必用户干预,系统自动进行的类型转换,如3+6.5。另一种是强制类型转换。当自动类型转换不能实现目的时,可以用强制类型转换。例如在函数调用时,有时为了使实参与形参类型一致,可以用强制类型转换运算符得到一个所需类型的参数。

3.4:C语句 3.4.1:C语句的分类

C语句分为以下5类。

1、控制语句2、函数调用语句3、表达式语句4、空语句5、复合语句——1、控制语句

控制语句用于完成一定的控制功能。C语言只有9种控制语句,它们的形式是:

① if()…else…② for()…③ while()…(条件语句)(循环语句)(循环语句)④ do…while()⑤ continue⑥ break(循环语句)(结束本次循环语句)(中止执行switch或循环语句)⑦ switch⑧ return⑨ goto(多分支选择语句)(从函数返回语句)(转向语句,在结构化程序中基本不用goto语句)——2、函数调用语句

函数调用语句由一个函数调用加一个分号构成,例如:

printf("This is a C statement.");

其中printf("This is a C statement.")是一个函数调用,加一个分号成为一个语句。

——3、表达式语句

表达式语句由一个表达式加一个分号构成,最典型的是由赋值表达式构成一个赋值语句。例如:

a=3

是一个赋值表达式,而

a=3;

是一个赋值语句。可以看到,一个表达式的最后加一个分号就成了一个语句。一个语句必须在最后有一个分号,分号是语句中不可缺少的组成部分,而不是两个语句间的分隔符号。

——4、空语句

下面是一个空语句:

;

此语句只有一个分号,它什么也不做。那么它有什么用呢?

可以用来作为流程的转向点(流程从程序其他地方转到此语句处),也可用来作为循环语句中的循环体(循环体是空语句,表示循环体什么也不做)。

——5、复合语句

可以用{}把一些语句和声明括起来成为复合语句(又称语句块)。例如下面是一个复合语句:

{ float pi=3.14159,r=2.5,area; area=pi *r* r; printf("area=%f",area); }3.4.2:最基本的语句——赋值语句

在C程序中,最常用的语句是:赋值语句和输入输出语句。其中最基本的是赋值语句

程序中的计算功能大部分是由赋值语句实现的,几乎每一个有实用价值的程序都包括赋值语句。有的程序中的大部分语句都是赋值语句。 先分析一个例子。

——例3.4

给出三角形的三边长,求三角形面积。

解题思路:假设给定的三个边符合构成三角形的条件:任意两边之和大于第三边。解此题的关键是要找到求三角形面积的公式。从数学知识已知求三角形面积的公式为 #include #include int main() { double a,b,c,s,area; a=3.67; b=5.43; c=6.21; s=(a+b+c)/2; area=sqrt(s*(s-a)*(s-b)*(s-c)); printf("a=%f\tb=%f\tc=%f\n",a,b,c); printf("area=%f\n",area); return 0; }注意:此处教材上的代码有问题,想要复现结果,直接复制上面的代码即可。3.5:数据的输入输出 3.5.1:输入输出举例

前面已经看到了利用printf函数进行数据输出的程序,现在再介绍一个包含输入和输出的程序 。

——例3.5

求 ax^{2}+bx+c=0 方程的根。 a,b,c 由键盘输入,设 b^{2}-4ac>0 。

解题思路:首先要知道求方程式的根的方法。由数学知识已知:如果 b^{2}-4ac>0 ,则一元二次方程有两个实根:

可以将上面的分式分为两项:

则 x_{1}=p+q,x_{2}=p-q 。

有了这些式子,只要知道 a,b,c 的值,就能顺利地求出方程的两个根。剩下的问题就是输入 a,b,c 的值和输出根的值了。需要用scanf函数输入 a,b,c 的值,用printf函数输出两个实根的值。

#include #include int main() { double a,b,c,disc,x1,x2,p,q; scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c; p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q;x2=p-q; printf("x1=%7.2f\nx2=%7.2f\n",x1,x2); return 0; }

程序分析

(1)用scanf函数输入 a,b,c 的值,请注意在scanf函数中括号内变量a,b,c的前面,要用地址符&,即&a,&b,&c。&a表示变量a在内存中的地址。该scanf函数表示从终端输入的3个数据分别送到地址为&a,&.b,&c的存储单元,也就是赋给变量a,b,c。双撇号内用%lf格式声明,表示输入的是双精度型实数

(2)在scanf函数中,格式声明为“%lf%lf%lf”,连续3个“%lf”。要求输入3个双精度实数。请注意在程序运行时应怎样输入数据。从上面运行情况中可以看到输入“1 3 2”,两个数之间用空格分开。这是正确的,如果用其他符号(如逗号)会出错。

(3)在printf函数中,不是简单地用%f式声明,而是在格式符f的前面加了“7.2”,表示在输出x1和x2时,指定数据占7列,其中小数占2列。

(4)在本例中假设给定的a,b,c的值满足 b^{2}-4ac>0 ,所以程序不对此进行判断。在实际上,用所输入的 a,b,c 并不一定能求出两个实根。因此为稳妥起见,应在程序的开头检查 b^{2}-4ac>0 是否大于等于0。只有确认它大于等于0,才能用上述方法求方程的根。

#include #include int main() { double a,b,c,disc,x1,x2,p,q; scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c; if (disc>0 ) { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q;x2=p-q; printf("x1=%7.2f\nx2=%7.2f\n",x1,x2); } else printf("Faluse Ipnut"); return 0; }3.5.2:有关数据输入输出的概念

输入输出是程序中最基本的操作之一,在讨论程序的输入输出时首先要注意以下几点。

(1)所谓输入输出是以计算机主机为主体而言的。从计算机向输出设备(如显示器、打印机等)输出数据称为输出,从输入设备(如键盘、光盘、扫描仪等)向计算机输入数据称为输入,如图3.17所示。

(2)C语言本身不提供输入输出语句,输入和输出操作是由C标准函数库中的函数来实现的。在C标准函数库中 提供了一些输入输出函数,例如printf函数和scanf函数。

读者在使用它们时,千万不要误认为它们是C语言提供的“输入输出语句”。printf和scanf不是C语言的关键字,而只是库函数的名字。不把输入输出作为C语句的目的是使C语言编译系统简单精练,因为将语句翻译成二进制的指令是在编译阶段完成的,没有输入输出语句就可以避免在编译阶段处理与硬件有关的问题,可以使编译系统简化,而且通用性强,可移植性好,在各种型号的计算机和不同的编译环境下都能适用,便于在各种计算机上实现。

C语言函数库中有一批标准输入输出函数,它是以标准的输入输出设备(一般为终端设备)为输入输出对象的。其中有

putchargetcharprintfscanfputsgets输出字符输入字符格式输出格式输入输出字符串输入字符串

(3)要在程序文件的开头用预处理指令#include把有关头文件放在本程序中

如果程序调用标准输入输出函数,就必须在本程序的开头用#include指令把stdio.h头文件包含到程序中。#include指令放在程序的开头,所以把stdio.h称为“头文件”(header file),文件后缀为“.h”。在stdio.h头文件中存放了调用标准输入输出函数时所需要的信息,包括与标准I/O库有关的变量定义和宏定义以及对函数的声明。

注意:#include指令还有一种形式,头文件不是用尖括号括起来,而是用双撇号,如:#include "stdio.h"

3.5.3:用printf函数输出数据

printf函数和scanf函数是格式输入输出函数,在使用时必须根据数据的不同类型指定不同的格式。

printf函数(格式输出函数)用来向终端(或系统隐含指定的输出设备)输出若干个任意类型的数据。

——1、printf函数的一般格式

printf函数的一般格式为 :printf(格式控制,输出表列)

——2、格式字符

前已介绍,在输出时,对不同类型的数据要指定不同的格式声明,而格式声明中最重要的内容是格式字符。常用的有以下几种格式字符。

(1)d格式符(2)c格式符(3)s格式符(4)f格式符(5)e格式符有符号的十进制整数一个字符一个字符串实数指数形式的实数(1)d格式符

用来输出一个有符号的十进制整数。

在前面的例子中已经看到了:在输出时,按十进制整型数据的实际长度输出,正数的符号不输出。可以在格式声明中指定输出数据的域宽(所占的列数),如用“%5d”,指定输出数据占5列,输出的数据显示在此5列区域的右侧。如:

(2)c格式符

用来输出一个字符。例如:

char ch='a'; printf("%c",ch);

运行时输出:a

一个整数,如果在0~127范围中,也可以用“%c”使之按字符形式输出,在输出前,系统会将该整数作为ASCll码转换成相应的字符;如:

#include int main() { short a=121; printf("%c",a); }(3)s格式符

用来输出一个字符串。如:

#include int main() { printf("%s","CHINA"); }(4)f格式符

用来输出实数(包括单、双精度、长双精度),以小数形式输出,有几种用法:

①基本型,用%f

不指定输出数据的长度,由系统根据数据的实际情况决定数据所占的列数。系统处理的方法一般是:实数中的整数部分全部输出,小数部分输出6位

——例3.6

用%f输出实数,只能得到6位小数。

#include int main() { double a=1.0; printf("%f\n",a/3); return 0; }

虽然a是双精度型,a/3的结果也是双精度型,但是用%f式声明只能输出6位小数。

②指定数据宽度和小数位数,用%m.nf

例3.5已经用了“%7.2”格式指定了输出的数据占7列,其中包括2位小数。对其后一位采取四舍五入方法处理,即向上或向下取近似值。如果把小数部分指定为0,则不仅不输出小数,而且小数点也不输出。如果在例3.6的printf函数中指定“%7.0f”格式声明,由于其整数部分为0,因此输出结果为0。所以不要轻易指定小数的位数为0

如果想在例3.6中输出双精度变量a的15位小数,可以采用例3.5所用的方法,用“ %20.15f”格式声明。

注意:在0的前面有3个空格。——例3.7

float型数据的有效位数。

本来计算的理论值应为3333.333333333…,但由于float型数据只能保证6~7位有效数字,因此虽然程序输出了6位小数,但从左面开始的第7位数字(即第3位小数)以后的数字并不保证是绝对正确的

如果将a改为double型,其他不变。

③输出的数据向左对齐,用%-m.nf

在m.n的前面加一个负号,其作用与%m.nf形式作用基本相同,但当数据长度不超过m时,数据向左靠,右端补空格。如:

第1次输出a时输出结果向左端靠,右端空5列。第2次输出a时输出结果向右端靠,左端空5列。

(5)e格式符

用格式声明指定以指数形式输出实数。如果不指定输出数据所占的宽度和数字部分的小数位数,许多C编译系统(如Visual C++)会自动给出数字部分的小数位数为6位,指数部分占5列(如e+002,其中“e”占1列,指数符号占1列,指数占3列)。

数值按标准化指数形式输出(即小数点前必须有而且只有1位非零数字)。例如:

也可以用“%m.ne”形式的格式声明,如:

格式符e也可以写成大写E形式,此时输出的数据中的指数不是以小写字母e表示而以大写字母E表示。

3.5.4:用scanf函数输入数据

在本章例3.5程序中已经看到怎样用scanf函数输入数据。下面再作比较系统的说明。

——1、scanf函数的一般形式

scanf(格式控制,地址表列)

“格式控制”的含义同printf函数。“地址表列”是由若干个地址组成的表列,可以是变量的地址,或字符串的首地址。

——2、scanf函数中的格式声明

与printf函数中的格式声明相似,以%始,以一个格式字符结束,中间可以插入附加的字符。

例3.5中的scanf函数是比较简单的。可以把scanf函数改写成以下形式:

在格式字符串中除了有格式声明%f外,还有一些普通字符(有“a=”“b=”“c=”和“,”)。

表3.8和表3.9列出scanf函数所用的格式字符和附加字符。它们的用法和printf函数中的用法差不多。

——3、使用scanf函数时应注意的问题

(1)scanf函数中的格式控制后面应当是变量地址,而不是变量名。例如,若a和b为整型变量,如果写成

是不对的。应将“a,b,c”改为“&a,&b,&c”。许多初学者常犯此错误。

(2)如果在格式控制字符串中除了格式声明以外还有其他字符,则在输入数据时在对应的位置上应输入与这些字符相同的字符。如果有

在输入数据时,应在对应的位置上输入同样的字符。即输入

因为系统会把它和scanf函数中的格式字符串逐个字符对照检查的,只是在%f位置上代以一个浮点数。

(3)在用“%c”格式声明输入字符时,空格字符和“转义字符”中的字符都作为有效字符输入,例如:

在执行此函数时应该连续输入3个字符,中间不要有空格。如:

若在两个字符间插入空格就不对了。如:

系统会把第1个字符'a'送给c1;第2个字符是空格字符′,送给c2;第3个字符'b'送给c3。而并不是把'a′送给c1,把'b'送给c2,把'c'送给c3。

(4)在输入数值数据时,如输入空格、回车、Tab键或遇非法字符(不属于数值的字符),认为该数据结束。例如:

若输入

第1个数据对应%d式,在输入1234之后遇字符'a',因此系统认为数值1234后已没有数字了,第1个数据应到此结束,就把1234送给变量a。把其后的字符'a'送给字符变量b,由于只要求输入一个字符,系统判定该字符已输入结束,因此输入字符a之后不需要加空格。

字符'a'后面的数值应送给变量c。如果由于疏忽把1230.26错打成123o.26,由于123后面出现字母o,就认为该数值数据到此结束,将123送给变量c,后面几个字符没有被读入。

3.5.5:字符输入输出函数

除了可以用printf函数和scanf函数输出和输入字符外,C函数库还提供了一些专门用于输入和输出字符的函数

——1、putchar:输出一个字符

想从计算机向显示器输出一个字符,可以调用系统函数库中的putchar函数(字符输出函数)。

putchar函数的一般形式为

putchar(c)

putchar是put character(给字符)的缩写,putchar(c)的作用是输出字符变量c的值,显然输出的是一个字符。

——例3.8

先后输出BOY三个字符。

解题思路:定义3个字符变量,分别赋以初值'B','O','Y',然后用putchar函数输出这3个字符变量的值。#include int main() { char a='B',b='O',c='Y'; putchar(a); putchar(b); putchar(c); putchar('\n'); return 0; }

从此例可以看出:用putchar函数既可以输出能在显示器屏幕上显示的字符,也可以输出屏幕控制字符,如putchar('\n')的作用是输出一个换行符,使输出的当前位置移到下一行的开头

从前面的介绍已知:字符类型也属于整数类型,因此将一个字符赋给字符变量和将字符的ASCII代码赋给字符变量作用是完全相同的(但应注意,整型数据的范围为0~127)。 因此,上面的程序可以进行以下改写:

putchar函数是输出字符的函数,它输出的是字符而不能输出整数。66是字符B的ASClI代码,因此,putchar(66)输出字符B。

——2、getchar:输入一个字符

为了向计算机输入一个字符,可以调用系统函数库中的getchar函数(字符输入函数)。

getchar函数的一般形式为

getchar()

getchar是get character(取得字符)的缩写,getchar函数没有参数,它的作用是从计算机终端 (一般是键盘)输入一个字符,即计算机获得一个字符。getchar函数的值就是从输入设备得到的字符。getchar函数只能接收一个字符。如果想输入多个字符就要用多个getchar函数

——例3.9从键盘输入BOY3个字符,然后把它们输出到屏幕。

解题思路:用3个getchar函数先后从键盘向计算机输入BOY3个字符,然后用putchar函数输出。

#include int main() { char a,b,c; a=getchar(); b=getchar(); c=getchar(); putchar(a); putchar(b); putchar(c); putchar('\n'); return 0; }

注意:输入的时候别敲空格,因为空格也是算一个字符。

用getchar函数得到的字符可以赋给一个字符变量或整型变量,也可以不赋给任何变量,而作为表达式的一部分,在表达式中利用它的值。

#include int main() { putchar(getchar()); putchar(getchar()); putchar(getchar()); putchar('\n'); return 0; }

也可以在printf函数中输出刚接收的字符:

——例3.10

从键盘输入一个大写字母,在显示屏上显示对应的小写字母。

解题思路:用getchar函数从键盘读入一个大写字母,把它转换为小写字母,然后用putchar函数输出该小写字母。 #include int main() { char c1,c2; c1=getchar(); c2=c1+32; putchar(c2); putchar('\n'); return 0; }总目录



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有