C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 1
例 1 辗转相除法求最大公约数假设 m>=n:
m = 10; n=6; r = 4
m = 6; n = 4; r = 2;
m = 4; n = 2; r = 0;
最大公约数为 n = 2
Y N
输入 m,n
m>n
m,n互换
r=m%n
当 r不为零时
n=>m
r=>n
r=m%n
输出 n
回顾:算法的概念、特性、表示与设计方法
Y N
m,n互换输入 m,n
m>n
r = m%n
r = 0 Y
输出 n
N
n =>m
r =>n
直到 r =0
编程技巧:遇循环时考虑当 … 执行 …
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 2
例 2 输出 100-200间的素数思考:图 2-34循环结束条件编程技巧:标记变量 (变量仓库 计数器 累加 /乘器)
回顾:算法的概念、特性、表示与设计方法 n= 100
当 n<=200
判断 n是否素数
n为素数
Y N
输出 n
n=n+1
i= 2
当 i<=sqrt(200)且 flag=0
n%i=0
Y N
flag=1
flag= 0
i=i+1
n= 100
当 n<=200
flag=0
Y N
输出 n
i= 2
当 i<=sqrt(200)且 flag=0n%i=0
Y Nflag=1
flag= 0
i=i+1
n=n+1
#include<stdio.h>#include<math.h>/*库函数 */
void main(){
int n,i,flag;n=100;
while(n<=200){
flag=0;i=2;
while(i<=sqrt(200)&&flag==0){ if(n%i==0)flag=1;i=i+1;}
}if(flag==0)printf(“%d\n”,n);
n=n+1;}
0?t,1?i
t+i?t
i+1?i
直到 i>100
输出 t 的值回顾:算法的概念、表示与设计方法开始
0?t,1?i
t+i?t
i+1?i
i>100
不成立成立输出 t 的值结束
sum=0
i=1
while(i<=100)
sum+i?sum
i+1?i
Print(sum)
#include<stdio.h>
void main()
{
int i,sum;
sum=0; i=1;
while(i<=100)
{
sum=sum+i;
i=i+1;
}
printf(“%d\n”,sum);
}/*结果为 5050*/;

例 3 求 t=1+2+… +100
第三章
主要内容
3.1 C的数据类型
3.2 常量与变量
3.3-3.5 整型、浮点型、字符型数据
3.6 变量赋初值
3.7 各数值型数据间的混合运算
3.8-3.10 各类运算符和表达式描述规则操作规则
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 6
§ 3.1 C的数据类型指针类型空类型 void
构造类型数组类型结构体类型 struct
共用体类型 union
枚举类型 enum
基本类型整型 int
字符型 char
浮点型 单精度实型 float双精度实型 double
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 7
§ 3.2 常量与变量
3.2.1 常量和符号常量
在程序运行过程中,其值不能被改变的量称为常量整型 5 -12 010 -010 0x2 -0x2F
实型 0.12 12,12.3e3 -1E4
字符型 ‘ aA2$\n\\\101?
\x2A?
字符串? study hard!”,a”
小数点不可丢
E或 e前不空,后为整规范化指数形式,1.23e3
分普通字符和转义字符 P48
a \0
字符串都是用字符数组实现
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 8
#define PRICE 30
#include <stdio.h>
void main ( )
{
int num,total;
num=10;
total=num * PRICE;
printf(″total=%d \n″,total);
}
1、含义清楚,见名知意
2、一改全改
3、不是变量,不可被赋值
4、符号常量多用大写表示符号常量,用一个标识符代表一个常量,如可定义 PI=3.14
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 9
变量代表内存中具有特定属性的一个存储单元,变量的值就是当中存放的数据,程序运行期间当中存放的数据可变
为变量赋值就是根据变量名找到相应存储单元,之后将数据写入其中;取变量的值就是通过变量名找到相应的内存地址,之后从该存储单元中读取数据
变量使用前必须声明,且最好 见 名 知意
3.2.2 变量
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 10
§ 3.3 整型数据
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
3.3.1整型常量的表示方法 (略 )
3.3.2 整型变量
(1)整型数据在内存中的存放形式,二进制补码如,int i,j; /*TC为两者各分配两字节空间 */
i=10;
j= -10 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0
为何用补码? ± 0的统一、使符号位能一起参与运算简化运算规则、减法变加法从而简化线路设计
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 11
(2)整型变量的分类:
共六种有符号基本整型有符号短整型有符号长整型无符号基本整型无符号短整型无符号长整型
(signed)int
(signed)short (int )
(signed) long (int)
unsigned int
unsigned short (int)
unsigned long (int)
2/4字节
2字节
4字节
2/4字节
2字节
4字节注:考虑各种类型整数的取值范围?
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 12
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
(4)数据溢出问题假设 int型,用 TC编译系统,输出 32767+1=?
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 13
§ 3.4 浮点型数据
3.4.2 浮点型变量
(1)浮点型数据在内存中的存放形式采用 IEEE-754标准,如 float型占 4字节,1个符号位,8指数位,23位尾数,具有 24位精度
3.4.1浮点型常量的表示方法如 17.625,首先 17.625= 10001.101= 1.0001101× 24
符号占 1位,0 指数部分 8位,4+127=131=10000011
尾数部分 23位,0001101 0000 0000 0000 0000(省略整数 1)
故 17.625标准格式为,0 10000011 00011010000000000000000
即,41 8D 00 00
思考:浮点格式如何转换为十进制? 如 42E48000= 114.25
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 14
类型 位数 数的范围 有效数字
float 32 10-37 ~ 1038 6~7 位
double型 64 10-307~10308 15~16位
long double 128 10-4931~104932 18~19位
(2) 浮点型变量的分类
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 15
例 3.4 浮点型数据的舍入误差
#include <stdio.h>
void main()
{float a,b;
a = 123456.789e5;
b = a + 20 ;
printf(“%f \n”,b);
} 说明,浮点型变量只能保证 7位有效数字,之后的数字无意义。应避免将很大的数和一很小的数直接相加或相减,否则就会“丢失”小的数。注意转换为浮点格式进行运算
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 16
§ 3.5字符型数据
3.5.2字符变量
字符变量在内存中占一个字节,存放字符对应的 ASCII码值,如字符 ’ A?实际存放 65
定义,char c1,c2;
通常赋值:
c1= ‘ a?; c2= ‘ b? ; char c3=?c?;
3.5.1 字符常量与字符串常量:’ a’与,a”区别
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 17
3.5.3字符数据在内存中的存储形式及其使用方法字符型数据和整型数据之间可通用
字符变量输出时可以字符形式 %c输出,也可以整数形式 %d输出,如例 3.6
注:对 ASCII码值介于 128-255间的字符,以 %d输出时有的系统输出负数,有的输出正数。可在定义字符变量时用 signed char或者 unsigned char来消除歧义
两者可进行算术运算,char c; c=?A?+32;例 3.7
两者可相互赋值 int i=?a?;char c=97;
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 18
小结:
1、整型,以补码形式存放,对于有符号变量,读入寄存器时按符号位扩充,无符号变量高位扩充 0。
2、浮点型,采用 IEEE-754标准规定的格式存放,如 float型占 4字节,1个符号位,8指数位(真正指数加 127),23位尾数,具有 24位精度。如 -17.625
3、字符型,内存中占一个字节,存放字符的 ASCII码,取入寄存器时,有的系统按符号位扩充,有的扩充零
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 19
实验说明,进一步参考第三章作业说明
char c2;
c2=400;
printf(“%c\n”,c2); /*问号 */
printf("%d\n",c2);/*-112*/
short a; unsigned short c; long e;
a=100; e=50000; c=a=e;
printf(“%d\n”,a); /*-15536*/
printf(“%u \n”,c); /*50000*/
printf(“%x\n”,a); /*ffffc350*/
printf(“%o \n”,c); /*141520*/
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 20
补充,P60-61
1、由真值求补码,先将数值部分转为二进制,对于正整数高位补 0即可;对于负整数,高位先补零,之后变反,
再末位加 1)。 由补码求真值,若补码最高位为 0则直接转十进制即可,否则,对补码,逐位变反末位加 1”,转成十进制,再加负号
2、整型、字符型数据相互赋值,先将赋值号右侧的值读入寄存器,之后从低到高截取相应数目的字节写入左侧变量对应的内存单元
3、输出结果分析,输出时现将欲输出的值读入寄存器,
以% c输出意味着输出 ASCII码值与寄存器最末一个字节对应的字符 ; 以% d输出意味着将寄存器中的数据当作补码,
输出此补码对应的真值;以% u输出意味着将寄存器中的数据当作一个无符号的二进制数,直接转换为十进制数后输出; 以% x或% X输出则将寄存器中的二进制数从低到高四位合一位输出,高位零省略;以% o则三位合一位输出
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 21
§ 3.6变量赋初值
float f=3.56; /*相当于 float f;f=3.56;
int a=3,b,c=5;/*不可写作 int a=b=c=5;但可先定义
int a,b,c;之后再用 a=b=c=5;*/
char c=‘a’;
注:赋值是在函数执行时进行的
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 22
① 浮点型数据 =>整型变量,舍弃小数部分
② 整型数据 =>浮点型变量:数值不变,以浮点数形式存储
③ double型 =>float变量:截取其前 7位有效数字,实际是指数部分与尾数部分分别截取。
④ float型数据 =>double变量:数值不变,有效位扩展
⑤各类整型、字符型之间:先将右侧值读入寄存器,之后截取相应数目的字节放入左侧变量的存储单元
P60-62 int?short unsigned?unsigned short
不同类型数据间相互赋值:
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 23
§ 3.7各类数值型数据间的混合运算不同类型的数据进行混合运算时,系统自动进行将它们转换成同一类型,之后进行运算
,具体转换规则如图 3.10
10+?a?+i*f-d/l
1/3 1./3 i/3 i*1./3
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 24
作业:
作业本:用 N-S图表示 2.4(6); 2.8(2)的算法设计过程
3.4 3.6
上机,(1)报告:实验 18.2(1)(3),分析 各步的运行结果,
注意将 (3)中 int改作 short
( 2)调试作业中的程序,发现问题作为“总结”
记入试验报告
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 25
一、算法设计与表示遇循环时考虑 当 …,执行 …,
变量仓库 计数器 标记变量回顾:
#include<stdio.h>
#include<math.h>/*库函数 */
void main()
{
int n,i,flag;
n=100;
while(n<=200)
{
flag=0;
i=2;
while(i<=sqrt(200)&&flag==0)
{ if(n%i==0)flag=1;i=i+1;}
}
if(flag==0)printf(“%d\n”,n);
n=n+1;
}
n= 100
当 n<=200
判断 n是否素数
n为素数
Y N
输出 n
n=n+1
i= 2
当 i<=sqrt(200)且 flag=0
n%i=0
Y N
flag=1
flag= 0
i=i+1
n= 100
当 n<=200
flag=0
Y N
输出 n
i= 2
当 i<=sqrt(200)且 flag=0n%i=0
Y Nflag=1
flag= 0
i=i+1
n=n+1
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 26
二、数据类型回顾:
1、整型,以补码形式存放,对于有符号变量,读入寄存器时按符号位扩充,无符号变量高位扩充 0。
2、浮点型,采用 IEEE-754标准规定的格式存放,如 float型占 4字节,1个符号位,8指数位(真正指数加 127),23位尾数,具有 24位精度。如 -17.625
3、字符型,内存中占一个字节,存放字符的 ASCII码,取入寄存器时,有的系统按符号位扩充,有的扩充零
4、不同数据类型间混合运算,char short?int float?double
Int? signed?long?double
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 27
实验说明,进一步参考第三章作业说明
char c2;
c2=400;
printf(“%c\n”,c2); /*问号 */
printf("%d\n",c2);/*-112*/
short a; unsigned short c; long e;
a=100; e=50000; c=a=e;
printf(“%d\n”,a); /*-15536*/
printf(“%u \n”,c); /*50000*/
printf(“%x\n”,a); /*ffffc350*/
printf(“%o \n”,c); /*141520*/
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 28
§ 3.8 算术运算符和算术表达式
3.8.1 C运算符简介
(1)算术运算符 ( + - * / %)
(5)赋值运算符 (=及其扩展赋值运算符,如 x+=y-1)
(7)逗号运算符 (如 x>=y,x>=z)
(10)强制类型转换运算符 (int)x或 (int)(x+y)
(13)自增 /自减运算符,如 i++ ++i i-- --i
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 29
§ 3.8.2 算术运算符和算术表达式
1、算术运算符:编译系统整除时多向零取整 -5/3
2、算术表达式,优先级和结合性
算术表达式:用算术运算符和括号将运算对象连接起来的符合 C语法规则的式子。每个表达式都有一个值
算术表达式求值时,先乘除后加减(优先级决定),
若优先级相同则按自左至右的顺序进行运算(结合方向决定)
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 30
3、强制类型转换。
#include <stdio.h>
voidmain()
{float x;
int i;
x=3.6;
i=(int)x;
printf("x=%f,i=%d\n",x,i);

说明,类型转换有两种,一种是系统自动进行的转换,如 3+6.5。第二种是强制类型转换。注意转换时产生一个临时变量,原变量类型不变
运行结果:
x= 3.600000,i=3
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 31
4、自增、自减运算符
( 1) i++与 ++i的区别:
++i是先执行i=i+1,后使用i的值;
i++是先使用i的值,后执行i=i+1。
例,i=3;j=++i; k=i++;
( 2)优先级与结合方向:
i=3; j=-i++;相当于 j=-(i++); P365
注意:自增、自减运算符只能用于变量
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 32
5、表达式问题说明:
( 1)编程时要避免“歧义”
a=f1( )+f2( ); => b=f1( );c=f2( );a=b+c;
a=(i++)+(i++) => b=i++;c=i++;a=b+c;或 a=i+i;i+=2;
(2)运算符的组合,i+++j相当于 (i++)+j或 i+(++j)?
尽可能多地自左而右将若干个符号当作一个运算符
(3) 函数调用时实参的求值顺序:
printf(“%d,%d”,i,++i);
=>j=++i;
printf(“%d,%d”,i,j);
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 33
§ 3.9 赋值运算符和赋值表达式
(1)赋值运算符,用来将一个数据值赋给一个变量
(2)类型转换
①浮点型数据 =>整型变量,舍弃小数部分
② 整型数据 =>浮点型变量:数值不变,以浮点数形式存储
③ double型 =>float变量:截取其前 7位有效数字,实际是指数部分与尾数部分分别截取。
④ float型数据 =>double变量:数值不变,有效位扩展
⑤各类整型、字符型之间:先将右侧值读入寄存器,之后截取相应数目的字节放入左侧变量的存储单元
P60-62 int?short unsigned?unsigned short
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 34
(3)复合的赋值运算符,x%=y+3相当 x=x%(y+3)
(4)赋值表达式,表达式的值对应左侧变量的值例,c=259;i=c=259;a=(b=4)+(c=6)
注意,(1)赋值表达式可作左值,如
(a=3*5)=4*6可以,但 a=3*5=4*6不可
(2)赋值运算符右结合,且优先级仅比逗号运算符高
a+=a-=a*a相当于 a=a+(a=a-a*a);
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 35
§ 3.10 逗号运算符和逗号表达式逗号运算符,用来 将两个表达式连接起来,又称? 顺序求值运算符?,左结合,优先级最低逗号表达式扩展形式:表达式1,表达式2,,……,表达式n
一般形式:表达式1,表达式2 值为式 2的值例,(a= 3*5,a *4),a+5
例:比较 x=(a= 3,6*3) 与 x=a=3,6*3
C语言程序设计 (第三版) http://ccf.tsinghua.edu.cn 36
作业:
作业本,3.9 3.10 3.12( 5)( 6)