Transcript Document

第三章
最简单的C程序设计
---顺序程序设计
主要内容
• 数据类型及运算
• C语句
• 数据的输入输出
3.1 顺序程序设计
计算y=2x^2+3x-1;
可以编写简单程序如:
#include <stdio.h>
变量定义
初始化 x:=5
计算
y:=2x^2+3x+1
输出y
int main(){
int x,y;
函
数
x=5;
体
y=2*x*x+3*x-1;
printf(“y=%f \n”,y);
return 0;
输出结果
}
3.2 C语言的数据类型
基本类型
整型(short、int、long)
浮点型(实型)(float、double)
字符(char)
枚举(enum)
数组类型([ ])
数据类型
构造类型
结构体类型(struct)
共用体类型(union)
指针类型(*)
空类型(void)
3.2.1 常量
• 程序运行过程中值不能改变的量
• 只能初始化赋值
直接常量
常量
char a=‘0’
符号常量
整型:-1, 0, -3
浮点型(实型): 4.6, -2.1,1.2e-3
字符: ‘a’, ‘0’, ‘\n’,‘\102’, ‘\x42’
字符串: “china”,”12baby”
#define PI 3.1415926
const float PI = 3.1415926;
符号
符号
例:
#define
PI
3.14159 26
int main()
{
float r=2,c,s;
c=2*PI*r;
s=2*PI*r*r;
printf(“c=%f,s=%f”,c,s);
return 0;
具有含义清楚、见名知意、修改
}
方便、一 改全改的优点
■变量
其值可以改变的量。
变量的三要素:
① 变量名
每个变量有一个名字,作为识别该变量的
标识符。
② 变量的值
每个变量有一个值,变量的值是随时
可以改变的。
③变量的存储单元
每个变量占据一个内存单元,用于存放变量
的值,内存单元的大小取决于变量的类型。
变量名的本质是内存地址。
int a=3;
变量名
a
3
变量值
存储单元
标示符(变量、函数、数组、符号常量)的
命名规则:
由字母、数字和下划线组成
以字母或下划线开头
a、x1、y_2、_b1、_1c
1x、a+2、Ф、Ω
合法
不合法
变量必须先定义后使用,且不能与关键字重
名。float int=3.0;
程序中何时使用常量?何时使用变量?
3.2.3 基本数据类型
•
•
•
•
•
整型数据
实型数据
枚举类型(enum)
空类型(void)
派生类型:指针,数组,结构体,共用
体等
3.2.3 整型数据
■整型常量
即整常数,c的整常数有三种形式:
①十进制整数
与数学中的整数一致,如:100,123,15等。
②八进制整数
以0开头的整数,如:010,07,020等。
③十六进制整数
以0x开头的整数,如:0x10,0xff,0x2a等。
■整型变量
用于存放整数的变量。
位(bit):01012
分4种类型:
1字节=8 bits
①基本型:int a
16/32位,可表示的数值范围:-32768—32767
②短整型:short int b
16位,可表示的数值范围:-32768—32767
③长整型:long int c
32位,数值范围:-2147483648—2147483647
④双长整型: long long int d;
64位,数值范围:-2^63---2^63-1
无符号型:加上 unsigned
只存放正数。
如:unsigned int x
变量x为无符号整数,16位全表示数码,
数值范围:0—65535(11111111 11111111)
在程序设计中,如果要使用整型变
量,必须首先选择以上类型符来定义变量,
然后才能使用;
例:
main()
{ int a,b,c;
a=100; b=50;
c=a+b+d;
printf(“%d”,c);
}
定义
使用
一般根据什么原则选择变量的类型?
• 整型变量 存储形式
int i=-10;
10/2=5 余数0
5/2=2 余数1
2/2=1 余数0
1/2= 0 余数1
10的二进制:1010
0 0
… 0 0 0 0 1 0 1 0
10的原码
1 1
… 1 1 1 1 0 1 0 1
取反
1 1
… 1 1 1 1 0 1 1 0
再加1,得10的补码
3.2.4
字符型数据
■字符常量
用单引号括起来的一个字符(127个ASCII字
符集)。
‘a’,’x’,’*’,’1’等
除此外,以’\’开头的字符如’\n’,’\t’等
称为转义字符,详见书表3.1
■字符型变量
用于存放字符的变量。
[unsigned/signed] char c1,c2
c1和c2为字符型变量
c1=’a’;
c2=’b’; 字符赋值
定义
字符型变量存放一个字符,占据一个字节
■字符型数据的存储形式
a
存放ASCII码 不是
而是 97
如字符’a’在内存中存放97,’b’ 存放98。
与整数的存储形式一致,它们之间可以通
用
一个字符数据既可以作字符用,也可以作
整数用(取其ASCII代码)。
如:32+’a’相当于 32+97
若 int x; char c;
则 x=’a’; c=97; x=97; c=’a’; 都允许
■字符串常量
用双引号括起来的字符序列。
如:”abcde”,”china”
”a”也属字符串。 注意”a”与’a’的区
别。
对于:
char c;
c=”a”;
用法错误
字符串中每个字符各占一个字节,并且在
字符串结尾加上一个结束标记’\0’
如:”china” 在内存中占6个字节。
c
h i
n
a \0
C语言中专门的字符串变量,可用字符数
组存放(以后介绍)。
3.2.5
实型数据
■实型常量
可使用两种形式表示:
①小数形式:如 1.23, 3.1415926
②指数形式:如
1e-20
1.23e5
e3, 1.2e3.0, .e3, e
规范化的指数形式0.314159e001
15.48
■实型变量
用于存放实数的变量
分单精度和双精度两种:
float a,b
定义a和b为单精度型变量
32位,6位有效数字,10-38—1038
double x,y
定义x和y为双精度型变量
64位,15位有效数字,10-308—10308
例:
main(){
float r,c;
//double
r=5;
c=2*3.1415926*r;
printf(“%f”,c);
}
r,c;
3.2.7 算术运算符与算术表达式
■基本的算术运算符
+
- *
/ %
■算术表达式
用算术运算符将运算对象连接起来的式子
用于表达数学公式的式子
如:2*x+y-1/a
表达式经过运算最终得到一个值:
算术表达式的值
■运算符的优先级与结合性
优先级:
在对表达式求值时,如果存在多个运算符,则
运算的先后次序按运算符的优先级别从高到底进
行。
运算符的优先级关系为:
高:* / %
低:+ 如:a-2*x
先算 *
2*(a+2)
有括号的情况?
结合性:
如果在一个运算对象两边的运算符的优先级相
同,则按规定的“结合方向”处理。
如:a-b+c
b与-结合是从左到右,称“左结合性”。
b与+结合是从右到左,称“右结合性”。
每个运算符都有相应的优先级和结合性。
基本算术运算符都是左结合性。
计算表达式例:
2+’A’-1/2.0
1+3/2-1
构造表达式例
2x2+3x-1
a+b
a+b
a-b
2*x*x+3*x-1
(*不能省)
(a+b)/(a-b)
a+b/a-b ?
(a+b)/(a-b)/(x+y)/(x-y)
(a+b)/(a-b)/((x+y)/(x-y))
a-b
x+y
x-y
■自增、自减运算符
自增运算符:++
使变量值加1
自减运算符:-使变量值减1
两种用法:
++i, --i
先加(减)后用
i++, i-先用后加(减)
两种用法对i效果一样,但表达式的值不同。
例:假设i的原值为5:
j=++i;
j=?
j=i++;
j=?
注意:
●++和--只能用于变量。
如:3++和(a+1)++ 不合法
深层次(i++)++还是(++i)++
error
●++和--为右结合性。
(-i)++
-i++
-(i++)
若i的原值是5,则该表达式的值是多少?
例:分析执行下列语句后的结果:
a=5;
a
b=a++;
65
c=--a-b++;
d=(a++)-(++b)+c--;
b
675
c
-1
0
d
-2
两种特殊情况:
① k=(i++)+(i++)+(i++);
② k=i+++j;
是 i+(++j) 还是 (i++)+j
? 取决于编译器
Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation of
an expression.---The Standard
sequence point: at the end of the evaluation of a full expression,
at the ||, &&, ?:, and comma operators; at a function call ;
i++虽然与i=i+1等效,但使用自增自减
运算符的代码优化程度好,因而经常使用;
但用时需特别小心。for(i=0;i<10;i++)
各数值型数据间的混合运算
整型、实型、字符型数据间可以进行混合运
算,如:
int i;float f;double d;
10-‘a’+i*f-d/3
运算时,参加运算的两个数据如果类型不同,
则首先将其类型转换成一致再运算,转换规则
是:
将优先级低的类型转换到优先级高的类型
数据类型的优先级:
高
double
float
long
unsigned
低
int
char short
int main(){
int a = 3;
unsigned int b = 4;
if((a-b)>a) printf("aaaaaaaa\n");
else printf(“bbbbbbb\n”);
}
输出结果:aaaaaaaa
■强制类型转换
可以用强制类型转换运算符将一个表达式
的值转换成所需类型:
(类型名)(表达式)
如:
(int)(x+y)
(float)(7%3)
应用举例:
int a=200,b=300,c; (int 2字节)
c=(long)a*b/100;
c=a*b/100;100
?c=(long)(a*b)/100;
可知,有自动转换和强制转换,
当自动转换达不到目的时,可用强制转换。
3.3 C语句
1.
2.
3.
4.
控制语句(9种):if (){}else{};for();return;…goto ;
函数调用语句: printf(“Hello world”);
表达式语句: i=i+1;
空语句: ;
5. 复合语句: int a,b=5,c;
3.3.2 赋值运算符和赋值表达式
■赋值运算符
“=”称赋值运算符,其作用是将一个数据
赋给一个变量。
如: a=5;
不要理解为“等号(==)”。
执行赋值运算的结果,是将右边的数据存
入左边变量所对应的内存单元中。
■赋值规则
如果赋值运算符两侧的类型不一致,则在赋
值时要进行类型转换,转换规则为:
●实型→整变量
舍去小数部分。
int a=5.5; a中为5。
●整型→实变量
数值不变,以浮点形式存储。
●字符型→整变量
放在整形变量低8位。保持原值不变原则。
int a=‘A’;
■复合赋值运算符
在赋值运算符前加上其它运算符,可以构成
复合赋值运算符。
a+=3
—— a=a+3
b-=x+5 —— b=b-(x+5)
x*=c-6 —— x=x*(c-6)
y/=a*4 —— y=y/(a*4)
k%=b-2 —— k=k%(b-2)
属于高效率运算符。
■赋值表达式
主要实现赋值运算的表达式。
一般形式:
<变量> = <表达式>
如: a=5 y=2*x+3 a=a+1
不是衡等
作用:将右边表达式的值赋给左边的变量。
赋值表达式的值取左边变量的值。
赋值表达式右边的<表达式>可以是任何表
达式,如:
a=(b=5)
赋值表达式中包含赋值表达式
赋值运算符的优先级低于所有算术运算符,
且是右结合性。
a=(b=5) 与 a=b=5 等效。
例:计算以下表达式的值:
a=b=c=5
a=5+(c=6)
a=(b=4)+(c=6)
a=(b=4.5)+(c=6.5) (a、b、c为整型变量)
a+=a-=a*a
a=(b=c)=5
(设a的原值为3)
ERROR
赋值表达式是C语言中的一个重要成分,
在赋值表达式后加一分号就成为常用的赋值
语句。如 y=2*x+1;
赋值表达式作为表达式的一种,可以出
现在任何表达式中,如:
x+2-(b/3-(a=k-5)+’b’
赋值语句与赋值表达式
if((a=b);>0) c=a; // 语法错误
If((a=b)>0) c=a;
错误说明:page 63:
-32768 补码:1000 0000 0000 0000
-1的补码:
1111 1111 1111 1111
变量赋初值
在定义变量的同时给相应的变量赋初值。
如:
int a=3;
a 3
float b=5.2;
char c=’a’;
int x=3,y=3,z=3; int x=y=z=6;
效果:
在给变量分配内存单元的同时在相应的单
元中存放初值。
逗号表达式(补充内容)
逗号也是一种运算符,用它对两个表达式
实现连接运算。
3+5,6+8
称逗号表达式。
逗号表达式的一般形式:
表达式1,表达式2
取表达式2的值作为整个逗号表达式的值。
如: a=3*5,a*4
逗号表达式的值为:60
一个逗号表达式又可以与另一个表达式组成
一个新的逗号表达式,如:
(a=3*5,a*4),a+5
因此,逗号表达式的一般形式可以扩展为:
表达式1,表达式2,表达式3,……, 表达式n
取表达式n的值作为整个逗号表达式的值。
逗号运算符的优先级最低,且是左结合性。
每个表达式都要计算
a=3*2,a++,a*2
逗号运算符只起到连接作用,没有实际操作。
int a=0,x,b=0,c=0;
x= (a=3,6*3);
x=a=3,6*a;
x=x%=(a%=5),b;
x=(c=(c-=a-5),(a=b,b+3));
3.4数据的输入输出
• 任意整数x计算y=2x^2+3x-1
• main(){
•
int
x,y;
•
x=5;
scanf(“%d”,&x);
•
y=2*x*x+3*x-1;
printf(“y=%d”,y);
•
}
该程序语法上完整,但还缺少输入和输出。
输入输出概念
• 以计算机为主体
• C语言本身不提供输入输出语句
• 常用输入输出语句
字符输入输出:getchar(); putchar();
格式输入输出: scanf(); printf();
字符串输入输出:gets(); puts();
• #include<stdio.h> or #include
“stdio.h”
3.4.3 printf()格式输出函数
printf(格式控制,输出列表)
任意类型、任意格式、任意个数。
例如:
int a=100,b=56;
printf(“a=%d,b=%d”,a,b);
普通字符
格式声明
格式字符 输出表列
输出结果:a=100,b=56
“%” 后的字符称格式字符,不同格式字符对应不同的数据类型。
d格式符:按十进制整数格式输出
几种用法:
%d 不指定域宽(列数),按实际宽度输出
%md 按指定域宽输出,m为宽度,m>0靠右对齐,
m<0靠在输出;
%ld 用于输出长整型数
例:
int
long
a=125,b=453;
c=65535;
printf(“a=%d,b=%5d,c=%ld”,a,b,c);
printf(“a=%d,b=%-5d,c=%ld”,a,b,c);
输出结果:
a=125,b=
453,c=65535
a=125,b=453
,c=65535
m<输出数据实际宽度?
int a=1254;
printf(“a=%3d”,a);
%ld也可以按指定宽度输出:
printf(“c=%8ld”,c);
输出结果:c =
65535
注意:格式字符的类型要与对应的输出对象
的类型一致。
c格式符:用于输出字符
char c=’A’;
printf(“c=%c,%c”,c,’B’);
输出结果:c=A,B
输出对象既可以是字符变量、字符常量,还
可以是整形变(常)量或整型表达式。
如:
int
a=100;
char
b=’A’;
printf(“\n%d,%c”,a,a);
printf(“\n%c,%d”,b,b);
输出结果:
100,d
A,65
注意超范围的整型数据用c格式
输出的截断误差(最低1字节)
printf(“%c”, 377);
377: 0000 001 0111 1001
‘y’:
0111 1001
s格式符:用于输出字符串
%s
不指定宽度
%-ms
指定宽度,左靠齐
%ms
指定宽度,右靠齐
%m.ns
指定宽度m,只取左端n个字符,
右靠齐
%-m.ns 指定宽度m,只取左端n个字符,
左靠齐
扩充内容
例:
printf(“1:%s”,”abcd”);
printf(“2:%8s”,”abcd”);
printf(“3:%-8s”,”abcd”);
printf(“4:%8.3s”,”abcd”);
printf(“5:%-8.3s”,”abcd”);
1:abcd2:
abcd3:abcd
4:
abc5:abc
f格式符:按小数形式输出实数
%f
由系统指定宽度(6位小数)
%m.nf
指定宽度m,小数位数n,右靠齐
%-m.nf 指定宽度m,小数位数n,左靠齐
注意:宽度包括符号和小数点。
例:
float a=3.141592654,b=14.326795,
c=-125.2468;
printf(“\na=%f,b=%8.3f,c=%-10.2f”,a,b,c);
输出结果:
a=3.141593,b=
14.327,c=-125.25
• e格式符:按标准化指数形式输出实数
%e 由 系 统 指 定 数 字 部 分 小 数宽 度 ( 6
位),指数部分占5列
%m.nf
指定宽度m,小数位数n,右靠齐
%-m.nf 指定宽度m,小数位数n,左靠齐
printf("%-12.2e,%12.2e",123.5489,123.5489);
输出结果:1.24e+002 , 1.24e+002
其他格式
•
•
•
•
•
1. i格式符:同d格式
2. o格式符:八进制整数
3. x格式符:十六进制整数
4. u格式符:无符号数据
5. g格式符:浮点数,系统自动选择f或
e格式
格式输出
%
附加字符
格式字符
l: 长整形整数,d,o,x,u
m: 正整数,数据的输出最小宽度
m.n
n:正整数,实数:n位小数,字符串
:截取的字符个数
-:输出数据向左靠
程序设计例:
编写程序计算如图中的电流I.
I=U/R1+U/R2+U/R3
U
R1
R2
假设 U=220,R1=30,R2=60,R3=45
R3
算法设计:
程序设计:
main()
{
I=U/R1+U/R2+U/R3
int U=220,R1=30,R2=60,R3=45;
float I;
I=U/R1+U/R2+U/R3;
printf(“\n I=%f”,I);
}
正确的程序:
main()
{
int U=220,R1=30,R2=60,R3=45;
float I;
I=(float)U/R1+(float)U/R2+(float)U/R3;
printf(“\n I=%f”,I);
}
考虑通用:
main()
{
int U,R1,R2,R3;
float I;
输入 U,R1,R2,R3
I=(float)U/R1+(float)U/R2+(float)U/R3;
printf(“\n I=%f”,I);
}
数据的输入
scanf 函数(格式输入)
与printf函数相反。
用于输入若干任意类型的数据。
scanf(“%d%d%d”,&a,&b,&c);
格式控制
地址列表
scanf(“%d%d%d”,&a,&b,&c);
执行此函数时,等待从键盘输入三个整
数给a,b,c
若从键盘输入 3 5 8
则系统即从键盘缓冲区取出这三个数分
别赋给a,b,c
注意与printf的区别,注意格式的匹配
如:
scanf(“%3d%2d%4d”,&a,&b,&c);
若从键盘输入123456789
a=123,b=45,c=6789
若想使a=12,b=5,c=100
则键盘输入应为: 12 5 100
方便的输入格式一般不 指定宽度,
如:
scanf(“%d%d%d”,&a,&b,&c);
在键盘输入时,用分隔符把每个数据隔开,
标准的分隔符是空格。
如:123 150 23
若想用逗号作分隔符,则:
scanf(“%d,%d,%d”,&a,&b,&c);
不要随便使用普通字符,如使用:
scanf(“a=%d,b=%d c=%d”,&a,&b,&c)
对应数据输入:
a=123,b=150 c=23
%c格式输入字符
scanf(“%c%c%c”,&a,&b,&c);
键盘输入:abc
键盘输入:a b c
输入数值数据遇到空格、回车、Tab键或非
数值字符 则该数据输入结束
scanf(“%d%c%f”,&a,&b,&c);
键盘输入:124a1.24o85
a=124,b=‘a’,c=1.24
格式说明
% 附加字符 格式字符
• l:长整形数据(%ld、%lx、%lo、%lu)
或double数据(%lf、%le)
• h:短整型数据( %hd、%hx、%ho )
• m: 正整数,输入数据的域宽
• *:不进行赋值操作
前面的欧姆定律:
main()
{
int U,R1,R2,R3;
float I;
scanf(“%d%d%d%d”,&U,&R1,&R2,&R3);
I=(float)U/R1+(float)U/R2+(float)U/R3;
printf(“\n I=%f”,I);
}
求三角形面积
#include “math.h”
main()
{ float a,b,c,area,s;
scanf ( “%f,%f,%f”, &a,&b,&c);
s=1.0/2*(a+b+c);
area=sqrt (s*(s-a)*(s-b)*(s-c));
printf(“\n area=%f”,area);
}
使用数学函数
使用三角函数
#include “math.h”
main()
{ float x, y;
scanf ( “%f”, &x);
y=sin(x*3.1415926/180);
printf(“\n y=%f”,y);
}
以弧度为单位
字符数据的输入
getchar函数(字符输入)
#include “stdio.h”
main()
{ char c;
c=getchar();
等待键盘输入
putchar(c);
}
总结
• 1、常量、变量 int a; #define PI
3.14159
• 2、数据类型 int, float, double,
char
• 3、C语句与表达式 int a=5;
• 4、数据输入输出 printf(), scanf();
作业 1,4,5 page82