第2章 顺序结构程序设计第2章 顺序结构程序设计学习目标 本章主要介绍了顺序程序设计方法、C语言中四种常用的基本输入输出函数p rintf、scanf、getchar、putchar的格式与使用方法,在本章的最后还介绍了基本位运算的方法。通过本章的学习,需要 初步理解顺序结构程序设计思想,掌握四种基本输入输出函数的调用格式,理解基本位运算的方法。第2章 顺序结构程序设计2.1 p rintf函数2.2 scanf函数2.3 字符数据的输入和输出2.4 位运算2.1 printf函数2.1.1 print f函数的一般格式2.1.2 格式字符2.1.1 printf函数的一般格式功能:按照用户指定的格式,向系统隐含的输出设备(终端)输 出若干个任意类型的数据。printf函数的一般格式:printf(“格式控制字符串”,输出列表)printf函数称为格式输出函数, 其关键字最末一个字母f即为“格式”(format)之意。其功能是按用户指定的格式,把指定的数据显示到显示器屏幕上。2.1.1 pr intf函数的一般格式例如:printf("%d %c\n",i,c)格式控制字符串(转换控制字符串):"%d %c\n"输出列表 :i,c其中,格式说明:%d %c函数参数包括两部分:1.“格式控制”字符串是用双引号括起来的字符串,也称“转换控制字符串”, 它 指定输出数据项的类型和格式。它包括两种信息:●格式说明项:由“%”和格式字符组成,如%d,%f等。格式说明总是由“%”字符开始,到 格式字符终止。它的作用是将输出的数据项转换为指定的格式输出。输出表列中的每个数据项对应一个格式说明项。●普通字符:即需要原样输出的 字符。例子中的逗号和换行符。2.“输出列表”是需要输出的一些数据项,可以是表达式。例如:假如a=3,b=4,那么printf(“a =%d b=%d”,a,b);输出a=3 b=4。其中两个“%d”是格式说明,表示输出两个整数,分别对应变量a,b,“a=”,“b =”是普通字符,原样输出。由于printf是函数,因此“格式控制”字符串和“输出表列”实际上都是函数的参数。printf函数的一般 形式可以表示为:printf(参数1、参数2、参数3、…参数n)printf函数的功能是将参数2-参数n按照参数1给定的格式输出。 例2.1 以下程序运行后的输出结果是 (2010年9月全国计算机等级考试二级C试题填空题第6题) #incl ude<stdio.h> main() {int a=200,b=010; printf(”%d%d\n”,a,b); }2.1.2 格式字符对于不同类型的数据项应当使用不同的格式字符构成的格式说明项。常用的有以下几种格式字符:1.d格式符。用来 输出十进制整数。有以下几种用法:●%d,按照数据的实际长度输出●%md,m指定输出字段的宽度(整数)。如果数据的位数小于m,则左端 补以空格(右对齐),若大于m,则按照实际位数输出。●%-md,m指定输出字段的宽度(整数)。如果数据的位数小于m,则右端补以空格( 左对齐),若大于m,则按照实际位数输出。●%ld,输出长整型数据,也可以指定宽度%mld。例2.2 %d格式几种用法#includ e “stdio.h” 程序预处理声明#define CODE 255 预处理声明, 常量CODE在程序中等于255main() 主程序 {printf(“%d\n”,CODE); 按照数据的实际长度输出printf(“%2d\n ”,CODE); 按照m=2的长度输出printf(“%10d\n”,CODE); 按照m=10的长度输出printf (“%-10d\n”,CODE); 按照%-md格式输出return 0; 程序返回主函数}运行结果:255255 255255 2.o格式符。以八进制形式输出整数。注意是将内存单元中的各位的值按八进制形式输出 ,输出的数据不带符号,即将符号位也一起作为八进制的一部分输出。例2.3 %d、%o、%x格式输出的比较#include “stdi o.h” 程序预处理声明main() 主程序,程序执行开始{int a=-1; 定义变量a,并初始化printf(“%d,%o%x”,a,a,a); 打印输出}运行结果:-1, 177777,ffff3.x格式符。以十六进制形式输出整数。与o格式一样,不出现负号。4.u格式符。用来输出unsigned无符号 型数据,即无符号数,以十进制形式输出。一个有符号整数可以用%u形式输出,反之,一个unsigned型数据也可以用%d格式输出。5. c格式符。用来输出一个字符。一个整数只要它的值在0-255范围内,也可以用字符形式输出。反之,一个字符数据也可以用整数形式输出。例 2.4 整形与字符型输出的差别#include “stdio.h” main() 主程序{ char c=’a’; 声明字符型变量c,并初始化int i=97; 声明整形变量i,并初始化printf( “%c,%d\n”,c,c); 格式打印输出变量cprintf(“%c,%d\n”,i,i); 格式打印输出变量c}运行结果:a ,97a,97分析:也可以指定字段宽度。%mc,m-整数6.s格式符。用来输出一个字符串。有几种用法:%s,输出字符串%ms,输出 的字符串占m列,如果字符串长度大于m,则字符串全部输出;若字符串长度小于m,则左补空格(右对齐)。%-ms,输出的字符串占m列,如 果字符串长度大于m,则字符串全部输出;若字符串长度小于m,则右补空格(左对齐)。%m.ns,输出占m列,但只取字符串左端n个字符, 左补空白(右对齐)。%-m.ns,输出占m列,但只取字符串左端n个字符,右补空白(左对齐)。例2.5 %s格式输出的表现手法#in clude “stdio.h”#define ACITOR “hello,how do you do?” ACITOR 等于hello,how do you do?main() 主程序{printf (“ /%2s/\n”,ACITOR); 按各种格式打印输出printf (“/%24s/\n”,ACITOR);printf (“/%24.5s/\n”,ACITOR);printf (“/%-24.5s/\n”,ACITOR);return 0;}运行 结果:/hello,how do you do? // hello,how do you do?// hello//hello /7.f格式符。用来输出实数(包括单、双精度,单双精度格式符 相同),以小数形式输出。有以下几种用法:%f,不指定宽度,使整数部分全部输出,并输出6位小数。注意,并非全部数字都是有效数字,单精 度实数的有效位数一般为7位(双精度16位)。例2.6 单精度实数的有效位#includemain(){float x,y;x=111111.111;y=222222.222printf(“%x”,x+y);}运行结果:333333.32812 5例2.7 双精度实数的有效位#include main(){double x,y;x=111111111111 11.11111111;y=22222222222222.22222222;printf(“%f”,x+y);}运行结果:3333 3333333333.3330108.e格式符,以指数形式输出实数。可用以下形式:%e,不指定输出数据所占的宽度和小数位数,由系统 自动指定,如6位小数,指数占5位-e占1位,指数符号占1位,指数占3位。数值按照规格化指数形式输出(小数点前必须有而且只有1位非0 数字)。例如:1.234567e+002。(双精度)%m.ne和%-m.ne,m总的宽度,n小数位数。例2.8程序段: (2009 年3月全国计算机等级考试二级C试题选择题第15题)int x=12;double y=3.141593;printf("%d%8. 6f",x,y);的输出结果是:A)123.141593 B)12 3.141593 C)12,3.141593 D)123.14 159309.g格式符。用来输出实数,它根据数值的大小,自动选f格式或e格式(选择输出时占宽度较小的一种),且不输出无意义的0(小 数末尾0)。例2.9 %f,%e,%g输出的比较#include “stdio.h” #define “ACITOR”main() 主程序{float f=123.10;printf("%f,%e,%g\n",f,f,f); 按各种格式打 印输出}运行结果:123.100000,1.23100e+02,123.1以上介绍的9种格式符,归纳如下表:表2.1 printf 格式字符功能描述 2.2 scanf函数2.2.1 scanf函数的一般格式 2.2.2 scanf函数中的格式声明2.2.3 使 用scanf函数时应注意的问题2.2.1 scanf函数的一般格式 scanf(格式控制字符串,地址列表)其中:格式控制字符串的含 义与printf类似,它指定输入数据项的类型和格式。地址列表是由若干个地址组成的列表,可以是变量的地址(&变量名)或字符串的首地址 。例2.10 有以下程序(2009年3月全国计算机等级考试二级C试题选择题第23题)#include main( ){ int a1,a2; char c1,c2; scanf("%d%c%d%c",&a1,&c1,&a2,&c2); printf("%d,%c,%d,%c",a1,c1,a2,c2); }若通过键盘输入,使得a1的值为12,a2的值为34,c1的 值为字符a,c2的值为字符b,程序输出结果是:12,a,34,b 则正确的输入格式是(以下_代表空格,代表回车)A)12a 34b B)12_a_34_bC)12,a,34,b D)12_a34_b2.2.2 scanf函数中的格式声明表2.3 scanf格式字符功能描述2.2.2 scanf函数中的格式声明表2.4 scanf格式中附 加格式说明字符2.2.2 scanf函数中的格式声明例2.11 有以下程序(2010年9月全国计算机等级考试二级C试题填空题第7题 ) #include<stdio.h> main() {int? x,Y; scanf(”%2d%ld”,&x, &y);printf(”%d\n”,x+y); } 程序运行时输入:1234567程序的运行结果是 。2.2 .3 使用scanf函数时应注意的问题1.scanf函数中格式控制符后面应当是变量地址,而不应是变量名。2.如果在“格式控制”字符 串中除了格式说明以外还有其它字符,则在输入数据时在对应位置应当输入与这些字符相同的字符。建议不要使用其它的字符。3.在用“%c”格 式输入字符时,空格字符和转义字符都作为有效字符输入。%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。2.2.3 使用s canf函数时应注意的问题4.在输入数据时,遇到下面情况认为该数据结束:1)遇到空格,或按“回车”或“跳格”(tab)键。如:in t a,b,c;scanf(“%d%d%d”,&a,&b,&c);输入:12 34 (tab) 567后,a=12,b= 34,c=5672)按指定的宽度结束3)遇到非法的输入。如:float a,c; char b;scanf(“%d%c%f”,& a,&b,&c);输入:1234a123o.26<回车>后,a=1234.0,b=’a’,c=123.0(而不是希望的1230.2 6)C语言的格式输入输出的规定比较繁琐,重点掌握最常用的一些规则和规律即可,其它部分可在需要时随时查阅。希望大家勤于动手,多上机练 习来加强上机操作!4)&的使用条件例2.12 &符号要根据实际情况而定有以下程序段(2011年3月全国计算机等级考试二级C试题选择 题第16题)char name[20]; int num; scanf("name=%s num=%d",name;&num) ;当执行上述程序段,并从键盘输入:name=Lili num=1001<回车>后,name的值为A)Lili B)name=Lil i C)Lili num= D)name=Lili num=10012.3 字符数据的输入和输出2.3.1 putchar函数输 出一个字符2.3.2 getchar函数输入一个字符2.3.1 putchar函数输出一个字符一般形式:putchar(字符表达式 );例如: putchar(''A''); (输出大写字母A) putchar(x); (输出字符变量x的 值)putchar(‘\101’); (也是输出字符A)putchar(''\n''); (换行)对控制字符则执行控制功能,不在屏 幕上显示。使用本函数前必须要用文件包含命令:#include或#include “stdio.h”例2.13 输 出单个字符#includemain(){char a=''B'',b=''o'',c=''k'';putchar(a);pu tchar(b);putchar(b);putchar(c);putchar(''\t'');putchar(a);putchar(b );putchar(''\n'');putchar(b);putchar(c);}运行结果:Book Book2.3.2 g etchar函数输入一个字符一般形式:c=getchar();【功能】从终端(键盘)输入一个字符,以回车键确认。函数的返回值就是输 入的字符。例如:通常把输入的字符赋予一个字符变量,构成赋值语句,如: char c; c=getcha r();例2.14 有以下程序(2010年3月全国计算机等级考试二级C试题选择题第15题)#include m ain() { char a,b,c,d; scanf(“%c%c”,&a,&b); c=getchar(); d= getchar(); printf(“%c%c%c%c\n”,a,b,c,d); }当执行程序时,按下列方式输入数据(从第 1列开始,注意:回车也是一个字符)1234则输出结果是:A)1234 B)12 C)12 D)12 34 3 2.4 位运算2.4.1 位运算符2.4.2 简单的位运算2.4.1 位运算符C语言提供了六种位运算 符:运算符含义描述& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0| 按位或 两个相应的 二进制位中只要有一个为1,该位的结果值为1^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0<< 左移 用来将一个数的各二进制位全部左移N位,右 补0>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补01.按位与运算 按位与运算符 "&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数 以补码方式出现。按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为0000000011111111)。例2.15 按位与运算#includemain(){i nt a=9,b=5,c;c=a&b;printf("a=%d\nb=%d\nc=%d\n",a,b,c);}运算结果:a=9b= 5c=1分析:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。2.按位或运算 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进制数位相或。只 要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。例2.16 按位或运算#include >main(){int a=9,b=5,c;c=a|b;printf("a=%d\nb=%d\nc=%d\n",a,b,c);}运 行结果:a=9b=5c=13分析:9|5可写算式如下: 00001001|00000101=00001101 (十进制为13)可见 9|5=133.按位异或运算 按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进制数位相异或,当两对应的二进位相 异时,结果为1。参与运算数仍以补码出现,例2.17 按位异或运算#includemain(){int a=9;a =a^15;printf("a=%d\n",a);}运算结果:a=6分析:9^5可写成算式如下: 00001001^0000010 1 00001100 (十进制为12)4.求反运算 求反运算符~为单目运算符,具有右结合性。 其功能是对参与运算的数的各二进制数位 按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110。大家可以按照顺序程序 的写法,上机实际操作。5.左移运算 左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进制数位全部左移若干位,由 “<<”右边的数指定移动的位数,高位丢弃,低位补0。例如: a<<4 指把a的各二进制数位向左移动4位。如a=00000011(十 进制3),左移4位后为00110000(十进制48)。6.右移运算 右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算 数的各二进制数位全部右移若干位,“>>”右边的数指定移动的位数。 例如:设 a=15,a>>2 表示把000001111右移为00 000011(十进制3)。 应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时, 最高位补0,而为负数时,符号位为 1。即:右移时最高位补符号位,左移时最低位补零。例2.18有以下程序(2009年3月全国计算机等级考试二级C试题选择题第39题)# include main(){ int a=5,b=1,t; t=(a<<2)|b; printf("%d\n" ,t); }程序运行后的输出结果是A)21 B)11 C)6 D)1分析:选择A答案。程序中的关键语句为t=(a<<2)|b ;由于当一个数左移1位时表示该数乘以2(请自行验证),因此表达式a<<2的值为变量a左移两位得到,即54=20(请特别注意:a的 值并未变化,仅仅是表达式的值为20!)。因此计算过程为:t=(a<<2)|b = (5<<2)|1 = 20 | 1 =21。例2 .19 按位右移运算#includemain(){char a=''a'',b=''b'';int p,c,d;p=a; p=(p<<8)|b;d=p&0xff;c=(p&0xff00)>>8;printf("a=%d\nb=%d\nc=%d\nd=% d\n",a,b,c,d);}运行结果:a=97b=98c=97d=982.4.2 简单的位运算1.“按位与”运算符(&)按位与是 指:参加运算的两个数据,按二进制数位进行“与”运算。如果两个相应的二进制数位都为1,则该位的结果值为1;否则为0。这里的1可以理解 为逻辑中的true,0可以理解为逻辑中的false。按位与其实与逻辑上“与”的运算规则一致。逻辑上的“与”,要求运算数全真,结果才 为真。若,A=true,B=true,则A∩B=true 例2.20 按位与运算#include main(){ int a=3int b = 5;printf("%d",a&b);}运行结果:1按位与的用途:1)清零若想对一个存储单元清零,即 使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:原来的数中为1的位,新数中相应位为0。然后使二者进行&运算,即可 达到清零目的。例2.21 按位与运算—清零#include main(){int a=43;int b = 14 8;printf("%d",a&b);}运算结果:0分析:原数为43,即00101011(2),另找一个数,设它为148,即100 10100(2),将两者按位与运算: 00101011(2)&10010100(2)= 00000000(2)2)取一个数中某些指 定位若有一个整数a(2byte),想要取其中的低字节,只需要将a与8个1按位与即可。a 00101100 10101100b 00 000000 11111111c 00000000 10101100 3)保留指定位:与一个数进行“按位与”运算,此数在该位取1. 例2.22 按位与运算—保留指定位#include main(){int a=84;int b = 59;pri ntf("%d",a&b);}运行结果:162.“按位或”运算符(|) 两个相应的二进制位中只要有一个为1,该位的结果值为1。借用 逻辑学中或运算的话来说就是,一真为真。例如:60(8)|17(8),将八进制60与八进制17进行按位或运算。 00110000|0 0001111= 00111111例2.23 按位或运算#include main(){int a=060;in t b = 017;printf("%d",a|b);}运行结果:633.“异或”运算符(^)规则是:若参加运算的两个二进制位值相 同则为0,否则为1即0∧0=0,0∧1=1,1∧0=1, 1∧1=0例2.24 按位或运算#include ma in(){int a=071;int b = 052;printf("%d",a^b);}运行结果:19分析:00111001∧ 00101010=00010011应用:1)使特定位翻转设有数01111010(2),想使其低4位翻转,即1变0,0变1.可以将其 与00001111(2)进行“异或”运算,即: 01111010(2)^00001111(2)= 01110101(2)运算结果的 低4位正好是原数低4位的翻转。可见,要使哪几位翻转就将与其进行∧运算的对应位置为1即可。2)与0相“异或”,保留原值例如:012^ 00=012 00001010^00000000= 00001010因为原数中的1与0进行异或运算得1,0^0得0,故保留原数 。3) 交换两个值,不用临时变量a=3,即11(2);b=4,即100(2)。想将a和b的值互换,可以用以下赋值语句实现:c语言源 代码:例2.25 按位异或运算#include main(){int a=3;int b = 4;a=a^b;b =b^a;a=a^b;printf("a=%d b=%d",a,b);}运行结果:a=4 b=3分析:a=a∧b;b=b∧a;a =a∧b;a=011(2)(∧)b=100(2)a=111(2)(a∧b的结果,a已变成7)(∧)b=100(2)b=011(2) (b∧a的结果,b已变成3)(∧)a=111(2)a=100(2)(a∧b的结果,a已变成4)等效于以下两步:执行前两个赋值语句: “a=a∧b;”和“b=b∧a;”相当于b=b∧(a∧b)。再执行第三个赋值语句: a=a∧b。由于a的值等于(a∧b),b的值等 于(b∧a∧b),因此,相当于a=a∧b∧b∧a∧b,即a的值等于a∧a∧b∧b∧b,等于b。5.左移运算符(<<)左移运算符是用 来将一个数的各二进制位左移若干位,移动的位数由右操作数指定(右操作数必须是非负值),其右边空出的位用0填补,高位左移溢出则舍弃该高 位。例2.27 有以下程序(2011年9月全国计算机等级考试二级C试题选择题第38题)#includemain( ){int a=2,b; b=a<<2; printf(“%d\n”,b); }程序运行后的输出结果是:A.2 B.4 C.6 D.8答案:D分析:将a的二进制数左移2位,右边空出的位补0,左边溢出的位舍弃。若a=15,即00001111(2),左移2位得00111100(2)。左移1位相当于该数乘以2,左移2位相当于该数乘以22=4,15<<2=60,即乘了4。但此结论只适用于该数左移时被溢出舍弃的高位中不包含1的情况。假设以一个字节(8位)存一个整数,若a为无符号整型变量,则a=64时,左移一位时溢出的是0,而左移2位时,溢出的高位中包含1。6.右移运算符(>>)右移运算符是用来将一个数的各二进制位右移若干位,移动的位数由右操作数指定(右操作数必须是非负值),移到右端的低位被舍弃,对于无符号数,高位补0。对于有符号数,某些机器将对左边空出的部分用符号位填补(即“算术移位”),而另一些机器则对左边空出的部分用0填补(即“逻辑移位”) 例2.28 按位右移运算#include main(){int a=0113755;printf("%d",a>>1);}运行结果:19446分析:a的值是八进制数113755:a:1001011111101101 (用二进制形式表示)a>>1: 0100101111110110 (逻辑右移时)a>>1: 1100101111110110 (算术右移时)7.位运算赋值运算符位运算符与赋值运算符可以组成复合赋值运算符。例如: &=, |=, >>=, <<=, ∧=例: a & = b相当于 a = a & b a << =2相当于a = a << 2 |
|