求修改C语言代码,输出以空格分隔,sql 去掉最后一个空格数字之后无空格

欢迎加入我们,一同切磋技术。 &
用户名: &&&
密 码: &
共有 2702 人关注过本帖
标题:求解,输入1990要求输出1 9 9 0 两个数字间有空格
来 自:江西
等 级:新手上路
帖 子:96
结帖率:76.92%
&&已结贴√
&&问题点数:10&&回复次数:10&&&
求解,输入1990要求输出1 9 9 0 两个数字间有空格
#include&stdio.h&
#include&string.h&
char str1[80]={' '};
void insertstr(char str[]);
char str2[20];
scanf(&%s&,str2);
insertstr(str2);
void insertstr(char str[])
&&for (i=0,j=0;j&=strlen(str);i++,j++)
&&& str1[2*i]=str[j];
&&printf(&%s\n&,str1);
我觉得我这个很合理就是得不出结果,请高手帮我忙啊 万分感激!
搜索更多相关主题的帖子:
等 级:职业侠客
帖 子:158
专家分:380
char str1[80]={' '};
&初始化时第一个元素时‘ ’,其他都为0,而你str1[2*i]=str[j];并没有改变str1[1]的值,str1[1]的值还是0,你以字符串格式输出,只能输出str[0]
等 级:业余侠客
帖 子:102
专家分:297
程序代码:#include&stdio.h&
#include&string.h&
void insertstr(char str[],char str0[]);
void main()
&&& char str1[<font color=#] = {<font color=#};
&&& char str2[<font color=#];
&&& gets(str2);
&&& insertstr(str1,str2);
&&& printf(&%s&,str1);
&&& printf(&\n&);
void insertstr(char str0[],char str[])
&&&int i,j;
&&&for (i=<font color=#,j=<font color=#;j&strlen(str);i++)
&&&&&if ( i % <font color=# == <font color=#)
&&&&&&&&&str0[i]=str[j];
&&&&&&&&&{
&&&&&&&&&&&& str0[i] = ' ';
&&&&&&&&&&&& j++;
&&&&&&&&&}
这样行的,最好还是不要用那个全局变量吧!
一阴一阳之谓道!
来 自:江西
等 级:新手上路
帖 子:96
回复 3楼 阴阳
#include&stdio.h&
#include&string.h&
{char str[80];
&void insert(char str[]);
&printf(&\nInput four digits:&);
&scanf(&%s&,str);
&insert(str);
void insert(char str[])
&for (i=0;i&strlen(str);i++)
&{str[2*i]=str[i];
&&str[2*i+1]=' ';
&printf(&\nOutput:\n%s&,str);
为什么我这样写就不会有答案出来呢,帮我 弄一下 啊!嘻嘻。。
等 级:业余侠客
帖 子:102
专家分:297
当i=0时,str[0]=1,str[1]=空格,当i=1时,str[2]=str[1](这里的str[1]本应该是9的,但上一步i=0时被改变,所以就凌乱了)
一阴一阳之谓道!
来 自:江西
等 级:新手上路
帖 子:96
回复 5楼 阴阳
谢谢,万分感激,谢谢啊万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激万分感激
来 自:上海
等 级:论坛游侠
帖 子:53
专家分:113
我重新写了一个
#include &stdio.h&
int main()
&&& char ss[20],*p;
&&& int i=0;
&&& printf(&请入一个数:&);
&&& scanf(&%s&,ss);
&&& printf(&%s\n&,ss);
&&& for(i;ss[i]!='\0';i++)
&&&&&&&&&&&printf(&%c&,ss[i]);
&&&&&&&&&&&putchar(' ');
&&&&&&&&&&&&if(ss[i]=='\0')
&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&ss[i]==' ';
&&&&&&&&&&&&&&putchar('\b');&&&&&&&&&&&&
&&&&&&&&&&&&&&&putchar(' ');
&&&&&&&&&&&&&&& putchar('\b');
&&&&&&&&&&&&&&&i--;
&&&&&&&&&&&&&&&}
&&& return 0;
等 级:新手上路
我想问一下,如果先拆分数字,然后直接输出会不会也正确呢?
等 级:论坛游民
帖 子:46
专家分:78
gets&&接收
等 级:论坛游民
帖 子:46
专家分:78
gets&&接收
版权所有,并保留所有权利。
Powered by , Processed in 0.337522 second(s), 7 queries.
Copyright&, BCCN.NET, All Rights Reserved本帖子已过去太久远了,不再提供回复功能。当前位置: >>
《C语言程序设计》
第一章 C语言程序设计初步? 教学要点:通过本章的学习,了解程序设计 语言的发展,源程序的编辑、编译、连接与 执行,设计简单的C函数。 ? 教学内容:程序设计语言的发展,C语言程序 的运行环境,源程序的编辑、编译、连接与 执行,用库函数组装C程序,设计简单的C函 数。 §1.1 程序设计语言 1.1.1 程序设计语言的发展机器语言 程 序 设 计 语 言 汇编语言 面向过程的语言 面向对象的程序设计语言 1.1.2程序设计语言的支持环境1.1.3源程序的编辑、编译、连接与执行输入程序 编辑 f.c文件 编译 f.obj 连接 f.exe 执行 结果§1. 2用库函数组装C程序例如1.1输出一行信息 main() /*一个程序只有一个主函数*/ 花括号内的部 分称为函数体{printf(Dthis is a c program.\n‖); } 说明:见书上第5、6页说明⑴―⑷ 例1.2 求两个数之和main(){ int a,b, a=123;b=456; sum=a+b;/*求两个数之和*/printf(Dsum is %d\n‖,sum);}§1. 3C程序的上机步骤编好一个C源程序,上机运行的步骤如下:输入与编 辑源程序对源程序 进行编译与库函 数连接运行目 标程序 用Turbo C运行C程序的步骤 ①调用TurboC 程序,进入TC目录执行TC 例如:C:\ TC&tc 进入Turbo C编辑环境②输入编辑源文件 (File、Edit) ③编辑源程序a、选Compile菜单下“Compile to OBJ‖进行编译生成一个.obj的目 标程序;b 、再选“Compile /Link EXE file‖进行连接。 c、也可直接选“Compile/Make EXE file‖或“F9‖键 ④执行程序。按“F10‖键或选“Run/Run菜单“或按Ctrl-F9⑤按“ALT+F5‖键查看结果⑥退出Turbo C.按Alt-X或选文件菜单下的“Exit‖退出。 §1. 4自己设计C函数开始 定义a,b,c,ave四个变量 存放三个数及平均值 给a,b,c赋值例如:求三个数的平均值main(){/*求三个数的平均值*/float a,b,c, a=12.3;b=45.6;c=34.5; ave=(a+b+c)/3; 求平均值printf(Dave is %f\n‖,ave);}输出平均值结束 main()/*求三个数的平均值*/{ float a,b,c,a=12.3;b=45.6;c=34.5 ave=average(a,b,c); /*a,b,c为实参*/ printf(Dave is %f\n‖,ave); } 把要解决的某个问 题用一个函数来完 成,如: average()自定义函数average()float average(x,y,z) /*x,y,z是形参*/ float x,y,z; { aver=(x+y+z)/3;return(aver); 例如:求任意三个数的平均值 main() { /*求三个数的平均值*/开始 定义a,b,c,ave四个变量 存放三个数及平均值 输入三个数给a,b,cfloat a,b,c,scanf(%f,%f,%f‖,&a,&b,&c); ave=average(a,b,c); printf(Dave is %f\n‖,ave);}自定义函数arerage()float average(x,y,z) /*x,y,z是形参*/ float x,y,z; { aver=(x+y+z)/3;调用求平均值函数输出平均值}结束 开始例如:求两个数中的大者main() */ /*求二个数的最大值 定义a,b,max 三个变量 存放两个数及最大值 输入二个数给a,b y max=a{float a,b, scanf(%f,%f‖,&a,&b); if(a&b) max=a;A&bn max=belsemax=b; printf(Dmax is %f\n‖,max); } 输出最大值结束 开始求1+2+3+……+100的和main() /*求1到100的和*/ 定义i,sum二个变量存放 循环值及和 输入I,sum赋初值 y{int i, sum=0;i=0; while (i&=100) {sum=sum+i;I&=100Sum=sum+ini=i+1;} printf(Dsum is %d\n‖,sum); } 输出最大值结束 从以上几个例子可看出,一个C函数的一般形式为:函数类型形参类型定义 { 函数体 }函数名(形参表)按ANSI新的书写形式:函数类型 函数名(形参类型 形参)作业:第15页5、7小题。 本章考核要点:掌握C语言程序的编辑、编译、 连接与执行,掌握C语言程序的结构及书写格 式,利用库函数编写简单的C语言程序,初步 了解C程序的特点。 第二章 数据描述与基本操作教学要点:了解C语言数据类型、常量和变量的概念,C语 言中的运算符和表达式、不同类型数据间的转换、C语言的 数据标准输入和输出函数。 教学内容:数据类型、定点数、浮点数、字符数据的表示 及存储形式。带符号的数据类型和无符号的数据类型,直 接常量和符号常量、变量及其变量的赋值、变量的声明、 算术运算、关系运算、逻辑运算与条件运算,不同类型数 据间的转换,C语言数据的输入和输出函数。 §2.1数据类型短整型short整型数值类型基本类型 实型 字符类型(char)整型int 长整型long 单精度型float数 据 类 型枚举类型(enum) 数组类型双精度型doubleC构造类型 指针类型 空类型void结结构类型struct共用类型union) 文件类型FILE) 2.1.1 数值的定点表示形式和浮点表示形式凡不带指数部分的数称为定点数。如:10,394.78,-58.9 而小数点是 浮动的称为浮点数。如3.56*105 在程序中出现小数形式,C语言则按指数形式存 放,(以浮点数形式存储)。2.1.2 字符类型数据的表示和存储形式字行类型的数据在内存中以ASCⅡ代码存放。在C语言中字符数据可等价为与相 应的ASCⅡ码的整数字符数据可用数值形式输出,也可参与整数运算。例如:main(){ int I;ch=?A‘;ch=ch+32;I=printf(D%d is %c\n‖,I,ch); printf(D%c is %d\n‖,ch,ch); }/*C语言中,字符用单引号*/结果是:97 is a a is 97 2.1.3 数据的存储空间长度及取值范围(见书上19页) 2.1.4 带符号和数据类型与无符号的数据类型数字化信息的编码信息在计算机内的具体表现形式是数据,可用数字、字 符、汉字、声音、图形、图像等,它们在计算机内部都是采 用二进制来表示的。 一、进位计数制:按进位的方法进行计数称为进位计数制。 在计算机中最常用的是二进制,有时也使用八进制、十 进制、十六进制。 任意一个r进制数M可表示为 M=∑Di*ri 其中Di是该数的基本符号,ri 是权,r是基数 (213.76)10=2X102+1X101+3X100 +7X10-1+6X10-2 二进制、八进制、十进制、十六进制的进位规则、基数、数 符、权、标志形式。 进位制 二进制 八进制 规则 逢二进一 逢二进一 基数 r=2 r=8 数符、 0,1 0,1…6,7 权、 标志 2i 8i B O十进制逢十进一r=100,1…8,910iDH十六进制 逢十六进一 r=160,…9,A,B…F 16i将任意十进制整数转换为二进制:除二倒取余 将任意十进制小数转换为二进制:乘二取整 二进制与八进制的转换:从小数点往左或右三位二进制转换 为一位八进制。 二进制与十六进制的转换:从小数点往左或右四位二进 制转换为一位十六进制。 十进制0 1 2 3二进制0 1 10 11八进制0 1 2 3十六进制的关系0 1 2 345 6 7 8 9 10 11 12 13 14100101 110 111 10 01 111045 6 7 10 11 12 13 14 15 1645 6 7 8 9 A B C D E15161111100001720F10 整数在内存中,一般是以最高位表示符号位,用0表示正,1表示 负,数值是以补码形式存放的,一个正数的补码就是该数的二进制 数,一个负数的补码是:①先取该数的绝对值,②用二进制来表示,③ 对其取反,④然后加一. 前面的short,int,long等都是带符号的,如:int Singed int signed 等价 short Singed short 等价 long Singed longC语言允许使用无符号的数,它将二进制数的最左位不作为负 号位,所有位全用来表示数据,只能存放正数,与带符号的数相 比,数的表示范围扩大了一倍,(0~65535) 字符型数据也发为signed和unsigned,字符数据占一个字节,标 准ASCⅡ允许的范围为0-127,用128―255表示一些特殊字符。 (这种表示形式根据系统而定)。 例如:main() { c=0362; printf(D%d\n‖,c); }其结果为-14,而不是正数242,在定义时可采用unsigned char c 输 出的结果为242.(见书上第21页表2.3,及说明) C语言中可用sizeof(类型标识符)来测某一类型数据所占存储 空间。 见书上例2.4 §2.2常量和变量 常量:在程序执行过程中其值不变的量。 变量:在程序执行过程中其值可以改变的量2.2.1直接常量和符号常量(如12.5,4),符号常量是在程序中用一个名字来代表 #define PI 3.14 的常量。例:已知半径求圆面积和周长main(){float area(float r),cir(float r); printf(“area=%f\n”,area(2.0)); printf(“cir=%f\n”,cir(2.0)); #define R 2.0 main() {float area(float r),cir(float r);宏定义printf(“area=%f\n”,area(R));printf(“cir=%f\n”,cir(R)); } {float area(float r); { return (PI*R*R);)} {float cir(float r); { return (2*PI*R);)}}{float area(float r); { return (3.14*r*r);)} {float cir(float r); { return (2*3.14*r);)} 2.2.2直接常量的书写格式㈠整形常量在C语言中整形常量可用十进制数、八进制数、十六进制数书写。 (以0开头的为八进制,以0x开头的为十六进制,在整型后加l或L为长整型㈡实型常量实型常量只能用十进制数和指数形式来表示,不能用其它进制来表示㈢字符常量输出字符常量需用单引号括起来。如‘a‘,‘B‘,‘7‘等,其中撇号中的 字符不能是单撇号或反斜杠。㈣转义字符(见书上24页) ㈤字符串常量字符串常量用双引号括起来。如“a‖,”B‖,”1337‖等,字符串中输出单 引号时应借助转义字符。系统在字符串末尾自动加一个\0表示结束 2.2.3变量和对变量的赋值数据存储在一定的存储空间,变量是用于存储数据的,一个变 量对应一个变量名,对应一个存储空间,在程序中定义时进行分配。变量的赋值 变量=表达式2.2.4 变量的声明在C语言中用到一个变量都需进行声明,其赋值的方式可先声 明后赋值;也可在声明时同时赋值。 如 : int a,b,c; a=2;b=3;c=5;Int a=2,b=3,c=5;2.2.5标识符(符号常量、变量名、函数名、数组名等)说明见书上 28页。 §2.3运算符和表达式? ? ? ? ? ? ? ? ? ? ?C的运算符有13类: 算术运算符(+-*/% ++ --) 关系运算符(& & == &= &= !=) 逻辑运算符(! && ||) 位运算符(&& && ^| &~) 赋值运算符(=) 条件运算符(? :) 逗号运算符(,) 指针运算符(*和&) 求字节运算符(sizeof(类型)) 分量运算符(. -&) 下标运算符({}) 2.3.1 算术运算㈠双元算术运算符包括:+ - * / %,其中* / % 同级,+ -同级, 其结合方式是“自左自右”㈡自反算术运算符 双元运算表达式通常表示为:a=a+b 表示为a+=b称为自 反算术赋值运算,其结合方式为自右向左:包括(-= *= /= %=) ㈢ 自加自减运算 在自反运算中 C语言中可表示为 i=i+1 i+=1 i++ 或 i=i-1 i-=1 先引用后增值例:{int i=3;I++; x= }i- {int i=3; x=i++;先增值后引用 {int i=3; {int i=3;++i; x=I;} x=++i;}} ㈣正负号运算符 正负号运算符为+(正号)和-(负号),是一元运算,其优先级高于* /运算符 ㈤赋值运算符的副作用2.3.2 关系运算、逻辑运算与条件运算㈠关系运算C语言中的关系运算包括: &(大于) &=(大于等于) &(小于)&=(小于等于) ==(等 于) !=(不等于)其优先级见(352页)关系表达式的值只有两个:表达式成立为“真”,C语言中用“1”来表示; 关系表达式不成立为“假”,C语言中用“0”表示。 注意:见书(34页) ㈡逻辑表达式 C语言中的逻辑运包括: &&(逻辑与) ||(逻辑或) !=(逻辑非)其中&&和||是二元运算符,结合方式为自左向右,!=为一元运算,结合方式为自 右向左,其优先级:算术运算、逻辑非、关系运算、逻辑运算。 在逻辑运算中, 1、在一个&&表达式中,若&&的一端为0,则不必计算另一端,该表达式的值为 0。(&&是自左向右的结合方式,&&左端为0则表达式的值为0) 2、在一个||表达式中,若||的一端为1,则该表达式的值为1 ㈢条件运算 (条件表达式? 表达式1:表达式2) 当条件表达式成立时,其值为表达式1的值,否则为表达式2的值 例如:求两个数中的最大数main() {/*求二个数的最大值*/float a,b,scanf(%f,%f‖,&a,&b); printf(Dmax is %f\n‖,a&b?a,b); } 例如:输入一个字符,判断它是否是大写字母,如果是,将其转换 成小写字母,若不是则不转换,输出最后得到的字符。 开始定义ch变量存放一个字符main() { scanf(%c‖,&ch); printf(Dmax is %c\n‖,ch); } Ch=ch+32 y Ch&‘A‘且ch&?Z‘ 输入一个字符ch=(ch&‘A‘&&ch&?Z‘? (ch+32):ch);输出ch结束 §2.4 不同类型数据之间的转换2.4.1 几个概念C语言允许数据从一种类型转换为另一种类型:同一类型不同长度数据间的 转换,定点方式与浮点方式间的转换,带符号和不带符号间的转换。1.提升和降格由低级的数据转换为高级的数据,称为提升。由高级的数据转换为低级的 数据,称为降格。 2.符号位扩展与零扩展 将signed升为长signed,若为正新增加的位为0,为负新增加的闰为1。 将unsigned升为长unsigned,新增加的位全为0,称为零扩展。 3.最高位失去符号功能与最高位变成符号位 由signed型转换为ussigned时 ,原符号位不再作为符号位,而成为数据的一 部分,对于负数据转换为无符号数时,数值将发生变化,对正数其值不变。 由unsigned型转换为signed时 ,各个二进制均不变,仅将高位作为符号位。 最高位作为符号位,也可能发生数值的改变。 4.截支小数与四舍五入:实数转换为整数时,舍支实数的小数部分。由double转 换为float型时,去掉多余的有效数字,并按四舍五入处理。 5.丢失精度 6.结果的不确定与截去高位。 2.4.2 不同类型数据的隐式转换 C语言中的数据类型的转换可分为隐式转换和显式转换(见书上40页) 1.一般算术转换: ①将短的数扩展成机器处理的长度 ②使运算符两端具有共同的类型 其转换的原则见书上(40页) 3输出转换在数据的隐式转换中要注意的问题: ①负数转换为无符号数据,符号位被作为数值的一部分。 ②较长类型转换为较短类型,当不超范围时正确。 ③实数转换为整数时,当实数值超过整数最大值时也会发生类似错误。.2.赋值转换:可自动将等式右边表达式的值的类型自动转换为其左边变量的类型。 2.4.3 不同类型数据的显式转换其格式为:(类型标识符)表达式例如: i=(int)13.4*x; 各种类型的标识符都可以用来作显示转换运算符,其格式必需用圆 括号括起来。在转换过程中原变量类型不变。 §2.5 数据的输入和输出 C语言中的输入输出由函数来实现,C语言提供了多种输入输出 函数,标准I/O函数写在头文件stdio.h中,使用标准函数时,一般 应在程序开头加写预编译命令: #include Dstdio.h‖ 2.5.1 printf函数 其一般形式为:printf(格式控制参数,输出项表) 格式控制符为:% - 0 m.n l或h 格式字符 %格式说明的起始符号、―指定左对齐输出、0指定空位填0、 m.n指定输出域宽及精度、l或h输出长度修正、指定输出类型。 1、格式字符见表2.7 2、长度修正符l或h:其中l是针对长整型long,如:%ld、%lX等。 h针对的是将整型数据修正为短整型short如:%hd、%hX等。 3、m.n域宽及其精度m:指域宽,即对应输出项所占的字符数。n:指精度,用于说明实 数输出的小数位数,不指定n按n=6输出。见表2.8注意:输出数据的实际精度并不主要决定于格式项中的域宽和精 度,也不决定于输入的数据精度,而主要决定于数据在机器内的 存储精度。增加域宽与精度并不能提高输出数据的实际精度。 4、用0指定输出数字前的空位是否用0填补:如 int a=13printf(D%05d‖,a) 输出结果:00013 5、负号用于输出是否左对齐,不加负号或加正号为右对齐 6、输出项可为常量、变量和表达式: 例: 两个整数以不同的格式输出。例3.1:main(){int a=15; long b=38988;程序运行结果为: | 15| 15|00015|15 | | 38988|a= 15| b= 38988|printf(‖%d‖,a);printf(‖%5d‖,a); printf(‖%05d‖,a); printf(‖%-5d\n‖,a);printf(‖%8ld‖,b);printf(Da=%8db=%8ld‖,a,b);} a、b两个整数按不同进制数据的输出 例3.2:main() {int a=15,b=-15; printf(‖%d,%d\n‖,a,b); /*以十进制形式输出*/ printf(‖%o,%o\n‖,a,b); /*以八进制形式输出*/ printf(‖%x,%x\n‖,a,b); /*以十六进制小写形式输出*/ printf(‖%X,%X\n‖,a,b); /*以十六进制大写形式输出*/ printf(‖%u,%u\n‖,a,b); } /*以无符号数的形式输出*/ 程序执行结果为:15,-15 17,177761 f,fff1 F,FFF1 15,65521 ⑶m.n域宽及其精度 m:指域宽,即对应输出项所占的字符数。n:指精度,用于说明实 数输出的小数位数,不指定n按n=6输出。 例3.3:main() {float a=555.; double b=555.,c=-5.e-9; printf(‖%f\n‖,a); printf(‖%lf\n‖,c); printf(‖%a=15.9f,b=%15.9f\n‖,a,c); printf(‖%.10f%.10f\n‖,a,c); printf(‖%2.5f‖,b); 其程序运行结果为: } 555...5.5. -0. 555.12346 ⑷ %c格式符,用来输出一个字符。main() { char ch=‘A‘;printf(Dch=%c\n‖,ch);} 其程序运行结果为:ch=A ⑸ %s格式符,用来输出一个字符串。main(){ printf(D%s\n‖,‖computer‖); } 其程序运行结果为: computer ① %ms,输出的字符串占m列,如字符串本身长度大于m,则 突破m的限制,将字符串全部输出。若串长小于m,则左补空格。 ②%-ms,如果串长小于m,则在m列范围内,字符串向左靠, 右补空格。 ③%m.ns,输出占m列,但只取字符串中左端n个字符。这n个 字符输出在m列的右侧,左补空格。 ④ %-m.ns,其中m、n含义同上,n个字符输出在m列范围的左 侧,右补空格。如果n&m,则m自动取n值,即保证n个字符正常 输出。 例3.5 字符串的输出。 main() {printf(D%3s,%8.3%.3%-5.3\n‖,‖computer‖, ‖computer‖,‖computer‖,‖compute‖);} |computer| com|com|com | 2.5.2scanf函数1.其一般形式为:scanf(格式控制参数,地址表) 地址表可为变量 的地址或字符串的首地址。2.格式控制符为:% * m l或h 格式字符格式控制符与printf函数类似。输入流数据分隔:①根据格式字符有含义从输入流中取得数据,当输入流中数据 类型与格式字符要求不符时,即该数据项结束。例:main(){printf(Dinput a,b,c‖); scanf(D%d%c%f‖,&a,&b,&c); printf(Da=%d,b=%c,c=%f‖,a,b,c);} ②根据格式项中指定的域宽分隔出数据项。例:main() {int a,b;float c,d;printf(Dinput a,b,c,d‖);scanf(D%4d%2d%5f%3f‖,&a,&b,&c,&d); printf(Da=%d,b=%d,c=%f,d=%f‖,a,b,c,d);} ③用分隔符:空格、跳格符、换行符来确定数据分隔。见例2.16 ④抑制字符*:在格式说明读入数据后不送给任何变量。例:scanf(D%4d%*2d%5f%3f‖,&a,&c,&d);输入456789 a=1234,c=,d=345.000000 3. scanf的停止和返回Scanf函数在执行中遇到以下情况时结束运行①格式参数中的格式项用完――正常结束: ②发生格式项与输入域不匹配时――非正常结束。 例: main() {int a,b;printf(D%d\n‖,scanf(D%4d-%2d-%3f‖,&a,&b,&c);printf(Da=%d,b=%d,c=%f‖,a,b,c);} 注意:此例中scanf函数出现在printf函数中作为输出项,程序 运行时先按scnaf函数的要求输入数据,再由printf函数把在输 入时匹配成功的数据项数输出。运行结果: 输入的数据项3a=1234,b=56,c=789.000000scanf函数的返回值输出的数据项 运行结果: 2 a=1234,b=56,c=79.000000输入的数据项 scanf函数的返回值 输出的数据项只有前两项成功匹配,scanf函数的返回值为2,c变量的值为 随机数。非正常终止。 4.scanf函数与输入缓冲区 在输入数据时,当键入一个回车键时,先将数据项送入缓冲区 中,再按scanf函数的格式说明从缓冲区读数,若输入的数据多 于scanf函数的数目,则可作为下一个输入函数使用。 5、 scanf函数的使用应注意的问题: ⑴ scanf函数中的“格式控制”后应该是变量的地址,不能是变 量⑵若“格式控制”字符串中除格式说明以外还有其它字符, 则输入数据应该输入与这些字符相同的字符。 ⑶使用%c格式输入字符时,空格字符、转义字符都作为有效字 符输入。(输入、输出函数在上机时注意理解掌握) 2.5.3getchar函数与putchar函数getchar函数是从标准输入设备上读入一个字符。putchar函数是将字符变量 中的字符输出到标准输出设备上,其格式为:getchar() 不带参数 putchar(c)含一个形式参数。 例如:输入任意三个字母,如果其中有小写字母将其转换为大写字母输出。 #include Dstdio.h‖ main() {char ch1,ch2,ch3; ch1=getchar(); ch2=getchar(); ch3=getchar(); if (ch1&=?a‘&&ch1&=?z) ch1=ch1-32; if (ch2&=?a‘&&ch2&=?z) ch2=ch2-32; if (ch3&=?a‘&&ch3&=?z) ch3=ch3-32; putchar(ch1); putchar(ch2); putchar(ch3);} 本章考核要点:掌握C语言中数据类型的意义,常量和 变量的定义、赋值的方式,掌握算运算中的自反算术赋 值运算、自增自减运算、关系运算、逻辑运算与条件运 算的使用,C语言表达式的运算规则,不同类型数据间 的转换,C语言的标准输入和输出函数的格式及其使用。 第三章 C程序的流程设计? 教学要点:程序设计的三种基本结构,算法的描述,用 C语句描述算法,选择型程序的设计,循环型程序的设 计。 ? 教学内容:算法的概念、程序设计的三种基本控制结构, 用流程图、N-S图描述算法,表达式语句的三种基本类 型,选择型程序的设计的三种语句:IF…ELSE结构的 应用、ELSE IF结构的应用、SWITCH结构的应用。循 环 型 程 序 的 设 计 的 三 种 语 句 : WHILE 结 构 的 应 用 、 DO…WHILE结构的应用、FOR结构的应用,三种限定 转向语句:break语句、continue语句、函数调用与返 回return语句,结束程序EXIT函数。 §3.1 算法程序是在数据的某些特定表示方式和结构的基础上对抽 象算法的具体描述。即程序=数据结构+算法。3.1.1算法的性质和组成要素㈠算法的性质 算法是进行操作的方法和操作的步骤。 ㈡算法的组成要素:包括操作和控制结构(顺序结构、分 枝结构、循环结构) 3.1.2算法的描述㈠流程图与算法的结构化开始/结束框 特定处理框 输入/输出框 判断框 流程线 连接点处理框1。顺序结构A B2.发枝结构判断 Y N3.循环结构循环条件 N Y 循环体 用N-S图表示:顺序结构A B Y分支结构条件 N循环结构条件成立执行A A BCD或执行A条件成立E 用PAD图表示: 顺序结构分支结构循环结构A PA P B 循环体B 用PDL语言表示:自然语言 DO WHILEIFELSEendifenddo §3.2 用C语句描述算法程序是对计算机要执行的一组操作序列的描述。高级语言 源程序的基本组成单位是语句,语句通常分为:描述计算机要 执行的操作运算,另一类是控制操作运算的执行顺序的语句。 3.2.1 表达式语句C语言是一种表达式语言,表达式语句分为三种基本类型: ①赋值语句:由赋值表达式加一个分号组成。如 i=1; ②函数调用语句:由函数调用语句加一个分号组成。如: getchar(); ③空语句:只有一个分号没有表达式的语句。如: ; C语言允许把几个表达式组合在一起,形成一个复合型表达式 语句,即逗号表达式。其值为最后一个表达式的值。如:a=(a=6,a*3,a+3); 3.2.2 控制结构的语句:一、选择型结构(if…else 语句):if语句是用来判定所给定的条件 是否满足,根据判定的结果决定执行给出的两种操作之一。二、循环控制语句:循环控制结构由三部分组成:进入条件、退出 条件、循环体。其语句分为:while语句、do-while语句、for语句。 三、限定转向语句: break语句:在循环结构或多选择结构中,遇此语句,使程序转 到循环体外或多选择结构之后。 continue语句:使本次循环体的执行提前结束,再由循环条件决定 是否进入下一次循环。函数调用和返回语句:使流程从被调用的函数返回主调函数节器。四、无条件转向语句:goto语句使程序无条件转向所指向的语句。 五、停止函数exit():其作用是立即停止当前程序的运行,并返 回到操作系统。 一、顺序结构的程序设计例1:输入一个无符号的整数a和一个整数b,分别以十进制、八 进制、十六进制、不带符号的十进制整数输出。main() 定义二个变量a、b 分别给a、b赋值 以四种方式输出a的值{ scanf(D%u,%d‖,&a,&b); printf(Da=%d%o%x%u\n‖,a,a,a,a); printf(Db=%d%o%x%u\n‖,b,b,b,b);}以四种方式输出b的值结束输入:65535,-2 运行结果为:a=-1,177777,ffff,65535b=-2,177776,fffe,65534 例2:输入三角形的三边长,求三角形的面积,输出三边长及面积。 #include &math.h& 定义a,b,c,s,area 输入a,b,c三边长 求三边长和的一半 求三角形的面积 输出三边的长 输出三角形的面积 结束 } main() { float a,b,c,s, printf(Dinput a,b,c‖); scanf(D%f%f%f‖,&a,&b,&c);s=(a+b+c)/2;area=sqrt(s*(s-a)*(s-b)*(s-c)); printf(Da=%7.2f,b=%7.2f‖,a,b); printf(Dc=%7.2f\n‖,c); printf(Darea=%7.2f\n‖,area); 例3:读程序,写出下列程序运行的结果。main(){int a=5,b=7; char c=?A‘; float x=67.8564,y=-789.124; long n=1234567; unsigned u=65535;printf(D%d%d\n‖,a,b);printf(D%3d%3d\n‖,a,b); printf(D%f,%f\n‖,x,y);57 5 7 67.9..9..,-7.89e+02 A,65,101,41 printf(D%-10f,%-10f\n‖,x,y);printf(D%e,%10.2e\n‖,x,y);printf(D%8.2f,%8.2f,%.4f,%.4f,%3f,%3f\n‖,x,y,x,y,x,y);printf(D%c,%d,%o,%x\n‖,c,c,c,c);printf(D%ld,%lo,%x\n‖,n,n,n); printf(D%u,%o,%x,%d\n‖,u,u,u,u);,ffff,-1 printf(D%s,%5.3s\n‖,‖COMPUTER‖,‖COMPUTER‖);} COMPUTER,COMPU 例4:设圆半径r=1.5,圆柱高h=3,求圆周长、圆面积、圆球表面 积、圆球体积、圆柱体积。用scanf函数输入数据,输出计算结果。 (保留两位小数) #include &math.h&#define PI 3.1415main() float r,h,p,s1,s2,s3,v1,v2; scanf(D%f,%f‖,%r,%h); printf(Ds1=%8.2f\n‖,2*PI*r);printf(Ds2=%8.2f\n‖,PI*r*r);printf(D%8.2f\n‖,4*PI*r*r); printf(Dv1=%8.2f\n‖,4*PI*r*r*r/3); printf(Dv2=%8.2f\n‖,PI*r*r*h);} 一、选择型结构(if 语句)if语句是用来判定所给定的条件是否满足,根据判定的结果 (真或假)决定执行给出的两种操作之一。㈠ if语句的三种形式:⒈ if (条件表达式)例如:求一个数的绝对值 main() {条件表达式语句序列 定义x为型 输入x Y |x|=-xscanf(D%f‖,&x);if (x&0) x=-x;X&0Nprintf(D%f\n‖,x);}输出x 2.if(条件表达式)语句1else 语句2 例如:求一个数的绝对值 main() {定义x为型 输入x Y|x|=-x 输出x X&0N|x|=xscanf(D%f‖,&x);if (x&0) x=-x;elseX=x; printf(D%f\n‖,x);} 例如:输入3个数a,b,c,要求按由小到大的顺序输出。main(){ float a,b,c,t: scanf(D%f,%f,%f‖,&a,&b,&c); if(a&b)If a&b a与b交换 If a&c a与c交换 If b&c b与c交换 顺序输出a,b,c{t=a;a=b;b=t;}if(a&c) {t=a;a=c;c=t;} if(b&c) {t=b;b=c;c=t;}printf(D%5.2f,%5.2f,%5.2f‖,a,b,c); 3. if(条件表达式1)语句1else if (条件表达式2)语句2else if (条件表达式3)语句3 …… else if (条件表达式m)语句m else 语句n条件表达式1 条件表达式2 条件表达式3 条件表达式4语句1…语句1 语句1 语句1 语句1 例如:-1(x&0)y=01(x=0)(x&0)main() { Int x,y; scanf(D%d‖,&x); if(x&0) y=-1; else if (x==0) y=0; else y=1; printf(D%d‖,y);} 4.if语句的嵌套if ()if () 语句1 else 语句2elseif () 语句3 else 语句4(见74页例3.6题) If语句的应用举例:例如:运输公司对用户计算运费。路程越远,每公里运费越低。S&250km 不打折 1000≤s&2000 8%折扣 250≤s&500 2%折扣 2000≤s&3000 10%折扣 500≤s&1000 5%折扣 3000≤s 15%折扣main (){ int c,s; float p,w,d,f; scanf(D%f,%f,%d‖,&p,&w,&s);if (s&250)d=0;else if(s&=250&&s&500) d=0.02; else if(s&=500&&s&1000) d=0.05; else if(s&=1000&&s&2000) d=0.08; else if(s&=2000&&s&3000) d=0.1; else d=0.15; f=p*(1-d)*w*s; printf(Dp=%5.2f,=%5.2f,d=%.2f,f=%5.2f\n‖,p,w,d,f); } main () { int c,s; if (s&250) d=0; else if(s&=250&&s&500) d=0.02; else float p,w,d,f; scanf(D%f,%f,%d‖,&p,&w,&s);if(s&=500&&s&1000)d=0.05; else if(s&=1000&&s&2000) d=0.08; else if(s&=2000&&s&3000) d=0.1; else d=0.15; f=p*(1-d)*w*s;printf(Dp=%5.2f,=%5.2f,d=%.2f,f=%5.2f\n‖,p,w,d,f);} 例2:求一元二次方程ax2+bx+C=0的根。 Y Y 无解 b=0 X=-c/b a=0 N Y N d=b*b-4*a*c d&=0 N输出两实根 输出实部、虚部 Y 无解 a=0&&b=0 N Y X=-c/b d=b*b-4*a*c a!=0 NYa=0&&b!=0d&=0 Y N 输出两实根 输出实部、虚部 #include Dmath.h‖ main() {float a,b,c,d,p,q; scanf(D%f,%f,%f‖,&a,&b,&c); if (a==0) if (b==0) printf(Dno answer\n‖); else printf(Dx=%f\n‖,-c/b);#include Dmath.h‖main(){float a,b,c,d,p,q; scanf(D%f,%f,%f‖,&a,&b,&c); if (a==0&&b==0)printf(Dno answer\n‖);else if(a==0&&b!=0) printf(Dx=%f\n‖,-c/b); else if(a!=0) {d=b*b-4*a*c; p=-b/(2*a); q=sqrt(fabs(d)/(2*a));else{d=b*b-4*a*c; p=-b/(2*a); q=sqrt(fabs(d)/(2*a)); if d&=0 printf(Dx1=%f\n‖,p+q); printf(Dx2=%f\n‖,p-q);if d&=0printf(Dx1=%f\n‖,p+q); printf(Dx2=%f\n‖,p-q); elseelseprintf(Dp=%f,q=%f\n‖,p,q);} } } }printf(Dp=%f,q=%f\n‖,p,q); 3.3.3 switch结构的应用switch结构与else if结构是多分支选择的两种形式,if结构用于多条件并列选择, 选择其中满足条件条件的一种,switch结构用于单条件测试,从其多种结果中取 一种情形。switch结构的执行过程为:进入switch结构后,对条件表达式进行计算,然 后从上到下去找与条件表达式的值相匹配的case,以此为入口,执行switch结构 后面的各语句。 switch语句的一般形式如下:switch ( 表达式){case 常量表达式1:语句1 case 常量表达式2:语句2case 常量表达式3:语句3case 常量表达式n:语句ndefault :语句n}… 说明:①switch后面括弧内的“表达式”,ANSI标准允许它为任何类型, 但不能含有变量与函数的常量表达式,通常是整数表达式或字符表达 式。②当表达式的值与某一个case后面的常量表达式的值相等时,就执 行case后面的语句,若所有的case中的常量表达式的值都没有与表 达式的值匹配的,就执行default后面的语句。 ③每一个case的常量表达式的值必须互不相同,否则就会出现互相 矛盾的现象 ④各个case和default的出现次序不影响执行结果,⑤执行完一个case后面的语句后,流程控制转移到下一个case继续 执行,在执行完switch语句时,根据switch后面表达式的值找到匹 配的入口标号,就从此标号开始执行,不再进行判断。⑥多个case可以共用一组执行程序。 例如:运输公司对用户计算运费。路程越远,每公里运费越低。S&250km 500≤s&≤s&3000 main () { int c,s; float p,w,d,f; scanf(“%f,%f,%d”,&p,&,&s); if (s&=3000) c=12; else c=s/250; 不打折 5%折扣 10%折扣 250≤s&500 2%折扣1000≤s&2000 8%折扣 3000≤s 15%折扣case 4:case 5: case 6: case 7:d=8;case 8:case 9: case 10: case 11:d=10; case 12:d=15;switch (c){ case 0:d=0; case 1:d=2; case 2: case 3:d=5;}F=p*w*s*(1-d/100);Printf(“fright=%15.4f”,f);} Else if和switch的比较例如:输入一个成绩判断并输出等级g&60 70&=g&80 输出E 输出C 60&=g&70 80&=g&90 输出D 输出Bmain() {int g,c; c=(int)(g/10); switch c {case 0: case 1: case 2:90&=gmain () {输出Ascnaf(“%d”,&g); if (g&60) printf(“E”); else if (g&=60&&g&70) printf(“D”); else if (g&=70&&g&80) printf(“C”); else if (g&=80&&g&90) printf(“B”); else if(g&=90) } printf(“A”);case 3;case 4; case 5:printf(“E”); case 6:printf(“D”); case 7:printf(“C”); case 8:printf(“B”); default printf(“A”); } } §3.4循环型程序设计3.4.1穷举与迭代算法循环是计算机解题的一个重要特征,在循环算法中穷举与迭代是两类具有代 表性的应用。一、穷举法:对问题可能出现的状态进行一一测试直到找出所有解为止。例如:搬砖问题。 二、迭代法:不断用新值取代变量的旧值。例如:兔子繁殖问题等。3.4.2 循环结构的语句: ①用goto语句和if语句构成的循环; ②用while语句 ③用do―whiel语句 ④用for语句 一、goto语句以及用goto语句构成的循环goto语句是一个无条转向语句,其一般形式为: 表达式 goto 语句标号; Y goto 语句有两种用法: 循环体1、与if语句一起构成循环。N2、从循环体内转到循环体外,(此种用法较少,常用break语句 或continue语句跳出循环。 例如:求6! main(){ int i=1,p=1;loop: if(I&=6) {p=p*i;i++;} printf(D%d‖,p); } 二、while语句while的一般形式:whlie (条件表达式) {循环体语句;} 例如:求6! main() 表达式循环体{ int i=1,p=1;while(i&=6) {p=p*i; i++;} printf(D%d‖,p);} 三、do-while语句do-while的一般形式:do {循环体语句;} whlie (条件表达式)例如:求6! main() { int i=1,p=1; do循环体 N 表达式 Y{ p=p*i;i++;} while(i&=6);printf(D%d‖,p);} 四、for语句for语句的一般格式:for (表达式1;表达式2;表达式3) {循环体语句}①先执行表达式1(循环中只执行一次) ②求解表达式2,若为真,执行循环体一次,若为假,则结束循环,执行for后面 的语句。③执行表达式3;返回②例如:求6! main()求解表达式1 N 表达式2 Y 循环体语句 求解表达式3 For 后面的语句{ int i,p;for(I=1,p=1;I&=6;I++;) p=p*i; printf(D%d‖,p); 说明:①for语句的一般形式中“表达式1‖可以省略,但其后的“;”不能省略, 在for之前应先给循环变量赋初值。 如:i=1;for(;i&=6,i++) ②表达式3也可以省略,但在循环体中应有改变循环变量的语句。 如:for (i=1;i&=6;) {p=p*i; i++;} ③3个表达式都省略,无终止地执行循环体。 如:for(; ;) ④表达式2一般为关系表达式如(i&10),但也可以是数值表达式或字符表达式,其 值为非零就执行循环体。如:for (i=0;(c=getchar())!=?\n?;i+=c) 只要输入的不是换行符就执行循环。 ⑤ for语句后加一个“分号”,表示for语句无循环体或循环体是一个空语句。如:for (i=0;(c=getchar())!=?\n?;i+=c) ; 五、循环的嵌套③while(){…… do {……} while();①while(){…… while() {……} }{……}} ④do {…… for(;;) { ……} while(); }② do{…… do {……} while();} ⑤ for(){……for() { ……} } ⑥ for( ){……while() {……} } 例如:找出100到200之间的所有素数产生一组数100-200,用m表示,当I&m的平方根时,分别用m除 I,求其余数,不能整除则是素数,能整除则退出循环。 #include&math.h&#include&math.h& main() { int m,k,I,n=0,p=0; for (m=101;m&=200,m=m+2) { k=sqrt(m);main(){ int m,k,I,n=0;for (m=101;m&=200,m=m+2){ k=sqrt(m);for(i=2;I&=k;i++)if (m%i==0) if(I&=k+1)for(i=2;I&=k;i++)if (m%i==0) p=1; if(p=0){printf(D%d‖,m);n=n+1;if (n%10==0) printf(D\n‖);} }{printf(D%d‖,m);n=n+1;if (n%10==0) printf(D\n‖);}printf(D\n‖);}}printf(D\n‖);} 循环结构应用举例:㈠、穷举法:(书上85页例3.18)例1:百钱买百鸡,鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱 一,问鸡翁、鸡母、鸡雏各几何?定义xyz为整型main() { int x,y,z; for (x=0;x&=20;x++) { for (y=0;y&=33;y++) {z=100-x-y; if(5*x+3*y+z/3==100) printf(D%5d%5d%5d\n‖,x,y,z); } } 5*x+3*y+z/3=100 y&=33 结束nX=0 X&=20y=0ynx++Y++z=100-x-yyny}输出x、y、z 例2:爱因斯坦的阶梯问题。(书上87页)设有一阶梯,每步跨2阶,最后余1阶;每步跨3阶,最后余2阶;每步跨5阶, 最后余4阶;每步跨6阶,最后余5阶;每步跨7阶,正好到阶梯顶。问共有多少阶? 设总阶数为a,则有如下算法: ①a%2=1; (则阶梯数为奇数) ②a%3=2; ③a%5=4; ④a%6=5; ⑤a%7=0 (阶梯数为7的倍数)由条件①和条件⑤可知,此阶梯数可能 为7,7+14,7+14+14,……从②③④条件中找出符合条件的阶梯数。main(){int a=7; while(a%3!=2||a%5!=4||a%6!=5) a+=14;main(){int a=7; loop: if (a%3!=2||a%5!=4||a%6!=5) a+=14;printf(Dflight of stairs=%d\n‖,a);}printf(Dflight of stairs=%d\n‖,a);} ㈡、迭代法:例3:如果我国工农业产值每年以8%增长,问几年后我国产值 翻一番。设原来p=100,n年后产值将达到或超过p&=200。main() {float p=100,r=0.08; int n=0; while (p&=200) {p=p*(1+r); n++;} printf(Dyear=%d‖,n); } main() {float p=100,r=0.08;int n=0;do {p=p*(1+r);n++;}while (p&=200); printf(Dyear=%d‖,n);} 例4:一球从100m高度自由落下,每次落下后反跳回原高度的 一半,再落下,求它在第10次落地时,共经过多少m?第10次反 弹多高? 第一次下落s=h=100,第二次反弹和下落高度h=h/2;路程 s=s+2hmain() { float s=100,h=s/2;for (n=2;n&=10;n++) {s=s+2*h;h=h/2;}printf(Ds=%f‖,s); printf(Dh=%f‖,h);} 例5:有一数列,前两项是1,1,第三个是前两个之和,以后的每 个数都是前两个数之和,求此数列的前20项。 1,1,2,3,5,8,13…… 设f1=1,f2=1,f3=f1+f2 f1=f2,f2=f3main() {int I;long f1=1,f2=1,f3;printf(D%ld%ld‖,f1,f2); for (i=3;i&=20;i++) {f3=f1+f2; f1=f2; f2=f3; printf(D%ld‖,f3);} } ㈢一元高次方程的求解:⒈二分迭代法(见书上81页) 先取f(x)=0的两个粗略解x1和x2。 求出f(x1) f(x2) ,输入x1和x2 fx1=f(x1),fx2=f(x2) 直到fx1和fx2不同号 X3=(x1+x2)/2 fx3=f(x3)②若f(x1) 与f(x2)符号相反,则方 程 f(x)=0在区间(x1,x2)中至 少有一个根,若f(x)在区间 (x1,x2)内单调,则(x1,x2)间 有一个实根 ,x3=(x1+x2)/2,并 在x1与x2中舍去函数值与f(x3)同 号者,x3与剩下的一个解组成一 新的区间,再求下一个点,直 到|xn-xn-1|&δ时, xn即为所求 的近似解。③若f(x1) 与f(x2)符号相同,返回 ①,重取x1和x2Tfx1和fx3不同号FX2=x3 Fx2=fx3X1=x3 Fx1=fx3直到|x2-x1|&δ 输出x例:求方程2x3-4x2+3x-6=0在 (-10,10)之间的根。(程序) #include&math.h& Main(){ float x1,x2,x3,fx1,fx2,fx3;do {printf(Denter x1, x2:‖); scanf(D%f,%f‖,&x1,&x2);fx1=x1*((2*x1-4)*x1+3)-6;fx2=x2*((2*x2-4)*x2+3)-6; } while (fx1*fx2&0); do {x3=(x1+x2)/2; fx3=x3*((2*x3-4)*x3+3)-6; if ((fx1*fx3)&0) {x2=x3; fx2=fx3;} else {x1=x3;fx1=fx3;} } while (fabs(x2-x1)&=0.00001); printf(Dx=%6.2\n‖,x3); } ⒉牛顿迭代法:(见书上82页)①设X1是方程f(x)=0的一个真 实根x的近似根 ②求f(x1) ③过f(x1)作曲线f(x)的切线, 交x轴于x2.输入近似根x X1=x 求f(x1)求f(x1)的导数f1④求出x2:x2=x1-f(x1)/f‘(x1)⑤若|x1-x2|&=δ,x2=x1;返回 ②重复求x2,否则所求的近似 解为x2.例:求方程2x3-4x2+3x-6=0在 (-10,10)之间的根。(程序)求x=x1-f(x1)/f1|x1-x|&=0.00001输出x #include&math.h& main() { float x1,x,f,f1; printf(Denter x:‖); scanf(D%f‖,&x); do {x1=x;f=x1*((2*x1-4)*x1+3)-6;f1=(6*x1-8)*x1+3); x=x1-f/f1;}while (fabs(x-x1)&=0.00001); printf(Dx=%6.2\n‖,x);} 输入两个正整数m和n,求其最大公约数和最小公倍数。main() {int p,r,n,m,t; scanf(D%d,%d‖,&n,&m); if(n&m){t=m;m=n;n=t;} p=m*n; /*用于求最小公倍数*/ while(m!=0){r=n%m;n=m; m=r;} printf(Dmax=%d,min=%d‖,n,p/n);} 读程序:阅读下列程序,回答问题。main() { int I,j,k;1、程序运行后的图案为()2、去掉注释语句的注释标记,程 序输出的图案是()char ch=?*‘,space=?‘;printf(D\n‖); for(i=0;i&=3;i++) {for(j=0;j&=2;j++) printf(D%2c‖,space); for(k=0;k&=2*I;k++) printf(D%2c‖,ch); printf(D\n‖); } /*for(i=0;i&=3;i++) printf(D%8c\n‖,ch);*/} 2、main(){int a,b;for(a=1,b=1;b&=20;b++) {if (a&10) if (a%2==1){a+=5;} a-=3;} printf(Da=%d,b=%d\n‖,a,b); }程序运行后,a和b的值为() 编程完成打印乘除九九表。(91页)怎样输出直角三角形的九九表? main() {int i,j; for(i=1;i&=9;i++)printf(D%4d‖,i);printf(D\n‖); for(i=1;i&=36;i++) printf(D%c‖,‘-‘); printf(D\n‖); for(i=1;i&=9;i++) { for(j=1;j&=9;j++)printf(D%4d‖,i*j);}printf(D\n‖);} } 考核要求:掌握流程图、N-S图描述算法、用C语句描 述算法;表达式语句,掌握IF…ELSE结构、ELSE IF结 构、SWITCH结构选择语句的应用。掌握WHILE结构、 DO…WHILE结构、FOR结构循环语句的应用,掌握三 种限定转向break语句、continue语句、函数调用与返 回return语句的应用,程序结束EXIT函数的应用,掌握 选择结构的一些简单程序和循环结构的一些简单程序 设计。 作业1、求s=a+aa+aaa+aaaa+……+aaa ……aa之和。(例 如: 2+22+222+),n用输入函数输入。2、求 1!+2!+3!+……+10!3、打印以下图案。* *** ***** ******* ***** *** *4、猴子吃桃子,第一天摘下桃子若干,吃掉一半,又多 吃一个,第二天又吃掉余下的一半,又多吃一个。以后 每天都吃前一天剩下的一半零一个,到第10天,只剩下 一个桃子,求第一天共摘多少桃子。 上机步骤:开机――桌面――开始――程序――MS-DOS c:\windows&cd\tcC:\tc&tc进入C的编译窗口 1、选FILE下的NEW,输入源程序 2、选COMPIL下的COMPIL TO OBJ――编译(可不做) 3、选COMPIL下的MAKE EXE FILE――连接 4、执行程序:选RUN下的RUN或按CTRL- F9或按F10功能键 5、按F5功能键查看运行结果。6、上机结束按ALT-X退出C系统――按EXIT返回windows main()/*习题1*/{int a,n,i,s,k; printf(Dinput:a,n‖); scanf(D%d%d‖.&a,&b);Int a,n,I=1,s=0,k=0;For (I=0,s=0,k=0;i&n;i++){k=k*10+a; s=s+k;}printf(Da+aa+aaa+……+……=%d\n‖,s);} main() /*习题2*/ { float s,t; for (i=0,s=0,t=1;i&=10;i++) {t=t*i;s=s+k;}While(I&=n) {K=k*10+a; s=s+k; I++;}printf(D1!+2!+3!+……+10!=%f\n‖,s);} main(){int I,j,k;char ch=D‖ for (i=1;i&=4;i++){for (j=1;j&=4-i;j++)printf(D%c ‖,ch); for (k=1;k&=2*i-1;k++)printf(D*‖);printf(D\n‖);} for (i=3;I&=1;I--){for (j=1;j&=4-i;j++)printf(D %c‖,ch); for (k=1;k&=2*i-1;k++)printf(D*‖);printf(D\n‖);} } 4、编程方式一main() {int day,x1,x2;编程方式二main() {int day,x1,x2;day=9;x=1; while (day&0) {x=(x+1)*2; day--;}for (day=9,x=1;day&0,day--)x=(x+1)*2; printf(Dtotal=%d\n‖,x) }printf(Dtotal=%d\n‖,x)} 5、编程完成以下程序,输入50个学生的成绩,求平均分, 最高分和最低分。 定义变量i,x,s,ave,max,min 输入第一个成绩x,max=min=s=x 循环变量赋初值x=2 N X&=50 Y S=s+x max&x Y Max=x N Min&x Y Min=x NAve=s/50输出ave,max,minI++结束 6、百马百担问题,有100匹马,驮100担货,大马驮3担,中 马驮2担,两匹小马驮1担,问有大中小马各多少?x+y+z=100 3x+2y+z/2=100 main() {int x,y,z; for (x=0;x&=33;x++) for(y=0;y&=50;y++) 定义x,y,z X=0 X&=33 y=0 Y&=50 z=(100-3x-2y)*2 X+y+z=100 y n 输出x,y,z{z=(100-3*x-2*x)*2if(x+y+z==100) printf(D%d%d%d‖,x,y,z);} } 第四章模块化程序设计? 基本思想:将一个大的程序按功能划分为若干个 模块,使每一个模块具有独立的功能、结构清晰、 接口简单、易理解的小程序。 ? C语言具有如下功能: ⑴函数式的程序结构。一个程序由一个多个函数 组成。每个函数都具有各自独立的功能和明显的 界面。 ⑵可通过不同类型的变量,控制模块内部和外部 的诈的交换。 ⑶具有编译预处理的功能,为程序的调试、移植 提供了方便,支持了模块化的程序设计。 §4.1函数4.1.1C程序结构main() { …… f1(); …… f2(); …… }f1() { …… f11(); …… } f2() { …… f21(); …… F22(0; …… }f11() { …… }f21() { …… }f22() { …… } 程序设计的原则:由大到小、自顶向下、层层分解。在程序设计中,首先考虑main()主函数的算法,当主函 数中需要使用某一功能时,先写好调用的函数,只知道完 成的功能,如何与程序通信(数据的传递),主函数设计 好后再考虑其它的自定义函数。 main() f1() f11() f21() f2() f22() 4.1.2函数定义和函数声明㈠函数定义: 函数类型 函数名(形式参数的数目和类型){函数体; ……return(); (或用在void空类型函数中)} 见书上(104页)㈡函数的声明 在主函数中,需对本函数中要调用的函数进行声明。 函数类型 函数名(形式参数的数目和类型);注意:调用是在函数的有效域内,即同一个文件中位于定义之后 的调用。当被调用函数定义写在前面时,主函数写在后面时可省 略函数的声明语句。 函数的调用main(){变量的定义; 函数声明语句; …… 函数调用语句;函数定义开始函数类型 { 函数名(形式参数的数目和类型)函数体;…… return(); (或用在void空类型函数中) }……} 4.1.3函数的传值调用函数的参数包括实参和形参,实参是调用函数中的变量,形参 是被调用函数中的变量。在调用过程中实现实参和形参的结合。 传值调用的过程:(见书上109页) 其传递关系是:实参 形参 例如:找出100到200之间的所有素数#include&math.h& main() { int m,p,n=0; int primr(int x);Int prime(int a) {Int k,I; k=sqrt(a); for(i=2;I&=k;i++) {if (a%i==0)for (m=101;m&=200,m=m+2){ p=primr(m);return(0); } return(1); }if(p==1){printf(D%d‖,m);n=n+1; if (n%10==0) printf(D\n‖);}}printf(D\n‖); } 例如:找出100到200之间的所有素数 void prime(int a)#include&math.h& main() { int m,p,n=0; void primr(int x);{Int k,I,p=1; k=sqrt(a); for(i=2;I&=k;i++) if (a%i==0)for (m=101;m&=200,m=m+2)primr(m); }{ p=0;}if(p==1) {printf(D%d‖,m);n=n+1;if (n%10==0) printf(D\n‖);} 打印九九表(见书上91页)main(){ void put1(void);程序开始对被调用的函数进行声明void put2(void);void put3(void); put1();调用输出0―9的函数换行printf(D\n‖);put2(); printf(D\n‖);调用输出短―的函数换行put3();printf(D\n‖); }调用输出九九表的函数换行程序结束 void put1(void) { for (i=1;i&=9;i++) printf(D%4d‖,i); I++定义iI&=9输出i定义i}void put2(void) { for (i=1;i&=36;i++) printf(D%c‖,‘-‘);} void put3(void) { int i,j; for (i=1;i&=9;i++) for (j=1;j&=9;j++) printf(D%4d‖,i*j);} I++ I++I&=36输出- 定义ij 返回I&=9J++j&=9输出I*j返回 函数定义与函数声明的一般格式 main() { float f1(int x,float y); /*函数声明*/……} float f1(int x,float y) { 函数体; /*函数定义*/return(变量);} 4.1.4函数的嵌套调用C语言的函数定义是互相平行、独立的,不能将一个函 数定义在另一个函数体中,但允许在调用一个函数时又调 用另一个函数,即函数的嵌套调用。主函数main() {…… u=f1(a,b); ……} 函数f1() {…… c=f2(x,y); ……} 函数f2() {…………}例:用弦截法求方程x3-5x2+16x-80=0 的根。①取两个不同的点x1、x2,如果f1和f2符号相反,则(x1,x2)区间 内必有一个根,若则重输入x1、x2,直到f1、f2异号为止。②连接f1和f2交x轴于x,x=(x1*f2-x2*f1)/(f2-f1),求f ③f与f1同号,则根在(x,x2)区间x1=x, f与f1异号,则根在(x1,x) 区间x2=x。 ④重复②③,直到|f|&δ为止, δ为一个很小的数。 #include &math.h& Float f(float x) { y=((x-5)*x+16)*x-80; return(y);} Float xpoint(float x1,float x2) { y=(x1*f(x2)-x2*f(x10/(f(x2)-f(x1)); Return(y);}输入x1和x2 求f1=f(x1)、f2=f(x2) 直到fx1和fx2不同号求x=root(x1,x2) 输出求f1和f2交x轴于x Y=f(x)、y1=f(x1) Y与y1同号 yX1=x Y1=y X2=x Y2=yFloat root(float x1,float x2){int I; Float x,y,y1; Y1=f(x1); Do {x=xpoint(x1,x2); Y=f(x); If(y*y1&0) {y1=y;x1=x;} Else {y2=y;x2=x;} }hile ()fabs(y)&=0.0001; Return(x); }n|y|&δ Main(){ float x1,x2,f1,f2,x;do {printf(Denter x1& x2:‖); scanf(D%f,%f‖,&x1,&x2); f1=f(x1);f2=f(x2);} while (f1*f2&0); x=root(x1,x2); printf(Dx=%6.2\n‖,x);} 4.1.5函数的递归调用递归就是直接或间接调用自己,当调用若干次后,就应到达递归调用的终 点并得到一个确定值,然后进行回代,回代的过程是从一个已知值推出 下一个值,应注意递归方式和递归的终止条件。例:求n!的函数long rfact(int n){ if(n&0)main(){long rfact(int n); printf(Denter i‖); scanf(D%d‖,&i);{ printf(Dno\n‖);exit(-1); }else if (n&=1)return(1); else return(n*rfact(n-1)); }printf(Dld\n‖,rfact(i));} 例:汉诺塔问题(见书上113页)⒈先将n-1个盘子设法从a借助于b移到c,即hanoi(n-1,a,c,b)。 ⒉将第n个盘子从a移到b。 ⒊将c借助于a移到b,即hanoi(n-1,c,b,a). main() { void hanoi(int n,char a,char b,char c); printf(Denter n‖);scanf(D%d‖,&n);hanoi(n,‘a‘,‘b‘,‘c‘); }void hanoi(int n,char,char b,char c){if (n&0) {hanoi(n-1,a,c,b); printf(D\n Move disc %d from pile %c to %c‖,n,a,b); hanoi(n-1,c,b,a);} §4.2 变量的存储属性⒈变量的存储器类型:内存储器、外存储器、寄存器⒉变量的生存周期 ①永久存储:程序开始执行分配存储空间,到程序执行结束才被 撤销。 ②动态存储:只是在程序执行的某一段有效 ⒊变量的可用域:全局变量、局部变量(见书上115页表4.1) 存储属性是变量的重要特征,C语言要求,在定义变量时,指定变 量类型外还应指明存储类别。例如:static int a; auto float x,静态变量寄存器变量 自动变量 外部变量 4.2.1动态变量动态变量是在程序执行的某一时刻被动态建立并在另一时 刻被动态撤消的一种变量,它存在于程序的局部,在局部可 以使用。动态变量包括:自动变量(auto)和寄存器变量 (register)。 ㈠自动变量 定义:[auto] 数据类型 变量名[=初值表达式],……; 其中auto是自动变量的标识符,可省略。 说明:1.自动变量是局部变量,C语言规定,如果内存与 外存有相同的变量名,则在内存范围内只有内层变量有效, 此时外层的同名变量无效,即被“屏蔽”。 2.在对自动变量赋值之前,它的值是不确定的。3.对同一函数的两次调用之间,自动变量的值不保留 例如:读程序输出结果main(){ int x=1; { void prt(void);int x=3;prt(); printf(D2nd x=%d\n‖,x).}printf(D1st x=%d\n‖,x); }void prt (void){ int x=5; Printf(D3th x=%d\n‖,x);} ㈡寄存器变量寄存器变量与自动变量具有相同的性质,定义一个寄存 器变量 就将其放在CPU的一个寄存器中,通常将使用较 多的变量定义为寄存器变量(循环变量)。当定义的寄 存器变量超出寄存器的个数时自动处理为自动变量。定义格式: ㈢静态变量①静态变量的存储空间在程序的整个运行期间是固定的 (static),定义一个静态变量,在编译时就分配存储空间, 程序一开始执行就建立,直到程序结束都存在 ②静态变量的初始化是在编译时进行的,在定义时中能 使用常量或常量表达式,未显示初始化时,编译时其值 为0,其格式为: Static 数据类型 变量名[=初始化常量表达式]注:只有静态变量和外部变量才是编译时建立,才有初 始化,自动变量称为赋初值。 ③在函数多次调用中,静态局部变量的值具有可继承 性。(见书上例120页4.15题) ④静态局部变量 的值只能在本函数(或分程序)中使 用。在一个函数中定义的局部变量,只能在其局部内 被引用,但static类型在函数调用结束后其存储单元的 值不释放,其值具有继承性,定义静态局部变量是为 了在多次调用同一个函数时能使变量保持上次调用的 结果。例如:下列程序输出的结果是(),如将static z=3; 改为int z=3;程序执行的结果是()#include&stdio.h& func(int x) { int y=0; static z=3; x=z++;y++; return(x);} main() { int a=2,I,b; for (i=0;i&2;i++) b=func(a++); printf(D%d\n‖,b); }①4② 5③3④0 4.2.3外部变量㈠外部变量是全局变量 在一个函数中定义在所有函数之外的变量称为外部变 量。 例如:int a=3,b=6; main() {void fun(void); printf(D%d,%d\n‖,a,b); fun(); } void fun(void) { printf (D%d,%d\n‖,a,b);}例如:交换两个变量的值 int a=3,b=6; main() { void fun(void); printf(D%d,%d\n‖,a,b); fun(); printf(D%d,%d\n‖,a,b); } void fun(void) { c=a; a=b; b=c; }main() {……} f1() {……} Int a,b; f2() {……}Float x,y; F3() {……}外部变量也可以放在两个函数之间,而不放在函数的开头。其 作用域从定义点开始到文件结束。 ㈡外部变量使用的几种情况⒈限定本文件的外部变量只在本文件使用。其格式为:static 类型 变量表; 静态外部变量 注意:外部变量是在编译时分配存储单元,其生存周期是整个程序 的运行周期。在内存的数据存储区分为两个部分:静态存储区和动 态存储区,自动变量和形参存放在动态存储器区,而静态变量和外 部变量存放在静态存储区。 ⒉将外部变量的作用域在本文件内扩充。 一个外部变量从定义开始到文件结束有效,可用extern说明符使变 量的作用域扩充到需要使用的函数。其格式如下: extern 类型 变量表; /*在需要扩充的函数中声明*/ …… 类型 变量表; /*定义外部变量*/ }类型 函数名(){ 函数体例如4.18(见书上124页4.18) main(){void gx(),gy();extern int x,y; /*声明x,y为外部变量*/ printf(Dx=%d,y=%d\n‖,x,y); /*输出x=,y=*/y=246;gx(); gy();}扩充x,y有效void gx(){extern int x,y x=135; /*声明x,y为外部变量*/扩充x,y有效 x,y有效printf(Dx=%d,y=%d\n‖,x,y); /*输出x=,y=*/}int x,y; void gy(){printf(Dx=%d,y=%d\n‖,x,y); /*输出x=,y=*/} 注:外部变量的定义在函数中只有一次,而对外部变量的声明可以 有多个,定义外部变量时分配内存,声明变量只是告示“此变量应 到外部变量中找。 另外,除了例4.18中可以在函数内用extern声明之外,还可以将它 书写在函数体外,以达到扩充作用域的目的。extern int x,y; /*声明x,y为外部变量*/main() {void gx(),gy();……} void gx()扩充x,y有效{ …… }int x,y; void gy()x,y有效{……}⒊还可以将外部变量扩充到其它文件中,(见书上125页) file 1.c int x,y; main() {…… x=12; y=24; f1(); printf(D%c‖,ch); }file 2.c extern int x,y; f1() { printf(D%d%d‖,x,y); }㈢外部变量的副作用§4.3编译预处理4.3.1宏替换 ㈠字符串宏替换格式: #define 宏名 宏体其持点是提高了程序的可读性,易修改。 ㈡带参的宏替换格式:#define 宏名(形参表) 宏体例如:#define PI 3.14159 #define S(r) PI*r*r main() {float a, a=3.6; area=S(a); printf(Dr=%f\narea=%f\n‖,a,area); } 注意函数调用和宏替换的区别: ⒈函数调用时先求出实参,再代入形参;而用宏只进行字 符替换。 ⒉函数调用是程序运行时处理,分配临时存储空间;宏展 开是在编译时进行,不分配存储空间。 ⒊对函数实参和形参都定义类型,并要求一致,宏不存在 类型。 ⒋函数调用有返回值,宏无返回值。 ⒌宏使用较多时,其展开源程序长,程序膨胀,加大了系 统有存储开销。 ⒍宏替换不占运行时间,只占编译时间,而函数调用占运 行时间。㈢书写#define 命令行应注意的几点(见书上133页) 4.3.3 条件编译条件编译的几种形式:1、#ifdef 标识符 程序段1 #else 程序段2 当标识符已被#define命令 定义过,则在程序编译阶段 只编译程序段1#endif或#ifdef 标识符 程序段1 #endif 例如:#define DEBUG main() {……#ifdef DEBUGprintf(Dx=%d,y=%d,z=%d‖,x,y,z); #endif …… #ifdef DEBUGprintf(Da=%d,b=%d‖,a,b);#endif ……} 2、#ifndef 标识符程序段1 #else当标识符未被#define命令 定义过,则在程序编译阶段 编译程序段1程序段2#endif 或#ifdef 标识符 程序段1 #endif 3、#if表达式程序段1 #else当表达式的值为真时,则编 译阶段编译程序段1,否则 编译程序段2程序段2#endif 或#ifdef 标识符 程序段1 #endif 例如:输入一行字母字符,根据需要设置条件编译,使其能将字母全部改为大写 输出,或全改为小写输出。#define AAA 1 main() {char str[]=DCLanguage‖,c;i=0; while(c=str[i]!=?\0‘){i++;#if AAA if (c&‘a‘&&c&?z‘) c=c-32; #else if (c&‘A‘&&c&?Z‘) c=c+32; #endif printf(D%c‖,c);}} 4.3.2文件包含文件包含是通过命令#include把已经进入系统的另一个文 件的整个内容嵌入进来,其格式如下: 格式1 格式2 #include D文件标识” #include &文件名&其中格式1中的文件标识含有文件路径,在编译时,首先在原 文件目录中检索指定的文件,未找到,则按系统指定的标准 方式检索其它文件目录;格式2只按规定的标准方式检索目录。 见书上139页4.13 #define LOW 0 #define HIGH 5 #define CHANGE 2 int i=LOW; main() {int workover (int i);int reset(int i); int i=HIGH; int workover (int i) {i=(i%i)*((i*i)/(2*i)+4); printf(Di=%d\n‖,i); return(i);} int reset (int i)reset (i/2);printf(Di=%d\n‖,i); reset (i=i/2);{I=I&=CHANGE?HIGH:LOW;return(i);}printf(Di=%d\n‖,i);reset (i/2); printf(Di=%d\n‖,i);workover ( i);printf(Di=%d\n‖,i);} Printf(Da=%d\t‖,(int(x*2+3.)));main() {Putchar(?\n‘);{{int x=2;print(x*FUDEGE(2));}for (cel=0;cel&=100;cel+=50)PRINT2(CEL,9.15*cel+32); } {int x=1;y=2; print3(MAX(x++,y),x,y);PRINT3(MAX(x++,y),x,y);}} 第五章§5.1 一维数组数组数组是一组同类型数据组成的序列,用一个统一的名称标识这一组数, 用下标来指示数组中元素的符号。同一数组中的所有元素必需属于同一 类型。 5.1.1一维数组的定义类型标识符 数组名[元素个数]例如:int a[5];共含有a[0],a[1],a[2],a[3],a[4],五个元素。 5.1.2一维数组的初始化 C语言允许在定义时对数组元素赋初值,称为数组的初始化。 例如:int a[5]={1,2,3,4,5};直接赋初值时可不指名数组个数。 5.1.3数组元素的引用 数组必需先定义后引用,其下标可以是整数或整型表达式,其下标起 始值为0,注意C编译不检测下标是否越界,当超范围引用时,自动将下 一个数据引用。 例如:用数组来求数列 1,1,2,3,5,8,13,…… main() {int a[20]={1,1};for(i=2;i&20;i++) f[i]=f[I-2]+f[I-1]; for(I=0;I&20;I++) {printf (D%12d‖,f[i]);if (I%5==0)printf(D\n‖);} } 5.1.4数组作为函数的参数①将数组元素作为函数参数传递(其使用方式与变量的传递相同,是 一种值传递)例如:求二个数的和及其平均值main() {float a[2]={45,78}, float f(float x,floaty); sum=f(a[0],a[1]); printf(Dsum=%f\n‖,sum); } float f(float x,floaty){float ss=x+y; return(s);} ②将数组名和为函数参数传递(以数组名作为参数传递时, 采用的是“地址传递”方式,即把实参数组的起始地址传 递给形参数组,实参数组和形参数组共用一个存储空间, 在被调用的函数中形参数组的值发生变化,则实参数组的 值也会发生变化)注意:一维数组数组名代表数组的首地 址。 例如:从键盘输入10上学生的成绩,求平均成绩,并将低 于平均分的成绩打印出来。定义变量和数组 调用向数组元素的函数并输出数组的值 调用求平均值的函数 输出平均分 调用输出平均分和低于平均分的成绩 main() {void read(float sc[10]); float aver(float sc[10]); void print(float sc[10],float ave1); float ave,score[10]; read(score); ae=aver(score); frintf(Daverage=%6.2f\n‖,ave); frint(score,ave);} void read(float sc[10]) { int I; printf(Dinput 10 ); for (I=0,I&10;I++) scanf(D%f‖,&sc[i]);} float aver(float sc[10]) { int I;/*输入10个成绩到数组中*//*求平均成绩*/for (sum=0,I=0;I&10,I++)sum=sum+sc[i]; return(sum/10);} void print(float sc[10],float ave1) { int I; printf(Dbelow the average:\n‖); for (I=0;I&10;I++) if(sc[i]&ave1) printf(D%6.2f,sc[i]‖);} /*输出所有低于平均成绩*/ 例如:对n个数排序(主要有冒泡法、选择法)采用冒泡法排序其流程如下:定义数组和变量n 输入n I&n 输入n个数到数组中调用给数组元素赋值调用排序 调用输出排序后的结果I&n输出n个数For I=1 to n-1 T=n-iI&n输出n个排序后的数 For I=0 to n-2For j=0 to t-1a(j)&a(j+1)P=IFor j=I+1 to n-1 a(j)&a(p)a(j)与a(j+1) 交换yn 选择法 yy P=j P!=in n冒泡法流程a(p)与a(i)交换 main() {void enter(int a[].int n); void bubble(int a[].int n); void print(int a[].int n); int a[10]. printf(Denter n:‖); scanf(D%d‖,&n); enter(a,n); bubble(a,n);void bubblr(int a[].int n) /*冒泡法*/ {int I,j,t, for (I=1;I&=n-1;I++) {t=n-I; for (j=0;j&=t-1;j++) if (a[j]&a[j+1]) {temp=a[j]; a[j]=a[j+1]; a[j+1]=}Print(a,n)} void enter(int a[].int n) /*给数组赋值并输出*/ {int I; for (I=0;I&n;I++) scanf(D%d‖,&a[i]); Printf(Dno sort‖); For (I=0;I&n;I++) }}Rvoid print(int a[].int n)院 /*输出排序后的数组*/ {int I; printf(Dsort\n‖); for (I=0;I&n;I++) printf(D%d‖,a[i];)}printf(D%d‖,a[i]);Printf(D\n‖);} void select(int a[].int n); {int I,j,p, for (I=0;I&n-1;I++) {p=I;/*选择法*/for (j=I+1;j&=n;j++) if (a[j]&a[p]) p=j; if (p!=i) {temp=a[p]; /*记下最小数的位置*/ /*最小数的位置不等于I交换两个数据*/a[p]=a[j];a[i]=} } R } 输入一个数,将其插入到一个有序的数列中main(){int a[11]={1,4,7,9,43,56,78,88,98,99}; int i,j,x; printf(Dinput :x‖);scanf(D%d‖,&x);for (I=0;I&10;I++) printf(D%4d‖,a[i]); printf(D\n‖);if (a[9]&x) a[10]=x;else for(I=0;I&10;I++) {if(a[i]&x) for (j=10;j&I;j--) a[j]=a[j-1]; a[i]=x; } for(I=0;I&=10,I++) printf(D%d‖,a[i]); } §5.2二维数组和多维数组 5.2.1二维数组的定义 类型标识符 数组名[下标1][下标2];多维数组的定义类型标识符 数组名[下标1][下标2][下标3]……; 例如:int a[3][4]; a数组共包含12个元素,分别是 a[0][0]、a[0][1]、a[0][2]、a[0][3] a[1][0]、a[1][1]、a[1][2]、a[1][3]a[2][0]、a[2][1]、a[2][2]、a[2][3] 5.2.1二维数组引用和初始化①对一维数组的初始化可以分行对各元素赋值. Int a[2][3]={{1,2,3},{4,5,6}};②也可将各初值全部写在一个花括号内,编译时按数组 在内存中的排列顺序分别赋值. Int a[2][3]={1,2,3,4,5,6}; ③可以只对部分元素赋初值 Int a[2][3]={1,2,3,4}; ④可以分行赋值时只对其中部分元素赋值. Int a[2][3]={{1,2},{4,5}}; ⑤在对全部元素赋值时,可省略第一维的下标.Int a[ ][3]={1,2,3,4,5,6}; 例如:一个班有50个同学参加期未考试,共考4门课程, 定义一个数组存放所有成绩,并输出结果。Main(){int a[51][4];int i.,j; for(I=1;I&=50;I+=) for (j=1,j&=4;j++) scanf(D%d ‖,&a[i][j]); for(I=1;I&=50;I+=) {for (j=1,j&=4;j++) printf(D%4d ‖,a[i][j]); printf(D\n‖); }} 例5.6(见书上161页)函数声明 定义数组并赋值主函数调用求班平均调用求单个学生的平均求班平均 求个人 不均定义循环变量以C、S 定义求和和变量T和求平均值的变量ave定义循环变量C、S 定义求和变量T和求平均值的变量avec&bT=0S&aT=0S&a求和t=t+sc[s*b+c]; 求平均ave=t/a;输出结果c&b求和t=t+sc[s*b+c]; 求平均ave=t/a;输出结果 打印杨辉三角形(打印前10行)1 1 1 1 2 1 1 3 3 1 Main() {int I,j,a[11][11]; for (I=1;I=10;I++) { a[i][1]=1; a[i][i]=1; 1 } for(I=3;I&=10,I++)1 4 6 411 5 10 10 5 1 1 6 15 20 15 6 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1for (j=2;j&=I-1;j++)a[i][j]=a[I-1][j-1]+a[I-1][j]; for(I=1;I&=10,I++) {for (j=1;j&=I-1;j++)printf(D%d‖,a[i][j]);printf(D\n‖); }} 输入一个n*n矩阵各元素的值,求出两条对角线元素的和 #define N 10 main()int a[N][N];int I,j,sum=0; for (I=0;I&N;I++) for (j=0;j&N;j++) scanf(D%d‖,&a[i][j]);for(I=0;I&N;I++)sum=sum+a[i][i]+a[i][N-I-1]; if( N%2==1)sum=sum-a[N/2][N/2]; } §5.3字符数组和字符串5.3.1字符串和字符串的存储方法字符串是若干有效字符的序列,C语言中的字符串包 括字母、数字、专用字符、转义字符等。如:“ABC‖, “――‖ 、 “123.45‖。 C语言中没有字符串变量,字符串存于字符数组中而 不是存于变量中,以“\0‖作为字符串结束标志。 (“\0‖是指ASCII代码为0的字符)。字符存于字符数 组中,但字符数组与字符可以不等长。 5.3.2字符串数组的初始化1、逐个地赋值Char a[5]={?A‘,‘B‘,‘C‘}; 2、对数组赋一个字符串Char a[5]={Dcomputer‖}; Char a[5]=Dcomputer‖;或 5.3.3字符串的输入除定义字符数组时直接赋值外,也可用scanf()函数输入字 符串。例如: char a[10];scanf(D%s‖,a);char a[10]; gets(a); 5.3.4字符串的输出/*但scanf()函数不能输入带空格的字符*/C语言提供了一促输入函数gets(数组名)用于输入字符串。 /*专用于字符串的输入函数*/1、 printf(D%s‖,a);输出时只输出\0前面的字符。 2、 puts(a); /*专用于字符串的输出函数*/ 5.3.5字符串运算函数1、字符串的拷贝函数strcpy(string copy)格式如下:Strcpy(str1,str2) 或 Strcpy(str1,Dcomputer‖)其中str1必需为数组名且足够大。 2、字符串的连接函数strcat (string catenate)格式如下: Strcat(str1,str2) 或 Strcat(str1,Dcomputer‖)其中str1必需为数组名且足够大。3、字符串比较函数strcmp(string compare)格式如下:Strcmp(str1,str2)或Strcmp(字符串1,字符串2)功能如下:字符串1=字符串2,函数值为0 字符串1&字符串2,函数值为正整数字符串1&字符串2,函数值为负整数 4、测字符串长度函数strlen(string lenght)格式如下: Strlen(str); 5.3.6二维字符串数组 1、二维字符串数组的定义 Char a[3][20]={Dabcd‖,Defghijk‖,Dlmnopq‖};2、二维字符串数组的引用printf(D%c‖,a[1][2]); 其结果为“g‖ printf(D%s‖,a[1]); 其结果为“efghijk‖对于二维数组a[3][20],其中a[0]、a[1]、a[2]代表行 的首地址。 怎样设计C语言字符串标准函数?例如:编一个程序完成字符串长度的测试。main() {int strlen1(str1[]); char str[]={Dabbbcdssd‖};l=strlen1(str);Printf(D%d‖,l); } Int strlen1(str1[]) {int I=0; while (str1[i]!=?\0‘) I++; retunr(i);} 编一程序,将两个字符串连接起来1、不使用strcat函数main() {char s1[80],s2[40]; int I=0,j=0; gets(s1); gets(s2); while(s1[i]!=?\0‘) I++; while(s2[j]!=?\0‘) s1[I++]=s2[j++]; s1[I]=?\0‘;2.使用strcat 函数main() {char s1[80],s2[40]; gets(s1); gets(s2);strcat(s1,s2);puts(s1);}puts(s1);} 编一程序,将两个字符串s1和s2进行比较,若s1&s2l输出 正数,s1=s2输出0,否则输出负数1、不使用strcmp函数main(){int I=0,r; char s1[20],s2[20];2、使用strcmp函数main(){ char s1[20],s2[20];gets(s1);gets(s2); while ((s1[i]==s2[i])&&s1[i]!=?\0‘)gets(s1);gets(s2); r=strcmp(s1,s2);i++;if (s1[i]==?\0‘&&s2[i]==?\0‘) r=0; elseprintf(D%d‖,r);}r=s1[i]-s2[i];printf(D%d‖,r);} 编一程序,将个字符串数组s2中的全部字符拷贝到 字符串数组s1中。不使用strcpy函数 方法1 main() 方法2 main() {char s1[80],s2[80]; int I;{char s1[80],s2[80];int I; gets(s2); for (I=0;I&=strlen(s2);I++) s1[i]=s2[i]; printf(D%s‖,s1); }gets(s2);for (I=0;s2[i]!=?\0‘;I++) s1[i]=s2[i]; s1[i]=?\0‘; printf(D%s‖,s1);} 例:删除一个字符串中指定的一个字符 main() {void del_str(a[],ch1); char a[20], gets(a); ch=getchar(); del_str(a[],ch1) {int I; for (I=0;a[i]!=ch1;I++); while(a[++I]!=?\0‘) a[I-1]=a[i];del_str(a,ch);puts(a); }a[i]=?\0‘;return} 有多个字符串,要求找出最大的一个和最小的一个字 符串main() {char max[20],min[20];char a[10][20];int I; for (I=0;I&10;I++)gets(a[i]);strcpy(max.a[0]); strcpy(min.a[0]);for(I=1;I&10;I++){ if (strcmp(a[i],max)&0) strcpy(max,a[i]); if (strcmp(a[i],max)&0) strcpy(min,a[i]);}printf(Dmax=%smin=%s‖,max,min);} 输入一行字符,统计其中有多少个单词,单词之间 用空格分隔开。 main() {char s[80];int I,n=0,w=0; gets(s); for(I=0;(c=s[i])!=?\0‘;I++) if(c==?‘) w=0; else if (w==0) {w=1;n++;}printf(D%d‖,n);} 有17个人围成一圈(编号为0――16),从第0号的人开始报数,凡 报到3的倍数的人离开圈子,然后再数下去。直到最后只剩下一个 人为止,问此地原来的位置是多少号。main() {int I,t,p[17],h;for(I=0;I&16;I++)p[i]=I+1; p[16]=; t=0; while(t!=p[t]) {for (I=1;I&3;I++) {h=t;t=p[t];} p[h]=p[t]; t=p[h]; }Printf(D\n%d‖,t);} 第六章6.1.1地址和指针(一)地址和取地址运算指针§6.1指针概述C语言是一种具有低级语言功能的高级语言,其特点是在程序中 可用名字引用一个实体,也可用地址来访问。 例:main( )a b c3 4{int a=3,b=4;float c,d; scanf(D%f,%f‖,&c,&d); printf(D%d%d%f%f‖,a,b,c,d); printf(D\n%x%x%x%x‖,&a,&b,&c,&d);}d (二)指针与指针变量 1、内存单元的地址与内存单元的内容的区别:044 8 2000a变量 b变量 P指针 变量2、程序编译以后,已将变量名转换为变量的地址, 对变量的存取都是通过地址进行的。这种按地址存取变量值的方式称为“直接访问”方式 ,而将一个变 量的地址存放在另一个变量中,这个变量是用来存 放变量地址的,在访问该变量时,由地址找到对应变量的方法,称为 “间接访问”。用于存放地址的变量是一种特殊的变量,只能用来存 放地址,即指针变量。6.1.2指针的类型与指针的定义指针的类型就是它所指向实体的类型:基本类型 *指针变量int *p; p是一个指向整型变量的指针,定义一个指针变量 必须用*,但是p是指针变量,而不是*p为指针变量。 将一个指针变量指向一个变量时,只能将变量的地址赋给指针变量。 例如:float I; float *p; I=3;p=&I;6.1.3指针变量的引用 (1)&:取地址运算符 (2)*:指针运算符 例如:main(){int a=10,*p;p=&a; printf(D%d%d‖,a,*p);}输出的结果相同。 &a为a变量的地址,*p为指向变量a的存储单元 对“&‖和“*”运算符的说明:例如:int a,*p;a=10; p=&a; *P 将a变量的地址赋给指针变量p 指针变量所指向的地址的值(1)&*p &和*两个运算的优先级别相同,但按 自右至左方向结合,应先进行*P的运算,它就是变量 a,再执行&运算,即等价于&a运算。是变量a的地址。 (2)*&a 先进行&a的运算,得到a的地址,再进 行*运算,即&a报指向的变量,*&a和*p的作用是一样 的。 (3)(*p)++相当于a++,括号是必需的,若省略 括号就成为*P++,++与*同级,相当于*(p++)运算, ++在p的右侧,先引用后自增,其结果是不同的。 例如:使两个指针交换指向main(){int *p1,*p2,*p,a=10,b=20; p1=&a; p2=&b; printf(D%d,%d,%d,%d\n‖,a,b,*p1,*p2);p=p1;p1=p2;p2=p;printf(D%d,%d,%d,%d\n‖,a,b*p1,*p2); } 结果为:10,20,10,20 10,20,20,10 例如:交换两个指针指向的变量的值 main() {int *p1,*p2,a=10,b=20,c;p1=&a;p2=&b; printf(D%d,%d,%d,%d\n‖,a,b,*p1,*p2); c=*p1;*p1=*p2;*p1=c; printf(D%d,%d,%d,%d\n‖,a,b*p1,*p2);}结果为:10,20,10,20 20,10,20,10 6.1.4指向指针的指针(二级指针)类型标识符 **指针变量例如:main() {int **p,*p1,I=3; p1=&I; p=&p1;printf(D%d,%d,%d‖,I,*p1,**p)} P1一级指针 变量iP二级指针 §6.2指针与数组 6.2.1一维数组的指针表示方法:一个变量有一个地址,一个数组由若干个元素组成,每个元素在内存中都有 一个地址,指针可指向变量,也可以指向数组和数组元素,数组元素的引用在第 五章中采用的是下标法,如a[i],也可以使用地址法,如:*(a+i),也可以采用指针 法。即通过指向数组元素的指针找到所需的元素,使用指针法占内存少,运行速 度快。使用程序质量提高。1、指向数组元素的指针 int a[10],*p;p=a;是将a数组的首地址赋给指针变量pp=&a[0]; 是将a数组的第一个元素的地址赋给指针变量p 也可以用以下形式:int a[10];int *p=a; 或: int *p=&a[0]; 定义时赋值 2、通过指针引用数组元素如果指针变量p已指向数组中的一个元素,则p+1指 向同一个数组中的下一个元素(而不是将p值简单加1)。如对整型数组,p+1相当于加2个字节,对实型变量 单精度,p+1相当于加4上字节。(例5) 如果p的初值是&a[0] (1)p+I和a+I就是a[I]的地址,指向第I个元素,而实际 地址为a+I*d(d表示字节数) (2)*(p+I)和*(a+I)是p=I或a+I所指向的数组的元素即: *(p+I)=*(a+I)=a[i] (3)指向数组的指针变量也或以带下标如:p[i]与*p+I等 价.下标法a[i],指针法*(a+I)或*(p+i),其中a为数名,p为 指针 例如:输出数组中的全部元素 (1)下标法main() {int a[10],i; for (I=0;I&10;I++) scanf(D%d‖,&a[i]); for (I=0;I&10;I++)(2)地址法main() {int a[10],i; for (I=0;I&10;I++) scanf(D%d‖,&a[i]); for (I=0;I&10;I++) printf(D%d‖,*(a+I)); }printf(D%d‖,a[i]);}(3)指针法main() {int a[10],i; int *p;p=a;for (I=0;I&10;I++) scanf(D%d‖,&a[i]); for (p=0;p&(a+10);p++) 例如:下面是利用指针变量输出a数组的10个元素 的程序,请指出其存在的问题。(3)main(){int a[10],i;int *p; p=a; for (I=0;I&10;I++) scanf(D%d‖,p++);for (I=0;I&10;I++,p++)printf(D%d‖,*p); } 在使用指针变量时,有几个问题要注意:(1)、指针变量可以实现使本身的值的改变,如指针法中P++使P的值不断改变。若将程 序改为: for (p=0;a&(p+10);a++) printf(D%d‖,*a);是不行的,a是代表的数组名,它的值在程序执行中是不变的。(2)要注意指针的当前值 (3)注意指针变量的运算。①如p=a指向数组元素的首地址,则p++或(p+=1)是使p指向下一个元素。②*P++是先执行*P再自增。 ③*(p++)和*(++P)作用不同,前者是*p的值,后果者是P+1后的值④(*p)++表示p所指向的元素值加1,即(a[0])++⑤如果p当前指向a数组中 第I个元素,则:*(p--)相当于a[I--],先对p进行“*”运算,再自减。 *(++p)相当于a[++i],先使p自加,再作*运算。 *(--p)相当于a[--i],先使 p自减,再作*运算。 例如:输入若干天的温度,求平均温度.main() {float t[31];float s=0;int n,day=0; do{printf(Dinput t %d‖,day);scanf(D%f‖,t+day); }while (*(t+day++)&0);n=day-1;for (day=0;day&n;day++) sum+=*(t+day);printf(Daverage is %4.1f‖,s/n);} 6.2.2二维数组的指针表示方法一维数组与指针的关系:在C语言中,一维数组名代表该数组元素的 首地址,或是一个指向所代表的数组的起始地址,因一个数组定义后, 其起始地址被确定,所以数组名实际上是一个指针常数,一维数组的任 何一个元素的地址,都可以用其数组名加上一个偏移量来表示,这个偏 移量的单位不是字节,而是数组元素的数据类型的字节数大小,如int 偏移单位是2个字节,float 偏移单位是4个字节。 下面看一下二维数组:int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};a是一个数组名,a数组包含三个元素,a[0],a[1],a[2],而每一个 元素又是一个一维数组,包含4个元素,如:a[0]代表一维数组 a 又包含4个元素,a[0][0],a[0][1] a[0] 1 2 3 4 ,a[0][2],a[0][3];由此可认为二 a[1] 5 6 7 8 维数组是“数组的数组”即数 a[2] 9 10 11 12 组a是由3个一维数组报组成的. 由此可知,对于二维数组或多位数组,可用一维数组来表示 二维数组或多维数组,对于二维数组来说,可以看成是由下 列元素组成的一维数组。 如:a[0],a[1],a[2],a[3],…a[i]…a[i]代表一维数组的一个元素,又是一维数组a[i]的名字,是 指向a[i]的起始元素的指针常量。下面int a[3][5]二维数组的 地址与元素关系的示意图: a[0] a[0]+1 a[0]+2 a[0]+3a 2000 a+1 2008 a+2 2016 a a[0] a[1] a[2] a+1 a+208 11 0A 200B 04 07 200C 200E 200D 200F 15 2017 a 1000a[0] a[0]+1 *a+1a[0][0] a[0][1]……a+1 1010a[1]1010a[1]+1 1012 *(a+1)+1a[1][0] a[1][1] ……a+210201020 a[2] a[2]+1 1022 *(a+2)+1a[2][0] a[2][1] …… 例如:a5.cmain() {int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};printf(D%X,%X,%X\n‖,a,a[0],*a);printf(D%X,%X,%X\n‖,a+1,a[1],*(a+1)); printf(D%X,%X,%X\n‖,a+2,a[2],*(a+2)); printf(D%X,%X,%X,%X\n‖,a[0]+2,*a+2,*(a+0)+2,&a[0][2]); printf(D%d,%d,%d\n‖,*(a[2]+2),*(*(a+2)+2),a[2][2]);} FFCA, FFCA,FFCA FFD2,FFD2,FFD2 FFDA,FFDA,FFDA FFCE,FFCE,FFCE,FFCE 11,11,11 例如:输出二维数组的有关值(见书上191例6.9)#define FORMAT D%d,%d\n‖main() {int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};Printf( FORMAT ,a,*a);Printf( FORMAT ,a[0],*(a+0); Printf( FORMAT ,&a[0],&a[0][0]);结果为158,158158,158 158,158Printf( FORMAT ,a[1],a+1);Printf( FORMAT ,&a[1][0],*(a+1)+0); Printf( FORMAT ,a[2],*(a+2));166,166166,166 174,174Printf( FORMAT ,&a[2],a+2);Printf( FORMAT ,a[1][0],*(*(a+1)+0)); }174,1749,9注意:a是二维数组的数组名,代表数组的首地址,但不能用*a来得 到a[0][0]的值,*a相当于*(a+0),即a[0],a是行指针,而*a是列指针 例如:指向数组元素的指针变量(列指针,一级指针)main() {int a[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};int *p;for (p=a[0];p&a[0]+15;p++) printf(D%d‖,*p); printf(D\n‖);} 如果书写为p=&a[0][0]或p=*a或p=*(a+0)均可。若要 将a赋给p,则需要强制转换,如p=(int *)a,即将a转换成 指向整型数据的指针 例如:指向由m个元素组成的一维数组的指针变量(行指针、二级指针) main() {int a[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; int I,j,(*p)[5]; p=a; for (i=0;I&3;I++) for(j=0;j&5;j++)P,a P+1 P+2 a[0] a[1] a[2]printf(D%d‖,*(*(p+i)+j));printf(D\n‖);}程序中的int(*p)[5]表示p是一个指针变量,它指向包含5个元素的一维数组, 且*p两侧的括号不可少,如果写成*p[5],将变为指针数组。 例如:int a[5]; int (*p)[5]; p a有5个元素,每个元素为整型 *p有5个元素,每个元素为整型 (*p)[1](*p)[0](*p)[2](*p)[3](*p)[4] 6.2.3指针与字符串在C语言中,字符串是通过字符串数组来存放的,可以定义一个 数组来存储并输出,也可以通过指针来访问所需的字符。例如:用字符指针指向一个字符串main(){char str[]={Dabcdefg‖};或 char *p; p= printf(D%s\n‖,str); printf(D%s\n‖,p); } 注意:见书上下班92页: for (p=*p!=?\0‘;p++) char *p={Dabcdefg‖};字符串指针的使用 char *p={Dabc‖};或}

我要回帖

更多关于 正则匹配最后一个空格 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信