Professional Documents
Culture Documents
C语言编程基础框架
framework
C语言编程基础框架
framework
学习要点
基本的数据类型(常量、变量;整型、浮点型、字符型、字符串型)
字符的ASCII编码、转义字符
变量的赋值、类型转换、访问限定
变量命名规则
格式化输入输出(scanf , printf)
算术运算符、算术表达式
赋值运算、复合赋值运算
关系运算(符)、逻辑运算(符)
一维数组简介
常量的符号表示(const与define)
标准库函数简介
BeihangSoft.cn
2.1 常量
常量:就是在程序中固定(不可以被程序改变)的数值。
整数 (integer) 数字常量
……
实数 (double, float) int main()
整数常量 {
字符 (character) int a = 1;
double pai = 3.14
字符串 (string): char ch = 'A';
……
本质是字符数组
printf("%d\n", a);
printf("%f\n", pai);
printf("%c\n", ch);
return 0;
}
3
BeihangSoft.cn
十进制与二进制、八进制、十六进制
整数(integer)
C语言中默认的表示方式是十进制: 0, 123, 45678, -234, -987, -0
也可以指定进制
十六进制:0xA2, 0xFF11(以数字零加字母x开头)
八进制: 012, 034(以数字零开头)
进制 十进制Dec 八进制Oct 十六进制Hex
基本数字 0~9 0~7 0 ~9, A~F (or a~f)
基数 10 8 16
规则 逢10进1 逢8进1 逢16进1
实例 19 023 0x13
Dec 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Oct 0 01 02 03 04 05 06 07 010 011 012 013 014 015 016 017 020 021 022
Hex 0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF 0x10 0x11 0x12
BeihangSoft.cn
实数(浮点数)
实数(浮点数)(单精度 float, 双精度 double)
一般的表示方法 科学计数法
-0.016 -1.6E-2 // 表示-1.6*10-2
.28 // 表示小数0.28 2.8E-1 // 表示0.28
1233.6 1.2336e3 // 表示1233.6
8000. // 表示小数8000.0 8e3 // 表示小数8000.0
实数与整数在计算机中的表示和保存方式不同,数
值表示的范围和精度也不相同,计算时的方法也不
……
int main()
相同。
{
没有小数部分的实数看上去跟整数相同(数值相同, int a = 1;
但实际上不同,如8e3为8000.0而不是8000)。 double PAI = 3.14;
默认(缺省)的实数类型是double,要表示float类 float pai = 3.14f;
型(比double表示的范围和精度小),在数据后面 char ch = 'A';
……
加后缀f或F,如:-1.6E-2f,.28F,1233.6f
BeihangSoft.cn
字符常量
字符常量:用一对单引号括起来字符称为字符常量,如:'A',
'b', '?', ...
一个字符常量的值是该字符在机器中的字符集,通常是ASCII字符集
(American Standard Code for Information Interchange)中的编码值(但
某些IBM大型机用EBCDIC码),是一个整数值,如:'A' 的值为65,
'b' 的值为98,'?' 的值为63
……
int main()
{
int a = 1;
char ch = 'A';
……
printf("%d\n", a);
printf("%c\n", ch);
return 0;
}
6
BeihangSoft.cn
字符常量
表示数字的字符与数字是不一样的,如 '0' int x = '0';
的ASCII编码是0x30,或十进制的 48,而 printf("%d\n", x);
不是数字0(两者差值为48) 如下四个输出结果相同
字符实际上是一个小整数(字符的ASCII int a = 'a';
编码,0~127) printf("%c\n", a);
数字字符 0~9(即'0' ~ '9'),字母a~z, a = 97;
A~Z之间的所有字符都是连续编码的 printf("%c\n", a);
字符常量可像其它整数一样参与数值运算, a = '\x61';
如: printf("%c\n", a);
'5' 的编码等于 '0'+5,即 0x35; 'a'+2 等
a = '\141';
于 'c' ; '8' - '0' 等于 8 printf("%c\n", a);
printf("%d\n", a);
// 上一条语句输出什么
7
BeihangSoft.cn
ASCII编码表(PPT看不清楚,看书!)
ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符
0 NUL 32 (space) 64 @ 96 、
1 33 ! 65 A 97 a
2 34 ” 66 B 98 b
3 35 # 67 C 99 c
4 36 $ 68 D 100 d
5 37 % 69 E 101 e
6 38 & 70 F 102 f
7 39 , 71 G 103 g
8 40 ( 72 H 104 h
9 41 ) 73 I 105 i
10 \n 42 * 74 J 106 j
11 43 + 75 K 107 k
12 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 46 . 78 N 110 n
15 47 / 79 O 111 o
16 48 0 80 P 112 p
17 49 1 81 Q 113 q
18 50 2 82 R 114 r
19 51 3 83 X 115 s
20 52 4 84 T 116 t
21 53 5 85 U 117 u
22 54 6 86 V 118 v
23 55 7 87 W 119 w
24 56 8 88 X 120 x
25 57 9 89 Y 121 y
26 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 60 < 92 / 124 |
29 61 = 93 ] 125 }
30 62 > 94 ^ 126 ~
31 63 ? 8 95 — 127 DEL
BeihangSoft.cn
转义字符
在C语言中,还有一类特殊的字符常量,称为转义字符
常量,如:'\0', '\n', '\t', ...
也可用Hex或Oct来表示字符,分别为 '\xhh' 和 '\ooo' 形
式,如 'a', '\x61', '\141' 都表示字符 a
转义字符及其含义
转义字符 含义 转义字符 含义
\n 换行 \t 水平制表
\v 垂直制表 \b 退格
\r 回车 \f 换页
<
\a 响铃 \\ 反斜线
\' 单引号 \" 双引号
\ddd 3位8进制数代表的字符 9 \xhh 2位16进制数代表的字符
BeihangSoft.cn
转义字符实例
【例c2-1.c】图形输出! 💡💡 编程提示
• ‘\117’代表字符‘O’,117是八进制
#include <stdio.h> 数,不能写前导0
int main( ) • ‘\x29’代表字符‘)’,x29是十六进制
{ 数,不能写前导0且x为小写
printf(" * * * * *\n"
• 转义字符中只能使用小写字母
" * *\n"
• 每个转义字符只能看作一个字符
" * OO \117\117 *\n"
"* *\n" • 表示单引号、反斜杠、双引号和
"* *\n" 反斜杠时,须使用转义字符表示。
"* ___ *\n"
" * (___\x29 >>>>>>>>>>>\"Hi All\"\n"
" * *\n"
" * * * * *\n");
return 0;
}
10
BeihangSoft.cn
字符串常量
字符串常量:用一对双引号括起来的字符串,如 "hello\n"
注意:所有字符串均以 '\0' 结束(编码值为 0 的字符,是
不可见的字符,即存在但看不见),因此, "x" 和 'x' 不
同,字符串末尾的 '\0' 由编译程序自动添加。
字符串中可以有转义字符,如:
printf("Welcome \n to \nBeijing!\n");
输出:
printf("\"This is \x61 string\"\n");
Welcome
输出:
to
"This is a string"
Beijing!
11
BeihangSoft.cn
2.2 变量
与常量相对应,常用的变量基本类型有:
数据类型 关键字
整数(integer) int、long …
字符(character) char
字符串(string) char型数组
12
BeihangSoft.cn
2.2 变量
【例c2-2.c】a+b回顾。
// file: c1-2.c 变量定义
int: 变量类型(整型,通常32
#include <stdio.h> 位)(还可以定义其他类型,
如 float, double, char…)
int a, b, sum: 定义了三个整型
int main()
变量,名字分别为 a, b, sum,
{ 称为变量名。
int a, b, sum; 变量名命名规则(后文介绍)
定义多个变量时,用逗号分开。
scanf("%d %d", &a, &b); 也可以分开定义,如
sum = a + b; int a;
printf("%d + %d = %d\n", a, b, sum); int b;
int sum;
return 0;
} 13
BeihangSoft.cn
变量命名规则
【例c2-2.c】a+b回顾。
// file: c1-2.c int a, b, sum: 定义了三个整型
变量,名字分别为 a, b, sum,
称为变量名。
#include <stdio.h>
变量名命名规则:变量的名字
必须是合法的标识(zhi, 4声)符
int main() (identifier)。一个标识符是
{ 由字母(或_)开头,由字母、
int a, b, sum; 数字和下划线组成的字符串。
系统保留的关键字不能作为标
scanf("%d %d", &a, &b); 识符,如main, int, return 等。
sum = a + b; 标识符在C语言中可作为变量
名、常量名、函数名、参数
printf("%d + %d = %d\n", a, b, sum); (parameter)名、类型名、枚举
(enumeration)名和标号(label)
return 0; 等。
} 14
BeihangSoft.cn
下面哪些是非法的标识符?
匈牙利命名法
之所以叫做匈牙利命名法时为了纪念匈牙利籍的Microsoft程序员
Charles Simonyi
在变量名前面加上相应的小写字母的符号标识作为前缀,标识出
变量的作用域、类型等。
int i_num;
char c_name;
double d_averScore;
16
BeihangSoft.cn
变量命名法
遵循一致的命名约定会对提高代码的可用性起到重大作用
使得许多开发人员使用同一框架成为可能
统一的命名规范,帮助你在阅读代码的时候快速跟踪代码逻辑
骆驼命名法和下划线法
混合使用大小写字母来构成变量和函数的名字。
近年来越来越流行了,在许多新的函数库和Microsoft Windows这样
的环境中,它使用得当相多。
下划线法是C出现后开始流行起来的,在许多旧的程序和UNIX这样的
环境中,它的使用非常普遍。
骆驼式 下划线
double stuScore; double stu_score;
printEmployeePaychecks(); print_employee_paychecks();
名字中的每一个逻辑断点都 名字中的每一个逻辑断点
有一个大写字母来标记 都有一个下划线来标记
17
BeihangSoft.cn
变量命名法
遵循一致的命名约定会对提高代码的可用性起到重大作用
使得许多开发人员使用同一框架成为可能
统一的命名规范,帮助你在阅读代码的时候快速跟踪代码逻辑
帕斯卡(pascal)命名法
帕斯卡命名法与骆驼命名法类似。只不过骆驼命名法是首字
母小写,而帕斯卡命名法是首字母大写。
不建议!
在C#中,以帕斯卡命名法和
骆驼命名法居多。 double stuScore;
💡💡 编程提示int stu_num;
变量命名时:
double StuScore; • 风格同一性
int StuNum; • 最小化长度&&最大化信息量原则
• 避免过于相似
• 避免在不同级别的作用域中重名
18
BeihangSoft.cn
C语言保留的关键字
关键字(keyword):已经被系统使用的标识符,具有预先定义好的
特殊意义,不能作为变量名、函数名及标号等使用。
int auto goto if
float static return else
char extern break while
short register continue for
long do
unsigned switch
double case
struct default
union
void define, undef, include, ifdef, ifndef, endif,
enum
typedef 及line,虽不是关键字,但是最好把它
sizeof 们看作关键字,它们主要用于C预处理
const 程序中。
volatile
signed
19
BeihangSoft.cn
基本的数据类型及其能表示的范围
数据类型 一般 32 位操作系统 16 位操作系统
(如 UNIX, W32) (如 DOS)
int 整型 32 16
short (int) 短整型 16 16
long (int) 长整型 32 32
unsigned (int) 无符号整型 32 16
float 单精度浮点型 32 32
double 双精度浮点型 64 64
char 字符型 8 8
1. 在C语言中,数据是有范围的;如对于32位int,其数值范围为
-2,147,483,648 ~ 2,147,483,647 ( -232-1 ~ 232-1-1 )
2. 在不同的系统平台,同一数据类型(如int)范围可能不同。
一般来说,不同的系统(如Windows, Linux),相同数据类型长度可能有差异。但
有个原则是:短整型(short)不能长于普通整型(int);长整型(long)不能短于普通整
型(int)。
3. 浮点数使用标准数据格式(IEEE-754),float的有效数字大约相当于十进制的7
位,表示范围约-3.4*1038 ~ 3.4*1038,能表示的绝对值最小数约为10-44.85;double能
表示的范围和精度更大。浮点数的表示是近似值,如显示的是1.0,计算机中实际
可能是0.99999999… ,也可能是1.0000001… 。
20
BeihangSoft.cn
c1-2.c :a+b回顾
【例c2-2.c】a+b回顾。
#include <stdio.h>
a = 55; 赋值时左右两边类型不一致?
b = a; // b = a = 55;
d = 123.456;
return 0;
}
变量的赋值和类型转换
#include <stdio.h>
#include <stdio.h> int main( )
int main( ) {
{ int a, b;
int a, b; double d;
double d;
a = 55;
a = 55; b = a; // b = a = 55;
b = a; // b = a = 55; d = 123.456;
d = 123.456;
a = d; 赋值时左右两边
printf("a = %d, b = %d\n", a, b); d = a; 类型不一致?
printf("d = %f\n", d);
output? printf("a = %d, b = %d\n", a, b);
return 0; printf("d = %f\n", d);
} a = 55, b = 55
d = 123.456000 output?
return 0;
} a = 123, b = 55
d = 123.000000
BeihangSoft.cn
变量的初始化
#include <stdio.h>
变量定义的时候即赋
int main( )
值,赋值的内容可以
{
是常量、变量(已经
int a, b;
赋值了)、表达式
double d; (有具体的返回值)
short s = 0;
int a1 = 55, b1 = a1; 当局部变量定义时没
int day_seconds = 24*60*60; 有赋值时,变量的值
是随机的
const double pi = 3.141592653589;
output:
printf("a = %d\na1 = %d\n", a, a1);
a = 4200656 这里a的值是
return 0;
a1 = 55 不可信的!
} 24
BeihangSoft.cn
*类型限定符const
#include <stdio.h>
const可以放在任何
int main( )
变量定义之前,说
{
明变量是只读的
short s = 0;
(不能修改的),
int a = 55, b = a;
这样的变量又称为
int day_seconds = 24*60*60;
常量变量(仍然是
变量,有变量的属
const double pi = 3.141592653589;
性,相当于常量,
但不是常量)。
......
pi = 0.618; // 代码中增加这样一行?
......
return 0;
} 25
BeihangSoft.cn
2.3 数据输入输出简介
数据的 I/O (Input/Output) 并不是C语言
的组成部分。 int a;
标准库函数提供相应的 I/O 操作,常用的 double x;
是两个函数: scanf( ), printf( ) scanf("%d", &a);
scanf("%lf", &x);
标准输入函数:scanf, 其函数原型为
int scanf(char *format, …); 【例 scanf("%d %d", &a, &b); 】
转换控制字符 输入形式 对应参数类型 输入实例 备注
%d 十进制整数形式 int +123
%x 十六进制整数形式 int 8C
%c 一个字符 char x
%s 一个字符串(以空格分隔) 字符数组或字符指针 hello123 yes yes不会被输入
%f 小数形式 float -1.23
%lf 小数形式 double -1.23
26
BeihangSoft.cn
数据输入输出
标准输入函数:scanf, 其函数原型为
int scanf(char *format, …); 【例 scanf("%d %d", &a, &b); 】
format格式控制串是一字符串,其 …
中的转换控制字符(以%开始)决 int x, y, z, i;
定了其他参数(输入数据)的个数
和输入格式。 i = scanf("%d %d,%d", &x, &y, &z);
其它字符要必须原样输入。scanf
会跳过输入数据中的空格符、制表 printf("%d\n", i); printf("%d\n", x);
符、换行符等空格符,从与该字段 printf("%d\n", y); printf("%d\n", z);
说明项匹配的数据起始点开始读入 …
数据并进行规定格式的转换。
I/O?
scanf( )函数返回成功赋值的数据项 5
数,读到文件末尾而没有数据时返 5 6,7 567 6,7
回 EOF ( -1 )。 3 2 3
5 5 5
6 6 6
7 4200704 7
27
BeihangSoft.cn
数据输入输出--评测机的输入原理说明
scanf( )函数返回成功赋值的数据项数,读到文件末尾而没有数据时返回
EOF ( -1 )。
}
return 0;
}
30
BeihangSoft.cn
类型转换与输出类型格式
scanf( )函数返回成功赋值的数据项数,读到文件末尾而没有数据时返回
EOF ( -1 )。
// c2-3aplusb-M.c
【例c2-3.c】a+b进阶。多次计算! #include <stdio.h>
多组数据输入
int main()
输入:多组数据,每组一行,分别为整 {
数 a 和 b(空格分开)。 int a, b;
int sum;
输出:对每行输入,输出为一个数,表 while(scanf("%d%d", &a,&b)!=EOF)
示该输入行的和。 {
sum = a + b;
输入样例: 思考 printf("%d\n",sum);
12 不改变a和b的类型,
34 还要扩展求和的范围, }
输出样例: 该怎么办? return 0;
3 }
7 31
BeihangSoft.cn
类型转换与输出类型格式
scanf( )函数返回成功赋值的数据项数,读到文件末尾而没有数据时返回
EOF ( -1 )。
#include <stdio.h>
【例c2-3.c】a+b进阶。多次计算!
int main()
多组数据输入
{
输入:多组数据,每组一行,分别为整数 a
和 b(空格分开)。
int a, b;
long long sum;
输出:对每行输入,输出为一个数,表示该 while(scanf("%d%d", &a,&b)!=EOF)
输入行的和。 {
sum = (long long) a + b;
输入样例: printf("%lld\n",sum);
12
1000000000 }
2000000000 return 0;
输出样例: }
3
3000000000
32
BeihangSoft.cn
数据输入输出
标准输出函数:printf, 其函数原型为
int printf(char *format, …); 【例 printf("%d\n%d\n", a, b); 】
转换控制字符 输出形式 对应参数类型 输入实例 备注
%d 有符号的十进制整数形式 int 123
%x 十六进制整数形式 int 8C
%c 一个字符 char, int x
%s 一个字符串(以空格分隔) 字 符 数 组 或 字 hello123 yes "…"中的…被输出
符指针
%f 小数形式 double -1.23 没有特定的float输出
%e 小数形式(科学计数表示) double -1.23e-3 0.00123
在控制字符前还可以加数字,如:
%-4d :输出最小域宽为4个字符的整数,左对齐(右边如有富裕补空格)。
%6.2f :输出最小域宽为6个字符的浮点数,并且小数点占两位。
BeihangSoft.cn
数据输入输出实例
输出域宽和
屏幕输出?
实际输出长度
double y = 3.14159265;
printf("%6.2f", y);
3.14
域宽为六个字符,输出数据若小于输
出域宽,则右对齐输出,其它部分填
空格;若输出数据长度多于给定域宽
,则按实际数据输出。
34
BeihangSoft.cn
数据输入输出常见问题
如何同时输出多个数据?
int x=2;
int y=3; 输出结果: 2 + 3 = 5
printf("%d + %d = %d\n", x, y, x+y);
如何同时输入多个数据? 输入多个数据时,
用空格 或回车换行
分隔,但在格式字
int n; 符串中不用给出空
格或回车换行符。
float r;
scanf("%d%f ", &n, &r );
5
5 6.6 6.6
35
BeihangSoft.cn
数据输入输出常见问题 必须原样
输入非转换
字符
float r;
输入例子:
scanf("r=%f", &r ); r=3.14
(必须原样输入r=,然后3.14,
数字将被读入到变量 r中)
double r;
💡💡 编程提示
scanf("%f", &r ); • 输入分隔符包含其它字
符时,应给出足够提示
scanf("%lf", &r ); 以确保正确输入。
• 熟记常用数据类型的格
式字符。
36
BeihangSoft.cn
数据输入输出常见问题
【例c2-2.c】a+b回顾。
输入格式控制串中含有空白
#include <stdio.h> 字符(如空格、\n或\t)
int main()
{ 回车换行后无法
int a, b; 读入数据!!!
int sum; 最后不要有 \n !
(先记住就好了)
scanf("%d%d\n", &a, &b);
//scanf("%d%d", &a, &b);
sum = a + b; 💡💡 编程提示
printf("%d \n", sum);
• scanf中不使用\n。
return 0;
}
37
BeihangSoft.cn
数据输入输出小结
标准输入函数:scanf, 其函数原型为
int scanf(char *format, …); 【例 scanf("%d %d", &a, &b); 】
标准输出函数:printf, 其函数原型为
int printf(char *format, …); 【例 printf("%d\n%d\n", a, b); 】
scanf( )和printf( ) 都有返回值,但printf返回值通常舍弃不用。
一个有用的输入返回值利用情况:while ( scanf(…) == ?) {…}
…
int x, y, z, i; I/O?
5 6,7 567
i = scanf("%d %d,%d", &x, &y, &z); 3 2
5 5
printf("%d\n", i); printf("%d\n", x); 6 6
printf("%d\n", y); printf("%d\n", z); 7 4200704
…
38
BeihangSoft.cn
2.4 算术表达式与算术运算符
算术表达式(arithmetic expression):由操作符和操作数构成
的具有计算结果的表达式
操作数 (operand): 数字常量 或 变量
算术表达式的结果是有数据类型的,由其操作数的类型决定。
如果操作数类型不同,则需要类型转换。例如:
1.0 + 1 (1自动转变为1.0,结果为2.0,double型)
2 / 3 (2和3均为int型,结果也为int型,值为0)
2.0f / 3 (3自动转变为3.0f,结果为0.666667f,float型)
2 / 3 * 1.0 = ?
39
BeihangSoft.cn
2.4 算术表达式与算术运算符
【例c2-4.c】求圆的面积和周长。 常见算术运算符
// to calculate the circle's area and perimeter C操作 算术运算符 代数表达式 C表达式
#include <stdio.h> 加 + b+8 b+8
const double PI = 3.141592653589; 减 - f-h f-h
int main() 乘 * ab a*b
{ 除 / a/b 或 a÷b a/b
double radius, area, perimeter; 求模 % r mod s r%s
scanf("%lf", &radius);
return 0;
} 41
BeihangSoft.cn
算术运算实例:求某天是星期几
【例c2-5.c】已知某月x日是星期y,该月有n天,求下一个月的
k日是星期几?
// file: c2-5-1_weekday.c
#include <stdio.h> 题目分析:
int main()
{ 用0~6表示周日至周六,则下一
short x, y, n, k, m;
个月的k日是星期几m可表示为
/* we choose 2019/3/5, Tuesday*/
x = 5; y = 2; n = 31; m = (n -x +k +y)%7
printf("day of next month: ");
scanf("%d", &k);
m = (n -x +k +y)%7;
return 0;
} 42
BeihangSoft.cn
算术运算实例:一元二次方程求根
【例c2-6.c】已知一元二次方程 ax2 + bx +c = 0 的系数a, b, c,
求方程的根?
题目分析:根据求根公式 //// file: c2-6_solve_equation.c
#include <stdio.h>
#include <math.h>
int main()
math.h :标准头文件,其中定义了 {
若干(数学)标准库函数。 double a = 1, b = 6, c = 5, r1, r2;
43
BeihangSoft.cn
算术表达式与算术运算符 --自增和自减运算符
C提供自增++(变量递增1)运算,用于取代赋值运算,如 a = a + 1 (或 a += 1)
同样也提供自减--(变量递减1)运算
自增++和自减--运算符可放在变量的前面也可放在变量后面
运算符 名称 示例表达式 说明
++ 前置自增 ++a 将a加1,然后在a出现的表达式中使用新值
++ 后置自增 a++ 在a出现的表达式中使用当前值,然后将a加1
-- 前置自减 --a 将a减1,然后在a出现的表达式中使用新值
-- 后置自减 a-- 在a出现的表达式中使用当前值,然后将a减1
int main() 注意:在单独一条语句中,前置自
{ 增(减)与后置自增(减)是相同
自增和自减运算 int i = 1, j = 2 的,但在表达式中两者有差别。如
通常在循环语句 int m = 5 , n = 6; a++; ++a; a = a + 1;
中控制条件变量 int u, v, x, y;
的改变。 u = i++; // u is ?, i is ? c = a++; c = ++a;
v = ++j; // v is ?, j is ?
while(i <= n){ c = a; a = a + 1;
x = m--; // x is ?, m is ?
…… a = a + 1; c = a;
y = --n; // y is ?, n is ?
i++;
...
} } 44
BeihangSoft.cn
复合赋值运算符
对一个变量的值在其原有值基础上修改时,赋值运算符可以缩写成赋
值表达式,如
a += 5 等价于 a = a + 5 , x *= y + 5 等价于 x = x * (y + 5)
其它二元运算符均可写成类似的形式,即
(v) = (v) op (expression) 可写为 (v) op= (expression)
赋值运算符 示例表达式 说明 赋值 使用赋值运算符可
假设:int c = 3, d = 5, e = 4, f = 6, g = 12; 以使程序员更快地
+= c += 7 c=c+7 10赋值给c 编写程序(精炼程
-= d -= 4 d=d-4 1 赋值给d 序),也可以使编
*= e *= 5 e=e*5 20赋值给e 译器更快地编译程
/= f /=3 f=f/3 2 赋值给f 序(提高编译效
%= g %=9 g=g%9 3赋值给g 率)。
自增和自减运算符
运算符 名称 示例表达式 说明
++ 前置自增 ++a 将a加1,然后在a出现的表达式中使用新值
++ 后置自增 a++ 在a出现的表达式中使用当前值,然后将a加1
-- 前置自减 --a 将a减1,然后在a出现的表达式中使用新值
-- 后置自减 a-- 在a出现的表达式中使用当前值,然后将a减1
46
BeihangSoft.cn
2.5 类型转换
… 各个输出分别是什么?
char c = '1'; // '1' is 49, or 0x31
int a = 1, b = 8; double d = 1;
C语言类型转换通常是自动的---
unsigned u;
a = c;
隐式(自动)类型转换
printf("%d\n", a); 1. 字符与整数:可以用整数的地
a = 60 + 4*50 - 3/2.0; 方就可以用字符。整数转换成
printf("%d\n", a); 字符时,超出8位就将高位丢掉。
d = (3+2)*(7-2)/4; 2. 浮点数与整数
printf("%f\n", d); 输出
c = a;
printf("%d\n", c);
3. 无符号整数:普通整数(int)
d = (double) (b/5);
和无符号整数(unsigned)混
printf("%f\n", d);
d = (double) (b)/5; 合使用,则普通整数转换成无
printf("%f\n", d); 符号整数。
…
47
BeihangSoft.cn
类型转换(续)
… C语言类型转换通常是自动的--- 隐
char c = '1'; // '1' is 49, or 0x31 式(自动)类型转换
int a = 1, b = 8; double d = 1;
4. 算术转换:如果一个运算符,有不
a = c;
同类型的运算对象,那么“较低”
printf("%d\n", a); 类型会自动转换成“较高”类型。
a = 60 + 4*50 - 3/2.0; 输出
printf("%d\n", a);
d = (3+2)*(7-2)/4;
printf("%f\n", d);
c = a;
printf("%d\n", c);
d = (double) (b/5);
printf("%f\n", d);
d = (double) (b)/5; 5. 赋值号右边表达式的类型会自动转
printf("%f\n", d); 换为赋值号左边变量类型。
…
48
BeihangSoft.cn
基本类型数据的“高低”层次关系
Data types
long double
double
float
unsigned long int (synonymous with unsigned long)
long int (synonymous with long)
unsigned int (synonymous with unsigned)
int
unsigned short int (synonymous with unsigned short)
short int (synonymous with short)
unsigned char
char
当发生由“较高精度类型数据” 转换到“较低精度类型
数据” 时,大多数编译器会产生一个警告,因为发生了
可能的精度损失
49
BeihangSoft.cn
类型转换:强制类型转换
… 强制类型转换(cast)
char c = '1'; // '1' is 49, or 0x31 --- 显式类型转换
int a = 1, b = 8; double d = 1;
#include <stdio.h>
a = c; const double DELTA=1e-9;
printf("%d\n", a); int main( )
a = 60 + 4*50 - 3/2.0; { int x,y;
printf("%d\n", a); double f=0.0006;
d = (3+2)*(7-2)/4;
printf("%f\n", d); x=(int)(f*10000);
c = a; 输出 printf("%d\n", x);
输出?
5
printf("%d\n", c);
y=(int)((f+DELTA)*10000);
printf("%d\n", y);
6
d = (double) (b/5);
printf("%f\n", d); return 0;
d = (double) (b)/5;
printf("%f\n", d);
} ?
…
50
BeihangSoft.cn
类型转换(续)
强制类型转换常用来进行浮点数的整数和小数分离
…
int int_part;
double x = 2018.321, decimal_part;
int_part = (int) x; // 获取x的整数部分
decimal_part = x – (int) x; // 获取x的小数部分
…
强制类型转换可抑制编译系统在精度损失时发出告
警信息(我就是要这样做,请不要提醒我!)。
【 *例2-7】时钟指针
讨论题
51
BeihangSoft.cn
类型转换的注意事项
混合类型表达式中的升 …
char c = '1'; // '1' is 49, or 0x31
级规则 int a = 1, b = 8; double d = 1;
混合类型表达式中的每 a = c;
个值的类型会升级为此 printf("%d\n", a);
a = c + 4*50 - 3/2.0;
表达式中的“最高”类 printf("%d\n", a);
型(实际上创建了此表 d = (3+2)*(7-2)/4;
printf("%f\n", d);
达式中每个值的临时值 c = a;
并用于表达式中,原来 printf("%d\n", c);
&& A || A
T F T F
A T F
T T F T T T
B B
F F F F T F !A F T
电路的串并联? 开关切换?
54
BeihangSoft.cn
关系运算符与逻辑运算符
A && B 若A为0(假),则B不必求值,结果一定为0(假)。
A || B 若A为非0(真),则B不必求值,结果一定为非0(真)。
如上逻辑表达式的这一重要性质也称为“短路求值”,在程序设计中经常会用到。
如在输入数据进行处理时,经常用如下的表达式:
char c;
if( ( ( c = getchar( ) ) != EOF) && (c >= 'a') && (c <= 'z') ) {…}
55
BeihangSoft.cn
逻辑表达式实例
判断整型变量n的值为一个0到10之间的值:
(0 <= n && n <= 10) 注意:不能写为 (0 <= n <= 10)
不能得到预期结果
(该表达式是一个合法的逻辑表达式,测
试一下其值为多少?)
int n = 2; printf("%d", 0 <= n <= 10);
判断字符变量c是字母:
((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
判断某年是平年还是闰年(闰年为能被4整除但不能
被100整除,或能被400整除):
(( y%4 == 0) && (y%100 != 0 )) || (y%400 == 0)
56
BeihangSoft.cn
实际应用中逻辑表达式
【例c2-8.c】输入一个三位整数x,判断x是否为水仙花数,如果是,则输出该
数是水仙花数。(水仙花数:一个三位数,其各位数字的立方之和等于该数,
如153是水仙花数,因为 153 = 13 + 53 +33)。
// c3-2_daffodil_number.c
#include <stdio.h>
int main()
{ 第一次运行程序,IO为:
short x, a, b, c;
Input a three-bits-integer: 123
printf("Input a three-bits-integer: "); 123 is not a daffodil number
scanf("%d", &x);
59
BeihangSoft.cn
实际应用中逻辑表达式
自然语言描述的条件转换为逻辑表达式通常不唯一,如:
a不大于b: (a <= b) , 也可以为 !(a >b)
a不等于b: (a != b) , 也可以为 !(a == b)
x不大于a且不大于不b:
x <= a && x <= b
也可以为 !(x > a) && !(x > b)
还可以为 !( (x > a) || (x > b) )
(德.摩根定理,亦称反演律)
60
BeihangSoft.cn
*2.7 运算符的优先级
一些基本的优先级规则:
先乘除(模),后加减
关系运算优于逻辑运算
括号优先
……
x = a - b * c;
61
BeihangSoft.cn
*2.7 运算符的优先级(有些还没有学过)
优先级 运算符 名称或含义 使用形式 结合方向 说明
后置++ 后置自增运算符 变量名++
后置-- 后置自减运算符 变量名--
[] 数组下标 数组名[整型表达式]
1 () 圆括号 (表达式)/函数名(形参表) 左到右
. 成员选择(对象) 对象.成员名
-> 成员选择(指针) 对象指针->成员名
- 负号运算符 -表达式 单目运算符
(类型) 强制类型转换 (数据类型)表达式
前置++ 前置自增运算符 ++变量名 单目运算符
前置-- 前置自减运算符 --变量名 单目运算符
/ 除 表达式/表达式 双目运算符
63
BeihangSoft.cn
*运算符的优先级(有些还没有学过)
优先级 运算符 名称或含义 使用形式 结合方向 说明
= 赋值运算符 变量=表达式
/= 除后赋值 变量/=表达式
*= 乘后赋值 变量*=表达式
%= 取模后赋值 变量%=表达式
+= 加后赋值 变量+=表达式
14 -= 减后赋值 变量-=表达式 右到左
<<= 左移后赋值 变量<<=表达式
>>= 右移后赋值 变量>>=表达式
&= 按位与后赋值 变量&=表达式
^= 按位异或后赋值 变量^=表达式
|= 按位或后赋值 变量|=表达式
15 , 逗号运算符 表达式,表达式,… 左到右 从左向右顺序运算
这么多!怎么记忆?
1. 读一遍,能记住多少就记多少。
2. 使用的时候,按常识和感觉,相信自己的直觉。
3. 加括号。
4. 不理它,天天坚持编程(模仿书上的例程),很快,不知为何,就都会了。
64
BeihangSoft.cn
*运算符的优先级(有些还没有学过)
优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最
低的优先级
相同优先级中,按结合顺序计算。大多数运算是从左至右计算,只有三个
优先级是从右至左结合的,它们是单目运算符、条件运算符、赋值运算符
基本的优先级需要记住:
指针最优。单目运算优于双目运算,如正负号。
先乘除(模),后加减。
逻辑运算最后计算。
很多优先级是比较显然的。记住一些常用运算的优先级。记不住怎么办?
提示:善用小括号 ( )
char c;
if( ( ( c = getchar( ) ) != EOF) && (c >= 'a') && (c <= 'z') ) {…}
65
2.8 一维数组简介
int i=0, a[12];
while(i<12)
int a[12]; {
表示定义一个包含12 个整数值的数组,名字为a。 a[i] = (i+1)*(i+1);
i++;
数组名的命名规则与其他变量名相同。
}
数组元素的标号从 0 开始(注意:不是 1)。
数组中第一个元素称为数组元素0 (zeroth element),这样,数组a中
的元素:
第1个元素为a[0];第2个元素为a[1]; …… ;第 i 个元素为a[i-1]。
要引用数组中的特定位置或元素,就要指定数组中的特定位置或元素
的位置号(position number)。
方括号中位置号称为下标(subscript),下标应为整数或整型表达式。
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10] a[11]
BeihangSoft.cn
一维数组初始化与数组访问
每一个数组元素的赋值和访问与单个变量一样
数组赋值的一些方法
注意:不要将循环条件写为i<=6。这是
int a[6] = {1, 3, 5, -2, -4, 6};
初学者常犯的错误。
int b[6] = {1, 3};
int e[6]; int i=0, a[6];
程序执行中进行赋值和访问
while(i<6){
每一个数组元素的访问与单个变量一样
a[i] = (i+1)*(i+1);
可以跟变量一样,定义不同类型的数组 i++;
int a[10]; }
double b[12]; i=0;
char c[128]; while(i<6)
…… { printf("%d\n", a[i]); i++; }
67
BeihangSoft.cn
应用实例:成绩平均分( 与c1-8.c进行对比分析)
【例c2-11.c】输入多人(少于200人)成绩(有效成绩0~100,输入-1结束),
求平均分(保留小数点后两位)并输出大于平均分的成绩。
#include <stdio.h> 输入:
int main() 76
if(n > 0) {
{ 82
ave = (float)sum/n;
int sum = 0, score[200]; 61
printf("%d/%d = %.2f\n",
float ave; 92
sum, n, ave);
int n = 0, i = 0 ; 50
while(i<n) {
-1
if((float)score[i]>ave)
scanf("%d", &score[0]); 输出:
printf("%d : %d\n",
361/5 = 72.20
i+1, score[i]); 1 : 76
while(score[n] != -1) {
i++; 2 : 82
sum += score[n];
} 4 : 92
n++;
}
scanf("%d", &score[n]);
return 0;
}
}
68
BeihangSoft.cn
应用实例:温度转换
【例c2-12.c】求摄氏温度℃转换为华氏温度℉(F = C*9/5 + 32)
数组的下标i和数组元素值CtoF[i]构成
#include <stdio.h> 了一个2列102行的表格(含表头)。 输出结果:
#define N 101 i是摄氏温度, CtoF[i]是华氏温度。 0 C = 32 F
1 C = 33 F
int main() i (℃) CtoF[i] (℉)
2 C = 35 F
{ 0 32 3 C = 37 F
int i=0, CtoF[N];
1 33 4 C = 39 F
… … 5 C = 41 F
while( i<N ) { 6 C = 42 F
CtoF[i] = i*9/5 + 32; 7 C = 44 F
printf("%3d C = %3d F\n", i, CtoF[i]); 8 C = 46 F
i++; 9 C = 48 F
10 C = 50 F
}
11 C = 51 F
return 0;
…
}
69
BeihangSoft.cn
2.9 常量的符号表示方法
宏定义、const限定符【*】、枚举常量(后面再学)
#define是编译预处理中的宏定义,定义一个符号和它所代表的字符串,编
译时这一符号被替换为该字符串。(EOF 就是 stdio.h 中定义的常量)
#include <stdio.h>
#define PI 3.14159
#define SEC_HOUR (60*60)
#define SEC_DAY (SEC_HOUR*24)
#define SUCCEED "test, Succeed!\n"
int main()
{
int sec_oneweek = 7*SEC_DAY;
printf("Oneweek has %d seconds.\n\n", sec_oneweek);
使用常量定义的好处:
double radius=1, area, perimeter;
area = PI * radius * radius;
可提高程序的可
perimeter = 2 * radius * PI;
printf("Radius = %-6.2f, Area = %-6.2f, Perimeter = %-6.2f\n\n", radius, area, perimeter); 读性
radius=2;
area = dPI * radius * radius;
程序的可移植性
perimeter = 2 * radius * dPI;
printf("Radius = %-12.6f, Area = %-12.6f, Perimeter = %-12.6f\n\n", radius, area, perimeter); 更好
printf(SUCCEED);
return 0;
可维护性更好
}
70
BeihangSoft.cn
【**】const与#define
… #define:宏定义,C的一种编译预处理指
#define arraySize 10 令。
// const int arraySize = 10; 在C语言源程序中允许用一个标识符来表
… 示一个字符串,称为“宏”。被定义为
int main() “宏”的标识符称为“宏名”。在编译
{ 预处理时,对程序中所有出现的“宏
int i=0, j=0, s[arraySize]; 名”,都用宏定义中的字符串去代换,
这称为“宏代换”或“宏展开”。宏定
whiel(i<arraySize)
义是由源程序中的宏定义命令完成的。
{ …… }
宏代换是由预处理程序自动完成的。
whiel(i<arraySize) 宏定义是纯粹的文字替换,不进行类型
{ …… } 检查。( 常见错误,#define PI 3.14; )
带参数的宏,如
return 0;
} #define max(a, b) ((a) > (b) ? (a) : (b))
71
BeihangSoft.cn
【**】const与#define
… const 定义的常数是变量,也带类型,存在
#define arraySize 10 于程序的数据段,并在堆栈中分配了空间。
// const int arraySize = 10; const常量是一个Run-Time的概念,它在程
序中确确实实地存在着,并可以被利用、
…
传递。const常量有数据类型。编译器可以
int main()
{ 对const常量进行类型的安全检查。
int i=0, j=0, s[arraySize]; #define 定义只是用来做文本的替换,当程
序进行编译的时候,编译器首先会将
whiel(i<arraySize) #define PI 3.14 以后所有代码中的 PI 全部
{ …… } 换成3.14,然后再进行编译,是在编译期预
处理阶段做的单纯文本替换
whiel(i<arraySize)
网上查询,进一步学习 const与#define
{ …… }
return 0;
}
72
BeihangSoft.cn
2.10 标准库函数简介
标准输入/输出(Input/Output, I/O)
# include <stdio.h>
int main( ) 标准输入(stdin, standard input)
{ 通常指键盘
int a, b, sum; 标准输出(stdout, standard output)
通常指屏幕显示器
scanf("%d%d", &a, &b);
在Windows等图形界面的操作系
sum = a+b; 统中,在控制台(console)编程
模式下,输入、输出信息一般
printf("sum = %d\n", sum); 被显示在一个窗口中,该窗口
称为控制台窗口。
return 0;
}
73
BeihangSoft.cn
标准库函数简介
#include <stdio.h>
C语言的编译系统以标准库函 #include <math.h>
数的方式实现了大量常用的功 int main()
能。 {
标准函数的函数原型在相应的 double a=3, b=4, c;
标准库头文件( *.h)中说明;
函数的定义以目标码的形式保 c = sqrt(a+b);
存在函数库中(用户使用时, printf("%.2f\n", c);
用#include 引用相应的.h文件, return 0;
编译时以编译选项的方式指明 }
需要链接的库函数)。
💡💡 编程提示
多多使用标准库函数。不必
“事无巨细”、“事必躬亲”。
74
BeihangSoft.cn
**标准库函数: I/O (include <stdio.h>)
常用的I/O函数(主要文本的 I/O)(参阅Page94-95,表5-2 ~ 5-4)
函数原型 功能说明 备注
int getchar() 返回从标准输入文件中读入的一个字符 读到文件尾时返回EOF
#include <stdio.h>
#include <math.h>
int main()
{
int x;
for( x = 1; x<=32; x++ ) // 还没有学for,先不理它!
printf("2^%d = %.0f\n", x, pow(2, x));
return 0;
}
77
BeihangSoft.cn
**标准库函数: 其他常用函数
void qsort(void
void *bsearch(void
以二分查找的方式在排 *base,size_t
*key,void *base,size_t 以快速排序方式对
序数组base中查找元素 num,size_t width,int
num,size_t width,int 数组base进行排序
key (*f)(void *e1, void
(*f)(void *e1, void *e2));
*e2));
78
BeihangSoft.cn
**标准库函数: 字符判断 (include <ctype.h>)
字符类型判断函数(参阅P97,表5-5 ~ 5-6 ,并试着编写一些试用程序)
函数原型 函数功能 函数原型 函数功能
c是否是可打印字符
int isalnum(int c) c是否是字母或数字 int isprint(int c)
(0x20~0x7e)
c是否是符号,可打印但
int isalpha(int c) c是否是字母(a~z,A~Z) int ispunct(int c)
非字母数字
c是否是控制符 c是否是空白符
int iscntrl(int c) int isspace(int c)
(0x00~0xlf,0x7f) (0x09~0x0D,0x20)
int isdigital(int c) c是否是数字 int isupper(int c) c是否是大写字母(A~Z)
c是否是可打印字符(空格 c是否是16进制数字
int isgraph(int c) int isxdigit(int c)
除外) (0~9,a~f,A~F)
int islower(int c) c是否是小写字母(a~z)
isdigit() 0~9
isxdigit()
A~F,a~f
isgraph() isalpha()
isupper() A~Z
isprint() isalnum() islowwe() a~z
isdigit() 0~9
ispunct() !@#$%^&*()_-+=|\{}:;"'<>?/~`
空格符(' ',0x20)
isspace() 空格符(0x20),换页符('\f'),换行符('\n'),回车符('\r'),水平制表符('\t'),垂直制表符('\v')
iscntrl() 控制字符(0x00~0x1f,0x7f)
79
BeihangSoft.cn
**标准库函数: 字符串处理 (include <string.h>)
字符串处理跟数组密切相关。
80
BeihangSoft.cn
*C89的标准库头文件
setjmp.h 非局部跳转
81
BeihangSoft.cn
*标准库函数小结
复用:C标准库提供了丰富的函数集合,程序员直接调用这些函数可以
完成许多操作,而不必事事从原始的代码开始编起(继承前人的优秀成
果,减少软件开发工作量)。
封装:不关心别人的程序(函数)的实现细节,了解接口即可。
数学计算( #include <math.h> ) : pow(a,b), sin(x), sqrt(x), ..
标准I/O ( #include <stdio.h> ) : scanf, printf, putchar, …
字符串操作、系统资源访问、时间处理、错误检查、…
Computer 工欲善其事,
Company 必先利其器
常用标准库函数及头文
件参见附录E。或联机
手册。
82
BeihangSoft.cn
本讲小结
了解C语言的基本数据类型,取值范围
理解ASCII编码规则和使用方法
熟练掌握变量的应用:变量的定义(命名规则并区分关键字) 、赋值、
使用
熟练掌握+、-、*、/、%、++、--等的使用方法和计算表达式的值
熟练掌握赋值运算、复合赋值运算
熟练掌握关系运算、逻辑运算
熟练掌握类型转换的规则及使用方法
熟练掌握scanf、printf函数的功能与使用方法
了解常量的符号表示形式、const与define的区别
简单掌握一维数组的使用方法
简单掌握库函数的使用方法
83
BeihangSoft.cn
第二讲 作业
看书
习题:all
预习后面章节
上机实践题
把本课件和书上的所有例程输入计算机,运行并观察、分
析与体会输出结果。
编程练习课后习题内容。
84
BeihangSoft.cn
课堂作业
【例c2-quiz1.c】对右侧程 #include <stdio.h>
序,以下输入的输出什么?
int main()
{
思考
int x, y, z, i;
输入1:4 5 6
i = scanf("%d %d,%d",&x, &y, &z);
输入2:4 5,6
printf("%d\n", i);
输入3:4.2 5.7,8.2
printf("%d\n", x);
输入4:5 a,6
printf("%d\n", y);
printf("%d\n", z);
return 0;
}
85
BeihangSoft.cn
课堂作业
【例c2-quiz2.c】 #include <stdio.h>
#include <math.h>
对右侧程序,会 #define PI 3.1415926
输出什么? int main()
{
int x = 4;
double angle = 45;
printf("\"Hell\x6f\"\12");
return 0;
} 86
课堂作业 #include <stdio.h>
int main() {
char c = '1'; /* '1' is 49, or 0x31*/
int a = 1, b = 8;
【例c2-quiz3.c】对右侧 double d = 1;
程序,会输出什么? a = c;
printf("%d\n", a);
a = 60 + 4*50 - 3/2.0;
printf("%d\n", a);
d = (3+2)*(7-2)/4;
printf("%f\n", d);
c = a;
printf("%d\n", c);
d = (double) (b/5);
printf("%f\n", d);
d = (double) (b)/5;
printf("%f\n", d);
return 0;
}
87
BeihangSoft.cn
本讲再补充:优秀程序员的编程习惯
// to calculate the circle's area and perimeter
优秀程序员应具备的一些素质
#include <stdio.h>
const double PI = 3.141592653589; 使用TAB (table) 键缩进或空格
int main()
{ { } 对齐
double radius, area, perimeter;
有合适的空行和空格
scanf("%lf", &radius);
89
BeihangSoft.cn
本讲再补充:优秀程序员的编程习惯
// to calculate the circle's area and perimeter
优秀程序员应具备的一些素质
#include <stdio.h>
const double PI = 3.141592653589; 有足够的注释
int main()
{
double radius, area, perimeter;
💡💡 编程提示
scanf("%lf", &radius);