从执行过程上看,从第一条语句到最后一条语句顺序执行,就是最简单的顺序结构。在顺序结构中,各语句是按照位置的先后次序依次顺序执行的,且每条语句都会被执行到。
顺序程序设计举例
1.有人用温度计测量出用华氏法表示温度(如64℉),今要求把它转换为以摄氏法表示的温度(如17.8℃)。
N-S流程图
代码
#include <stdio.h>
int main(){
float f,c;//定义f和c为单精度浮点型变量
f=64.0; //指定f的值
c=(5.0/9)*(f-32);//利用公式计算c的值
printf("f=%f\nc=%f\n",f,c);//输出c的值
return 0;
}
2.计算存款利息。有1000元,想存一年。有3种方法可选:
(1)活期,年利率为r1;
(2)一年期定期,年利率为r2;
(3)存两次半年定期,年利率为r3;
请分别计算出一年后按3种方法所得到的本息和。
N-S流程图
代码:
#include <stdio.h>
int main(){
float p0=1000,r1=0.0036,r2=0.0225,r3=0.0198,p1,p2,p3;//定义变量
p1=p0*(1+r1); //计算活期本息和
p2=p0*(1+r2); //计算一年定期本息和
p3=p0*(1+r3/2)*(1+r3/2); //计算存两次半年定期的本息和
printf("p1=%f\np2=%f\np3=%f\n",p1,p2,p3); //输出结果
return 0;
}
数据的表现形式及其运算
在定义实型变量的同时,对部分变量赋予初值
在输出p1,p和p3的值之后,用\n使输出换行
在计算机高级语言中,数据的两种表现形式:常量和变量。
常量
整形常量:1,10,0,-1等
实型常量:小数形式:1.1;指数形式:12.3e2
字符常量:普通字符'a','Z','#';转义字符'\n','\012','\h1B'
字符串常量:"123","boy"
符号常量:#define PI 3.1416 //注意行末没有分号
转义字符
变量
变量代表一个有名字的、具有特定属性的一个存储单元。变量用来存放数据,也就是存放变量的值。在程序运行期间,变量的值是可以改变的。变量必须先定义,后使用。
常变量
const int a = 3
定义a为一个整型变量,指定其值为3,而且在变量存在期间其值不能改变
常变量与变量的异同:
常变量具有变量的基本属性:有类型,占存储单元,只是不允许改变其值。可以说常变量是有名字的不变量,而常量是没有名字的不变量。有名字就便于在程序中被引用。
#define PI 3.1415926 //定义符号常量
const float pi=3.1415926; //定义常变量
符号常量PI和常变量pi都代表3.1415926,在程序中都能使用。但是二者的性质不同:定义符号常量用#define指令,这个指令是预编译指令,他只是符号常量带表一个字符串,在预编译的时候仅仅进行字符替换,在预编译后,符号常量就不存在了,全置换成了3.1415926,对符号常量的名字是不分配存储单元的。而常变量要占用存储单元,有变量值,只是该值不改变。从使用的角度看,常变量具有符号常量的优点,而且使用方便。有了常变量以后,可以不必多用符号常量。
标识符
标识符就是一个对象的名字。用于标识变量、符号常量、函数、数组、类型等。
标识符只能由字母、数字和下划线3中字符组成,且第一个字符必须为字母或下划线。
同时变量名中区分大小写字母,不能使用关键字作为变量名,变量的名字应该尽量反映变量在程序中的作用与含义。
数据类型
在定义变量的时候需要指定变量的类型,因为在数学中的数和数的运算都是抽象的,但是在计算机中是具体的,数据是存放在存储单元中的,而每一个存储单元中存放数据的范围都是有限的,不可能存放无穷大的数,也不能存放循环小数。
而数据类型就是对数据分配存储单元的安排,包括存储单元的长度(占用多少字节)以及数据的存储形式。不同类型分配不同的长度和存储形式。
数据类型包括基本类型,枚举类型enum,空类型void,派生类型。
基本类型与枚举类型enum的值都是数值,统称为算数类型。
算数类型和指针类型统称为纯量类型,因为其变量的值是用数字来表示的。
不同的数据类型占用不同的存储单元长度
基本类型
基本类型包括整型,浮点型。
整型
基本整形int,占用4个字节,用整数的补码形式存放在存储单元中。正数的补码就是其本身,而复数的补码需要先求出绝对值的原码,然后按位取反,最后+1。在存放整数的存储单元中,最左边的一位是用来表示符号的,0位正,1为负。
短整型short int,占用2个字节。
长整型long int,占用4个字节。
双长整型long long int,占用8个字节。
字符型char
布尔型bool
只有整型数据可以加signed或者unsigned修饰符,实型数据不能加。
对无符号整型数据用%u格式输出。%u表示用无符号十进制数的格式输出。
unsigned short price = 50; //定义price为无符号短整型变量
printf("%u\n",price); //指定用无符号十进制数的格式输出
在将一个变量定义为无符号整型后,变量就只能赋值为正数,不能为负数。
字符型
字符与字符代码
在程序中,如果需要使用字符,只能使用字符集中的字符,否则系统不能识别,一般在代码中,我们使用ASCII来代表字符较多,常用的有26个字母的大小写,数字0~9,空格符包括空格,水平制表符tab,垂直制表符,换行和换页,不能显示的字符包括空字符'\0',警告'\a',退格'\b',回车'\r',和29个专门符号包括!"&'()*,-./:<;=>?[\]^_`{|}~。还有一些其他的字符,但是以上字符更为常用。
用十进制表示,大写字母A的ASCII值为65,小写字母a的ASCII值为97,大小写字母ASCII值差32,相邻字母差1,大写字母的ASCII值较小,通常记住A就可以推断出26个字母大小写的ASCII值了。
数字0的ASCII值为48,其后数字依次+1。
空格字符的ASCII值为32。
这里注意:
字符里面的'1'和整数里面的1是不一样的概念。
字符变量
字符变量是用char定义字符变量
char c = '?'; //定义c为字符型变量并使初始值为字符'?'
//因为'?'的ASCII值为63,所以系统中把整数63赋值给c。
printf("%d %c\n",c,c); //用%d格式输出十进制整数63,用%c格式输出字符'?'
char类型也可以使用signed表示有符号型,unsigned表示无符号型,不管是有符号还是无符号,char始终占用一个字节。
浮点型
浮点型数据是用来表示具有小数点的实数,例如3.1415926。由于二进制形式表示一个实数以及存储单元的长度是有限的,因此不可能得到完全精确的值,只能存储成有限的精确度。小数部分占的位数越多,数的有效数字越多,精度也越高,指数部分占位越多,表示的数值范围越大。
单精度浮点型float,占用4字节,有6位有效数字
双精度浮点型double,占用8字节,占用15位有效数字
复数浮点型float_complex,double_complex,long long_complex
在C中,编译系统把浮点型常量都按双精度处理,分配8个字节。
凡是以小数形式或指数形式出现的实数均是浮点型常量,在内存中都以指数形式存储。
常量类型
因为在程序中出现的常量是要存放在计算机中的存储单元中,这就必须确定分配给其多少字节,按照什么方式存储。每一个变量都属于一个确定的类型,类型是变量的一个重要的属性。变量是占用存储单元的,是具体存在的实体,在其占用的存储单元中可以存放数据,而类型是变量的共性,是抽象的,不占用存储单元,不能用来存放数据。
'n'表示字符常量,23表示整形常量,3.1415926表示浮点型常数。
枚举类型enum
枚举类型是程序中用户定义的整数类型
派生类型
指针类型*
数组类型[]
结构体类型struct
共用体类型union
函数类型
数组类型和结果提类型统称为组合类型
函数类型用来定义函数,包括函数的返回值的数据类型和参数的类型
运算符和表达式
C运算符
常用的算数运算符
两个实数相除的结果是双精度实数,两个整数相除的结果为整数。
%要求参加运算的运算对象为整数,结果也为整数
自增自减运算符
++i; //在使用i之前,i的值先增加1,即先计算i+1,再执行后续程序
--i; //……减少1
i++; //在使用i的时候i的值不变,使用完之后i的值增加1,即先执行程序,再计算i+1
i--; //……减少1
int i = 3,j;
j=++i;
//i=4,j=4
j=i++;
//i=5,j=4
算数表达式和运算符的优先级与结合性
运算对象包括了常量,变量,函数等。在表达式求值时,先按运算符的优先级别顺序执行,当在一个运算对象两侧的运算符的优先级别相同的时候,按照结合方向处理。
如果一个运算符两侧的数据类型不同,则先自动进行类型转换,使二者成为同一种类型,然后进行运算。+,-,*,/运算的两个数中有一个数为float或double型,结果是double型,因为系统会将所有float型数据都先转换为double然后进行运算。
如果是int与float或者double一起运算,或者char与实型数据进行运算,也都是先将所有数据统一转换为double型。
int i=3,j;
float f = 2.5;
double d = 7.5;
printf("%lf",10+'a'+i*f-d/3);
首先进行10+'a'的运算,因为'a'的ASCII的值为97,所以运行结果为107;
因为i两边的运算符不同级,*的优先级比+高,因此先进行i*f的运算,结果为7.5;
然后由107和7.5相加,结果为114.5;
因为d两边的运算符也不同级,/的优先级高于-,所以先进行d/3的运算,运算结果为2.5;
此时由114.5与2.5相加,结果为112.0。
给定一个大写字母,要求用小写字母输出
#include <stdio.h>
int main() {
char c1, c2;
printf("请输入一个大写字母\n");
scanf("%c", &c1); //得到一个大写字母存放到c1中
c2 = c1 + 32; //得到对应的小写字母
printf("对应的小写字母为\n%c", c2); //输出小写字母
return 0;
}
强制类型转换运算符
可以利用强制类型转换运算符将一个表达式转换成所需类型,一般形式为(类型)(表达式)
例如:(int)x表示将a转换成int型,(int)x+y表示将x转换成int型之后与y相加,(int)(x+y)表示将x和y相加之后的结果转换成int型。
C语句
C语句的作用与分类
函数包含两个部分,分别是声明部分和执行部分。执行部分由语句组成,语句的作用是向计算机系统发出操作指令,要求执行相应的操作。
()表示括号中是判别条件,……表示内嵌语句,复合语句通常用在if语句中或循环中。
赋值语句
给出三角形的三边长,求三角形面积
解题思路:
假设给定的三个边符合构成三角形的条件:任意两边之和大于第三边
三角形面积公式为:,其中s=(a+b+c)/2
代码:
#include <stdio.h>
#include <math.h>
int main(){
double a,b,c,s,area; //定义各变量,均为double型
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;
}
输出结果:
sqrt函数是求平方根的函数,由于要调用数学函数库中的函数,必须在程序的开头加一条#include指令,把math.h包含到程序中以便调用。
\t是用来调整输出位置的,\n是用来回车换行的。
“=”的作用是将一个数据赋值给一个变量。在赋值符=之前加上其他的运算符可以构成符合运算符,如果赋值符右边是若干表达式,则默认该表达式有括号,先行运算。例如:
a+=3等价于a=a+3;x*=y+8等价于x=x*(y+8);x%=3等价于x=x%3
赋值表达式的作用是将一个表达式的值赋给一个变量,因此赋值表达式具有计算和赋值的双重功能,但并不是所有形式的数据都可以作为左值的,左值应当为存储空间并可以被赋值,变量可以作为左值,而算术表达式a+b就不能作为左值,常量也不能作为左值。例如如果将上述代码中b=5.43修改为b+a=5.43,则会报错
赋值表达式
举例:a=(b=5)
括号内的b=5是一个赋值表达式,它的值等于5。执行上述表达式,就是分别执行b=5和a=b这两个赋值表达式,因此a=5。赋值运算符按照“自右而左”的结合顺序,因此上述表达式可以去除括号,等价于a=b=5;赋值表达式使得赋值操作不仅可以出现在赋值语句中,而且可以出现在其他语句中,如输出语句,循环语句等
b=3;
printf("%d",a=b);
上述代码输出的值是a的值,输出结果为3。
赋值过程中的类型转换
如果赋值运算符两侧的类型一致,则直接进行赋值。
int i;
i=234; //直接将整数234存入变量i的存储单元中
如果赋值运算符两侧的类型不一致,但都是基本类型,在赋值时要进行类型转换。类型转换是由系统自动进行的,转换的规则是:
1.将浮点型数据(包括单、双精度)赋值给整型变量时,先对浮点数取整,即舍弃小数部分,然后赋予整型变量,举例运行如下图
2.将整型数据赋值给单、双精度变量时,数值不变,但以浮点数形式存储到变量中,举例运行结果如下图:
3.将一个double型数据赋值给float变量时,先将双精度转换为单精度,即只取6~7位有效数字,存储到float型变量的4个字节中,应注意双精度数值的大小不能超出float型变量的数值范围;将一个float型数据赋值给double型变量时,数值不变,在内存中以8个字节存储,有效位扩展到15位。举例运行结果如下图 :
4.字符型数据赋值给整型变量时,将字符的ASCII代码赋给整型变量,举例运行结果如下图:
5.将一个占字节多的整型数据赋值给一个占字节少的整型变量或字符变量时,只将其低字节原封不动地送到被赋值的变量(即发生“截断”),举例运行结果如下:
赋值表达式和赋值语句
C语言中的赋值语句属于表达式语句,由一个赋值表达式加一个分号组成,在一个表达式中可以包含另一个表达式。赋值表达式的末尾没有分号,而赋值语句的末尾必须有分号。在一个表达式中可以包含一个或多个赋值表达式,但绝不能包含赋值语句。例如:
if ((a=b)>0)
max = a;
/*先进行赋值运算,将b赋值给a,然后判断a是否大于0,如果大于,则执行max=a
在这里的a=b就是赋值表达式而不是赋值语句,因为后面没有分号*/
变量赋初值
可以用赋值语句对变量赋值,也可以在定义变量的时候对变量赋以初值。但是如果在定义变量的时候对变量赋值,只可以一个一个赋值,例如int a=3,b=3,c=3;而不可以int a=b=c=3;但是可以int a,b,c;a=b=c=3;
数据的输入输出
输入输出举例
求的根。abc由键盘输入,设
解题思路:
由题可知,方程有两个不同的实根,,,将分式分为两项:,,则,
代码:
#include <stdio.h>
#include <math.h>
int main() {
double a, b, c, disc, x1, x2, p, q; //disc用来存放判别式b^2-4ac的值
scanf("%lf%lf%lf", &a, &b, &c); //输入双精度变量的值要用格式声明%lf
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;
}
运行结果:
scanf函数用于输入abc的值,函数中括号内abc的前面,要用地址符&,&a表示变量在内存中的地址,双引号内用%lf格式声明,表示输入的是双精度型实数。格式声明为“%lf%lf%lf”表示要求输入3个双精度实数。程序运行时,输入“1 2 1”,两两之间用空格隔开。输入虽然是整数,但是由于指定了输入格式,所以系统会自动将整型转换为双精度的实数然后再赋值给变量。
printf函数中,在格式符f之前加了7.2,表示在输出x1和x2的时候,指定数据占7列,其中小数占2列。优点:可以根据实际需要来输出小数的位数,如果输出多个数据,可以使输出数据整齐美观。
有关输入输出的概念
1.输入输出是以计算机主机为主体而言的 。
2.C语言本身不提供输入输出语句。输入输出操作时由C标准函数库中的函数来实现的,优点:简化编译系统简化,增强通用性和可移植性
3.要在程序文件的开头用预处理指令#include把有关头文件stdio.h放在本程序中。
关于#include指令说明
三种形式:
#include "c:\cpp\include\myfile.h"——按指定路径查找文件
#include "myfile.h"——源程序文件所在目录
#include <myfile.h>——C编译系统指定的include目录
printf函数
用来向终端(或系统隐含指定的输出设备)输出若干个任意类型的数据。
//标准格式:printf(格式控制,输出表列)
printf("i=%d,c=%c\n",i,c);
/*
i=是普通字符,可以直接被输出
%是格式声明,%d表示输出的类型为整数类型
引号中是格式控制
引号外面的i,c是输出列表
*/
格式字符 | 说明 |
---|---|
d,i | 以带符号的十进制形式输出整数(正数不输出符号) |
o | 以八进制无符号形式输出整数(不输出前导符0) |
x,X | 以十六进制无符号形式输出整数(不输出前导符0x),用x则输出十六进制数的a~f时以小写形式输出,用X则大写 |
u | 以无符号十进制形式输出整数 |
c | 以字符形式输出,只输出一个字符 |
s | 输出字符串 |
f | 以小数形式输出单、双精度数,隐含输出6位小数 |
e,E | 以指数形式输出实数,用e时指数以“e”表示(如1.2e+02),用E时指数以E表示(如1.2E+02) |
g,G | 选用%f或%e格式中输出宽度较短的一种格式,不输出无意义的0.用G时,若以指数形式输出,则指数以大写表示 |
附加字符 | 说明 |
l | 长整型整数,可加在格式符d,o,x,u前面 |
m (代表一个正整数) | 数据最小宽度 |
n (代表一个正整数) | 对实数,表示输出n为小数,对字符串表示截取的字符个数 |
- | 输出的数字或字符在域内向左靠 |
printf函数输出时,务必注意输出对象的类型应与上述格式说明匹配,否则将会出现错误
除了X,E,G外,其他格式字符必须用小写字母
可以在printf函数中的格式控制字符串内包含转义字符\n,\t,\b,\r,\f,\377等
一个格式声明以%开头,以格式字符之一为结束,中间可以插入附加格式字符(也称修饰符)
如果想输出字符%,应该再格式控制字符串中连续使用两个%表示,如下图所示:
在用%f输出时要注意数据本身能提供的有效数字,如float型数据的存储单元只能保证6位有效数字。double型数据能保证15位有效数字,如下图所示:
虽然A是双精度型,A的结果也是双精度型,但是用%f格式声明只能输出6位小数。一个双精度只能保证15位有效数字的精确度,即使制定小数位数为50(%55.50f)也不能保证输出的50位都是有效数字,如下图所示:
scanf函数
用来输入数据
//scanf(格式控制,地址表列)
scanf("a=%f,b=%f,c=%f",&a,&b,&c);
/*
"a="普通字符
"%"格式声明
"……"格式控制
"&"地址表列
*/
格式控制是用双引号括起来的一个字符串,含义同printf函数。包括格式声明和普通字符
地址表列是由若干个地址组成的表列,可以使变量的地址或字符串的首地址。
格式字符 | 说明 |
同printf函数格式声明 | 同printf函数格式声明 |
附加字符 | 说明 |
l | 输入长整型数据(可用%ld,%lo,%lx,%lu)以及double型数据(用%lf或%le) |
h | 输入短整型数据(可用%hd,%ho,%hx) |
域宽 | 指定输入数据所占宽度(列数),域宽应为正整数 |
* | 本输入项在读入后不赋给相应的变量 |
scanf函数中的格式控制后面应当是变量地址,而不是变量名。
如果在格式控制字符串中除了格式声明以外还有其他字符,则在输入数据时在对应的位置上输入与这些字符相同的字符。如下图所示:
在用“%c”格式声明输入字符时,空格字符和“转义字符”中的字符都作为有效字符输入。
在输入数值数据时,如输入空格,回车,tab键或遇非法字符(不属于数值的字符),认为该数据结束。
字符输入输出函数
putchar函数
从计算机向显示器输出一个字符,putchar(c)
先后输出BOY三个字符
解题思路:
定义3个字符变量,分别赋以初值‘B’‘O’‘Y’,然后用putchar函数输出这3个字符变量的值
代码:
#include <stdio.h>
int main() {
char a = 'B', b = 'O', c = 'Y'; //定义3个字符变量并初始化
putchar(a); //向显示器输出字符'B'
putchar(b); //……'O'
putchar(c); //……'Y'
putchar('\n'); //……换行符
return 0;
}
用putchar函数既可以输出可显示字符,也可以输出控制字符和转义字符。putchar(c)中的c可以使字符常量、整形常量、字符变量或整型变量(其值在字符的ASCII代码范围内)。例如:
getchar函数
向计算机输入一个字符,getchar()
从键盘输入BOY3个字符,然后把他们输出到屏幕
解题思路:
用3个getchar函数先后从键盘向计算机输入BOY3个字符,然后用putchar函数输出
代码:
#include <stdio.h>
int main() {
char a, b, c; //定义3个字符变量
a = getchar(); //从键盘输入一个字符送给字符变量a
b = getchar(); //从键盘输入一个字符送给字符变量b
c = getchar(); //从键盘输入一个字符送给字符变量c
putchar(a); //向显示器输出字符变量a的值
putchar(b); //……b……
putchar(c); //……c……
putchar('\n'); //换行
return 0;
}
函数没有参数,函数的值就是从输入设备得到的字符
只能接收一个字符
如果想输入多个字符就要用多个函数,不仅可以从输入设备获得一个可显示的字符,而且可以获得控制字符
用getchar函数得到的字符可以赋给一个字符变量或整型变量,也可以作为表达式的一部分,如putchar(getchar());将接收到的字符输出
从键盘输入一个大写字母,在显示屏显示对应的小写字母
解题思路:
用getchar函数从键盘读入一个大写字母,把它转换为小写字母,然后用putchar函数输出该小写字母
代码:
#include <stdio.h>
int main() {
char c1, c2;
c1 = getchar(); //从键盘读入一个大写字母,赋给字符变量c1
c2 = c1 + 32; //求对应小写字母ASCII代码,放在字符变量c2中
putchar(c2); //输出c2的值,是一个字符
putchar('\n');
return 0;
}