流程控制和数据的输入输出
算法
著名计算机科学家沃思提出了一个公式:
数据结构 + 算法 = 程序
数据结构:对数据的描述
算法:对操作步骤的描述
算法定义
广义的说,为解决一个问题而采取的方法和有限的步骤,就称为"算法"
例如:
将大象放入冰箱的算法就可以如下描述:
打开冰箱门-把大象装进去-关闭冰箱门
算法特征
-
有穷性:包含有限的操作步骤,不能无限制的执行下去
-
可行性:算法中的每一条指令必须是切实可执行的
-
确定性:算法中的每一条指令必须有确切的含义,不能产生歧义
算法描述-流程图
案例:
-
要求:对于计算 s=1+2+3+4+5+6+7+8+9+10(累加求和)
-
用流程图表示为:
程序的三种结构
顺序结构
特点:各操作是按先后顺序执行的,是最简单的一种结构,这个结构是默认的。
其中A和B两个框是顺序执行的。也就是在A框所指定的操作后,必然接着执行B框所指定的操作。
分支结构
分支结构又被称作"条件结构"或"选择结构"
特点:根据是否满足给定条件而从两组或者多组操作中选择一种进行执行。
-
无论P条件是否成立,只能执行A操作或者B操作中的一个。
-
无论执行完哪一个分支后,就结束了
分支结构又被分为"重复结构"。即在一定条件下,反复执行某一部分的操作,有两种类型:
循环结构
又被称之为"重复结构"。即在一定条件下,反复执行某一部分的操作,有两种类型:
- 当型循环
-
执行过程:
-
当给定条件P成立时,执行S操作,然后再判断P条件是否成立,如果仍成立,再执行S操作,然后再判断···,如此反复,直到某一次P条件不成立为止,此时不再执行S,结束循环。
- 特点:
先判断,后执行,S有可能一次也不执行。(while,for)
-
直到型循环
- 执行过程:
执行S操作,然后判断条件P是否成立,如果成立,再执行S操作,然后再判断,···,如此反复,直到某一次P条件不成立不再执行S,结束循环。
- 特点:
先执行,后判断,S最少要执行一次。(do...while)
C语句
-
C程序是以函数为基本单位的。
-
一个函数的执行部分是由若干条语句组成的。
-
C语句都是用来完成一定的操作任务的。
-
C语句必须依赖于函数存在。
C程序结构
C语句分类
控制语句
用于完成一定的控制功能
① if()......else......
②for()......
③while()......
④do......while()
⑤continue
⑥break
⑦switch()
⑧return
⑨goto 标号(无条件跳转语句)
函数调用语句
由一个函数调用加一个分号构成,例如:
printf("这是一个c程序!\n");
表达式语句
由一个表达式加一个分号构成,最典型的是赋值语句,例如:
a = 3 // 是一个表达式
a = 3; // 是一个表达式语句
空语句
只有一个分号,什么都不做,例如:
;
复合语句
用"{......}"括起来的若干个语句,例如:
{
z = x + y;
t = z / 100;
printf("%f\n",t);
}
数据的输入输出
数据的输入与输出相对于计算而言,其中:
-
从计算机向外部设备输送数据称之为输出。通常的输出设备包括:显示器、打印机的等。
-
从外部设备向计算机输送数据称之为输入。通常的输入设备包括:键盘、鼠标、扫描仪等。
在C语言中,输入与输出时用标准库(<stdio>)函数中的输入(scanf())、输出函数(printf())实现。
库函数已经被编译成了目标,在链接时与编译源程序员得到的目标我问及那(oni),下生成可执行程序
注意:在使用系统函数时,要用编译命令#unclude将有关的头文件包含到用户源中(要放在程序的开头位置)头文件含入调用是需要的有关信息
简单的输入和输出
用简单的printf函数输出数据
语法"格式控制",输出列表;
printf("格式控制\n",i,34);
注意:格式控制中的格式化要和输出的数据一一对应
举例:
printf("i=%d,x=%d\n"i,34);
① 格式控制,用一对双引号括起来,包括两种信息:
-
格式说明:由"%"和特定的字符组成,如:%d,%c,%f等,这是格式说明符,用于说明输出项目所采用的格式
-
普通字符:作为说明性的文字、符号等,照原样显示出来
② 输出列表:输出列表中的各项目指出了所要输出的内容,可以是常量、变量、表达式
基本的格式字符
%d 按有符号十进制整型(int)数据的实际长度输出。(十进制(0)、八进制(00)、十六进制(0x00))
%u 按无符号十进制整型(int)数据的实际长度输出。
%c 仅输出一个字符(char)
%s 输出结果是字符串,举例:printf("%s\n","CHINA") ,输出结果:CHINA
%f 以小数形式输出一个实数(含单双精度)。整数部分全部输出,小数部分输出6位
%e 也可以写作%E,以指数形式输出一个实数(含单双精度)。小数点前1位非0数字,并输出6位小数。
%hd 短整型(short int/short)
%hhd 字符型的ASCII码,char数据对应的ASCII码的值,举例:char a = 'A';printf("%hhd\n",a);
%lf 双精度浮点型(double)
%ld 长整型(long int/long)
%lld 长长整型(long long int/long long)
%x 十六进制,并且十六进制的前缀0x不会打印出来
%#x 十六进制,并且十六进制的前缀0x也会打印出来
%#o 八进制,并且八进制的前缀0也会打印出来
%p 打印内存的地址
用简单的scanf函数输入数据
语法:
scanf("格式控制",地址列表); -- 注意,不能传变量、常量、表达式,只能传与之对应的内存地址
取地址举例:
int a = 10; // 定义一个变量a
scanf("%d",&a); // &被称之为取地址符
printf("%p\n",a); // 打印输出a的内存地址
作用:
将键盘输入的值存入内存中所占的存储单元里。存储单元有地址标识。
说明:
-
"格式控制":含义等同于printf函数的格式控制,说明输入的数据应该使用的格式,但是格式控制中不能添加除格式化符以外的字符。
-
"地址列表":是由若干个地址组成的,可以是变量的地址或者字符串的首地址。&取地址运算符,用于取出变量的地址。
-
与格式输出一样,在格式控制中,用于说明输入数据格式的格式说明符总是以%开头,后面紧跟具体的格式。
案例:
-
要求:从键盘输入整数给变量a,b,c
-
代码:
#include <stdio.h>
void main()
{
// 定义三个变量,用来接收控制台的输入
int a,b,c;
printf("请输入三个整数:\n");
scanf("%d%d%d",&a,&b,&c);
}
复杂的输入与输出
按指定格式输出数据的宽度、小数位数、上下行数据按小数点对齐、用八进制、十六进制输出等。
输出数据格式的控制
整型格式说明符
- 十进制形式
说明符 | 说明 | 数据类型 |
---|---|---|
%d或%md | 用于基本整型 | Int |
%ld或%mld | 用于长整型 | long |
%u或%mu | 用于无符号的基本整型 | unsigned |
%lu或%mlu | 用于无符号长整型 | unsigned long |
- 八进制形式
说明符 | 说明 | 数据类型 |
---|---|---|
%o或%mo | 用于基本类型 | int |
%lo或%mlo | 用于长整型 | long |
- 十六进制形式
说明符 | 说明 | 数据类型 |
---|---|---|
%x或%mx | 用于基本类型 | int |
%lx或%mlx | 用于长整型 | long |
m表示输出整型数据所占总宽度(即列数),其中:
① 当实际数据的位数不到m位时,数据前面将用空格填满;
② 若实际数据位大于m,则以数据的实际位数为准进行输出。
一个int型整数也可以用%u输出,反之一个unsigned型整数也可以用%d、%o、%x格式输出。按相互赋值的规则处理。
字符型格式说明符
- 字符char型
说明符 | 说明 | 举例 |
---|---|---|
%c或%mc | 输出的字符占m列 | printf("%3c\n",'a') |
- 字符串型
说明符 | 说明 |
---|---|
%ms | 输出的字符串占m列。若串长>m,全部输出,反之,在串前补空格(正前) |
%-ms | 输出的字符串占m列。若串长>m,全部输出,反之,在串前补空格(负后) |
%m.ns | 输出的字符串占m列。只取字符串前n个字符,不足部分串前补空格(正前) |
%-m.ns | 输出的字符串占m列。只取字符串前n个字符,不足部分串后补空格(负后) |
一个整数,只要其值在0~255范围内,也可以用%c格式使其按字符形式输出。
在这个输出前,系统会自动将该整数作为ASCII转换成相应的字符;反之,一个字符也可以输出成一个整数。
实型格式说明符
-
十进制形式:
%m.nf或%-m.nf
-
指数形式:
%m.ne或%-m.ne
-
%g或%G形式:根据数值的大小,自动选择%f或%e中宽度较短的一种格式,不输出无意义的0
-
在输出实型数据时,格式说明符中的m表示整个数据所占的列宽,n表示小数点后面所占的位数。
-
如果在小数点后取n位后,所规定的数据宽度m不够输出数据前面的整数部分(包括小数点),则按实际的位数进行输出。
-
在C语言中,用于输出单精度实型数据与双精度实型数据格式说明符是一样的。
案例
-
要求:输出实数时,指定小数位
-
代码:
#include "stdio.h"
main()
{
double x=34.567;
printf("x=%f\n",x);// 34.567000
printf("x=%d\n",x);// 34,这种写法错误,自动类型转换异常
printf("x=%d\n",(int)x);// 34
}
案例
要求:设有如下C程序
代码
这个程序的实际运⾏结果为
x=34.567000
x=27263
x=34
说明
显然,这个程序中的第⼆个格式输出语句输出的结果是错误的,这是因为在第二个格式输出语句中,格式说明符%d是基本整型格式说明符,而输出项目是双精度型的数据,它们是不匹配的。
输入数据格式的控制
整型格式说明符
- 十进制形式
说明符 | 说明 | 数据类型 |
---|---|---|
%d或%md | 用于基本整型 | Int |
%ld或%mld | 用于长整型 | long |
%u或%mu | 用于无符号的基本整型 | unsigned |
%lu或%mlu | 用于无符号长整型 | unsigned long |
- 八进制形式
说明符 | 说明 | 数据类型 |
---|---|---|
%o或%mo | 用于基本类型 | int |
%lo或%mlo | 用于长整型 | long |
- 十六进制形式
说明符 | 说明 | 数据类型 |
---|---|---|
%x或%mx | 用于基本类型 | int |
%lx或%mlx | 用于长整型 | long |
可⻅:
① ⽤于输⼊与输出整型数据的格式说明符是完全⼀致的。
② m表⽰输⼊数据时的宽度(列数)
③ 与输出情形⼀样,对于⼋进制与⼗六进制的输⼊格式,主要⽤于输⼊⽆符号的整型数据。
实型格式说明符
单精度实型:%f或者%e
双精度实型:%lf
※ 可⻅:
(1)与输出不同,输⼊时⽆论是单精度还是双精度实型,都不能⽤m.n来指定输出的宽度和⼩数点后的
位数;
(2)可以指定输⼊数据所占的列数,系统⾃动按它截取所需数据,如:scanf("%3d%3d",&a,&b); 当输⼊
1234567时,a得到123,b得到456,多余的7⽆⽤;
(3)若在%号后有⼀个 * 和⼀个数字,表⽰跳过它指定的列数,如: scanf("%2d%*3d%3d",&a,&b); 当输
⼊12345678时,a得到12, %*3d表⽰读⼊345这3个数但不赋给变量, b得到678。
int a,b;
scanf("%3d%3d",&a,&b);
// 1234567
- 当用于输入整型数据的格式说明符中没有宽度说明时,则在具体输入数据时分为以下两种情况:
① 如果各格式说明符之间没有其它字符,则在输入数据时,两个数据 之间用"空格"、或"Tab"、或"回车"来分隔。
② 如果各格式说明符之间包含其它字符,则在输入数据时,应输入与这些字符相同的字符作为间隔。
例如,设有如下说明
int a,b;
float c,d;
现要利用格式输入函数输入a=12,b=78,c=12.5,d=7.6。 采用不同的格式说明,其输入数据的形式也是不同的。分别说明如下:
-
若输入语句为 scanf("%d%d%f%f",&a,&b,&c,&d); (即格式说明符中没有宽度说明,各格式说明符之间也没有其他字符。)
则输入数据的形式应为 12 78 12.5 7.6↲ (两个数据之间用空格来分隔,当然也可用"Tab"或"回车"来分隔。)
-
若输入语句为 scanf("%d,%d,%f,%f",&a,&b,&c,&d);(格式说明符中没有宽度说明,但各格式说明符之间有其它字符,即逗号)
则输入数据的形式应为 12,78,12.5,7.6↲ (即在输入的两个数据之间同时要输入逗号。)
-
若输⼊语句 scanf("a=%d,b=%d,c=%f,d=%f",&a,&b,&c,&d);(即格式说明符中没有宽度说明,但各格式说明符之间有其它字符。)
输⼊数据的形式应为 a=12,b=78,c=12.5,d=7.6↲ (即在输⼊的两个数据之间同时要输⼊这些⾮格
式说明符的字符。)
- 在⽤于输⼊的实型格式说明符中不能⽤m.n来指定输⼊的宽度和⼩数点后的位数(这是与输出的不同之处)。
例如: scanf("%7.2f",&a); × 此用法是错误的