1.1 C
语言的生命力
1.1.1 C
语言的发展历程和趋势
1.1.1 C
语言的发展历程和趋势
C
语言是在 BCPL ( Basic Combined Progra
mming Language
)语言基础上发展而来的, B
CPL
语言的原型是 ALGOL60 语言(也称 A 语
言)。 ALGOL 60 是计算机发展史上首批高级语
言,更适用于数值计算。
1978
年, Brian W. Kernighan 和 Dennis. M. R
itchie
联合撰写影响深远的名著《 The C Progra
mming Language
》,成为第一个事实上的 C
1.1.2 C
语言的特点
C
语言与其他编程语言相比,有着自己独特的特
点:
( 1 )语言简洁、灵活方便
( 2 )表达能力强
( 3 )高效率的编译性语言
( 4 )可移植性好
( 5 )运算符和数据类型丰富
( 6 )语法限制少,设计自由度大
( 7 )允许直接访问物理地址
1.2 C
语言程序示例
1.2.1 C
语言程序示例
1.2.1 C
语言程序示例
例 1.1 在屏幕上输出如下信息“ This is the first p
rogram.”
。
程序清单如下:(文件名 1_1.c )
#include <stdio.h>
/*
编译预处理指令 */
int main()
//
定义主函数, C 程序的开始
{ /*
函数的开始标志 */
printf(“This is the first program.\n”); /*
输出
指定信息 */
return 0; /*
函数正常结束返回值为 0*/
1.2.1 C
语言程序示例
下面分析这个最简单的 C 语言程序的结构
:
1
.文件包含预处理指令
2
. main() 函数
3
.大括号与函数体
4
.输出函数
5
.注释
1.2.1 C
语言程序示例
例 1.2 求两个整数的和。
#include <stdio.h> // 编译预处理指令
int main() // 定义主函数, C 程序的开始
{ // 函数的开始标志
int a, b, sum; // 声明 a, b, sum 均为整型变量
a = 222; // 将整数 222 放在变量 a 中存储
b = 333; // 将整数 333 放在变量 b 中存储
sum = a + b; // 将整数 a 和 b 的和放在变量 sum 中存储
printf(“sum is %d\n”,sum); // 输出 sum 的值
return 0; // 函数正常结束返回值为 0
1.2.1 C
语言程序示例
例 1.3 求两个整数的和。
#include <stdio.h>
int add(int x, int y) // 定义函数 add , add 为函数名, x , y 为形式参数
{
return (x + y); //将 x + y 的和返回,通过 add 带回到调用函数的位置
}
int main()
{
int a, b, sum; // 定义变量 a , b 和 sum
printf(“Please input two number(like:3,5): \n”);// 使用 printf() 函数打印输入提示
scanf("%d,%d", &a, &b); // 使用 scanf() 函数对变量 a , b 赋值
sum = add(a, b); // 调用函数 add ,并将函数返回值赋值给 sum
printf("%d + %d = %d\n", a, b, sum); // 使用 printf() 函数输出结果
return 0;
1.2.2
运行 C 程序的方法
1
.进入 VC++ 6.0 集成环境
2
.新建源文件
3
.编译源程序
4
.连接目标程序
5
.执行程序
6
.退出 VC++ 6.0 集成环境
1.3
小结
本章概述了 C 语言的发展历程、 C 语言的发展趋
势和 C 语言的特点,并通过具体的示例程序对 C
程序中的文件包含预处理指令、 main( ) 函数、 C
语言的注释、变量的定义、输入输出函数的使用
、函数的定义与调用、赋值运算符的使用以及怎
样使用 VC++ 6.0 集成环境来运行一个 C 程序。
学习这一章,需要把注意力放在怎样编写第一个
程序这方面,通过本章的学习期望能够仿照例 1.1
编写一些简单的程序,并能够对里面的每个知识
点的使用方法熟练掌握。
第 2 章 C 语言基础
2.1
计算机中数据的表示
2.1.1
位、字节和字
2.1.1
位、字节和字
术语“位、字节和字”用于描述计算机数据单位或计算机
存储单位。这里主要指存储单位。
位( bit )是最小的存储单位。它可以是 0 或 1 。不能在
一个位中存储更多的信息,但是计算机中包含数量极其庞
大的位。位是计算机存储的最基本的单位。
字节( byte )是常用的计算机存储单位。几乎对于所有
的机器, 1 个字节均为 8 位。由于每个位或者是 0 或者
是 1 ,所以一个 8 位的字节包含 256 ( 28 )种可能的 0
、 1 组合。这些组合可用于表示 0 到 255 的整数或者一
组字符。这种表示可以通过二进制编码(仅使用 0 或
1
)来实现。
对于一种给定的计算机,字( word )是自然的存储单位。
对于 8 位微机,一个字正好有 8 位,对于 16 位机则意味
着一个字的大小为 16 位,基于 Pentium 的 PC 机和 Ma
cintosh PowerPC
中的字都是 32 位,更强大的计算机
可以是 64 位甚至更长的位数。
2.1.2
数据的机内表示
1
.数值数据的机内表示
2.2
数据的表现形式
2.2.1
常量
2.2.2
变量
2.2.1
常量
在某程序的整个运行过程中,其值不会发生变化
的量称为常量。如例 1.2 中的 222 和 333 ,数学
中的常数。
常量区分为不同的类型,如- 13 、 8 、 0 为整型
常量,其中,八进制整数常量以“ 0” 开头,如 02
34
表示八进制数 234 ,以“ 0x” 开头的常量为 16
进制常量,如 0x234 表示 16 进制的 234 。 4.6
、- 12.6 为实型常量, 'a' 、 'A' 为字符型常量。
这种常量一般从其字面形式即可判别。
还有一种常量,可以用一个标志符来代表一个常
量,称为符号常量,如例 2.1 所示。
2.2.1
常量
例 2.1 已知圆的半径,求圆的周长和面积。
#include <stdio.h>
#define PI 3.1415926
int main()
{
float r;
r = 3.5;
printf("l = %5.2f\ns = %5.2f\n", 2.0 * PI * r, PI * r * r);
return 0;
}
2.2.2
变量
程序 1.2 中的 a , b 和程序 2.1 中的 r 等是变量,变量在
程序中有确定的名称和特定的属性,并能够存储某种数据。
在程序运行过程中,变量的值允许改变。
以程序 2.1 中的变量 r 为例。 r 为变量名,语句“ r = 5;”
将常量 5 赋值给变量 r ,此时 r 中存放的是数值 5 ,那么
数值 3.5 就是此时 r 的变量值,这里 r 可以存放 3.5 ,也
可以存放其他数值,就像是一个容器,这个存放数据的
“容器”称为变量。
变量必须先定义,才能使用。例 2.1 中的语句“ float r;”
就是对变量 r 的定义,语句“ r = 3.5;” 就是使用变量 r 存
储数值 3.5 。在计算机内部,变量名实际上用名称代表一
个存储地址。
2.2.3
标示符
C
语言中,符号常量、变量都被称为标示符,以后要讲
到的类型、函数、数组等的命名使用的符号序列都是标示
符的一种。实际上,标示符就是一种对象的名称。如例 2
.1
中,语句“ #define PI 3.1415926” 中 PI ,语句“ float
r;”
中的 r ,语句“ printf("l = %5.2f\ns = %5.2f\n", 2.0 *
PI * r, PI * r * r);”
中的 printf ,都是标示符。
C
语言规定标示符只能由字母、下划线和数字 3 中字符构
成,并且首字符必须为字母或下划线。
下面列出的标示符为合法标示符:
a, b3, sum, point, average, year, _name, Day, BASIC,
Li_ning
下面列出的标示符为不合法标示符:
2.3 C
语言数据类型
2.3.1
整型数据
2.3.2
浮点型数据
2.3.3
字符型数据
2.3.1
整型数据
1 .整型 整型的类型名为 int 。不同的编译系统为整形数据分配的字节数是不 相同的, Tubro C 3.0 分配 2 个字节, Visual C++ 则是分配 4 个字 节,字节数的多少决定着这个数值的范围。 实际上,数值在计算机内是以补码的方式来表示的。在 Tubro C 3.0 中,一个 int 型的变量,系统分配 2 个字节,最大数为 0111111111 111111 ,最高位的符号位为 0 ,其他都为 1 ,数值为( 215 - 1 = 32767 ),最小数为 1000000000000000 ,最高位的符号位为 1 , 其他都为 0 ,数值为( -215 = -32768 )。 在 Tubro C 3.0 中,一个整型( int )变量只能容纳 -32768~32767 范围内的数。无法表示大于 32767 或小于 -32768 的数。遇到超出这 个范围的数就会发生“溢出”,但系统运行时并不会报错。好像里程表 一样,达到最大值以后,又从最小值开始计数。而在 Visual C++6.0 中,整型变量占 4 个字节,其容纳的数值范围为- 231~ ( 231 - 1 ),即 -2147483648~2147483647 。 随堂练习2.3.1
整型数据
2
.短整型
短整型的类型名为 short int 或 short , T
ubro C 3.0
和 Visual C++ 编译系统都是占
用 2 个字节存储,存储方式与整型( int )
相同,取值范围为 -32768~32767 。
2.3.1
整型数据
3
.长整型
长整型的类型名为 long int 或 long , Tub
ro C 3.0
和 Visual C++ 编译系统都是占用
4
个字节存储,存储方式与整型( int )相
同,取值范围为 -2147483648~214748364
2.3.1
整型数据
4
.双长整型
双长整型的类型名在 Visual C++ 编译系统
使用“ __int64” (两个下划线),在 GCC
中使用 long long int ,都占用 8 个字节存
储,存储方式与整型( int )相同,取值范
围为- 263~ ( 263 - 1 )。
双长整型是 C99 新增的类型,但一些 C 语
2.3.1
整型数据
5
.无符号整数
以上介绍的整数数据类型在计算机内部存储时都
以补码形式存在,存储单元中第 1 位代表符号。
而在实际应用中,有些数据的取值只能是非负值
(如年龄、销售数量、库存数量等)。为了充分
利用计算机的存储单元, C 语言允许将量定义为
“非负”类型,即“无符号”类型。在上述 4 种整型类
型名前加入修饰符 unsigned ,表示该量为“无符
号整数”类型。以上的整数类型的位数和取值范围
如表 2.1 所示。
2.3.1
整型数据
5
.整型常量
在程序中出现的形如数学中的整数,即为
整型常量,如例 1.2 中的 222 和 333 。其
他数据类型的常量与此相似。
2.3.1
整型数据
6
.整型变量
变量的定义方法如下:
数据类型名 变量名 1[, 变量名 2[, 变量名 3…]]
这里的数据类型名可以是表 2.1 中的类型名,也可以是下
面几节的数据类型名。变量名是标示符的一种,按照 2.2.
3
节中标示符的命名规则命名,方括号( [ ] )里面的内
容是可选项,即可有可无。
例如,定义一个变量,
int a;
定义多个变量,
2.3.2
浮点型数据
浮点数( floating-point number )可以和数学中的实数
( real number )的概念相对应。 2.75 、 7.00 、 3.16E
3
等都是浮点数。注意,加了小数点的数是浮点型值,所
以 7 是整数类型,而 7.00 是浮点型。
浮点型数据有两种表现形式:
( 1 )十进制小数形式。它由数字和小数点组成,注意,
必须有小数点。如 0.2 、 1.2 、 0.0 、 4. 、 2.0 都是十进
制小数形式。
( 2 )指数形式。如 1.23E5 或 1.23e5 都代表 1.23×105 。
但注意在字母 E 或 e 之前必须由数字,且 E 或 e 后面的
指数必须为整数。如 e3 、 2.1E3.5 、 .e3 、 e 都不是合
法的指数表现形式。
2.3.2
浮点型数据
浮点型变量可分为单精度浮点型( float )、双精度浮点型( double )和长双精度浮 点型( long double )。 标准 C 中并未规定每种类型数据的长度、精度和取值范围。有的系统将 double 型所 增加的 32 位全部用于存放小数部分,这样可以增加数值的有效位数,减少舍入误差。 而有的系统则是将所增加的位的一部分用于存放指数部分,这样可以扩大数值的范围 。 对于浮点型常量, C 语言编译系统都是作为双精度( double )型数据来处理的。如 : float f ; f = 2.34567 * 1234.56 ; 系统先把 2.34567 和 1234.56 作为双精度数,然后进行相乘的运算,得到的乘积也是 一个双精度数。最后取其前 7 位赋值给变量 f 。这样做可以使计算结果更精确,但是 运算速度降低了。如果是在数的后面加上字母 f 或者 F (如 1.23f 、 45.67F ),这样 编译系统就会把它们按单精度来处理。实际上,一个浮点型常量可以赋给 float 、 double 或者 long double 型的变量,系统将会根据变量的类型截取常量中相应的有效位 数。如:
float a;
a = 123456.789;
由于 float 型的变量只能接收 7 位有效数字,因此最后的两位小数将不起作用。如果 a
2.3.3
字符型数据
字符型数据的类型名为 char ,用于存储字母和标点符号之类的字符。 但是在技术实现上字符型数据却是整数类型,因为字符类型数据实 际存储的是整数而不是字符。为了处理字符,计算机使用一种数字 编码,用特定的整数表示特定的字符,如 ASCII 码。在 ASCII 码中 ,整数值 65 代表大写字母 A ,因此要存储大写字母 A ,实际上存 储整数 65 即可。 定义字符型变量根定义其他类型变量的方式相同,如: char c; char ch1, ch2; 这段代码创建了 3 个字符型的变量: c 、 ch1 和 ch2 。在所有的编 译系统中,都规定用一个字节来存放一个字符,或者说一个字符变 量在内存中占一个字节。 在内存中,字符数据以 ASCII 码存储,它的存储形式与整数的存储 形式类似。这就意味着字符型数据和整型数据之间可以通用。2.3.3
字符型数据
例 2.2 字符型数据两种形式输出。
#include <stdio.h>
int main()
{
char c1, c2;
c1 = 97;
c2 = 'b';
printf("%4c%4c\n", c1, c2);/*
以字符型的形式输出 */
printf("%4d%4d\n", c1,c2);/*
以十进制整数的形式输出 */
return 0;
}
2.3.3
字符型数据
例 2.3 字符型数据大小写字母转换。
程序清单如下:(文件名 2_3.c )
#include <stdio.h>
int main()
{
char c;
printf("Please input a lower character: ");
scanf("%c", &c);
c = c - 32;
printf("%c\n ",c);
return 0;
2.3.3
字符型数据
字符常量及字符串常量
C
语言中的字符常量是用单撇号括起来的单个字
符。如 'a' 、 'X' 、 '?' 、 '$' 等都是字符常量。除
了这种形式的字符常量之外, C 语言还允许用一
种特殊形式的字符常量,即用一个字符“ \” 开头
的字符序列。这是一种“控制字符”,在屏幕上不
能显示,在程序中也不能用一般形式的字符表示
,只能采用特殊的形式来表示。如前面已经提到
过的 printf( ) 函数中的“ \n” ,它代表一个换行符。
2.3.3
字符型数据
例 2.4 转义字符示例。 程序清单如下:(文件名 2_4.c ) #include <stdio.h> int main() { float salary; printf("Please input your desired monthly salary:"); // 语句 5
printf(" RMB_______\b\b\b\b\b\b\b"); // 语句 6
scanf("%f", &salary); // 语句 7
printf("\tRMB %.2f a month is RMB %.2f a year. \n ", salary, sal ary * 12.0); // 语句 8
return 0;
2.3.4
各种类型数据之间的转换和混
合运算
例 2.5 不同数据类型的混合运算示例。 #include <stdio.h> int main() { char ch; int i; float f; f = i = ch = 'C'; // 语句 7 printf("ch = %c, i = %d, f = %.2f\n", ch, i, f); // 语句 8 ch = ch + 1; // 语句 9 i = f + 2 * ch; // 语句 10 f = 2.0 * ch + i; // 语句 11 printf("ch = %c, i = %d, f = %.2f\n", ch, i, f); // 语句 12 ch = 123456.78; // 语句 13 printf("Now ch = %c\n", ch); // 语句 14 return 0; }2.3.4
各种类型数据之间的转换和混
合运算
例 2.6 数据类型强制转换示例
#include <stdio.h>
int main()
{
float x;
int i;
x = 3.6;
i = (int)x;
printf("x = %f, i = %d\n", x, i);
return 0;
}
2.4
运算符与表达式
2.4.1
基本算术运算符
2.4.2
算术表达式
2.4.3
自增、自减运算符
2.4.1
基本算术运算符
最常用的算术运算符包含数值计算中的加
、减、乘、除、正号、负号、求余。
下表中,变量 a 的值为 10 。
2.4.2
算术表达式
算术表达式是用算术运算符和圆括号把运
算对象(常量、变量和函数)连接起来构
成的合法的算式。
例如: 5 , a , 5+3 , 5.8/2.3 , a*b+c/2
, x*(y+z%3) 。
在算术表达式中,运算对象可以是整型、
浮点型、字符型的常量、变量及函数,运
算对象按照算术运算符的规则进行运算,
得到的结果就是算术表达式的值。
2.4.3
自增、自减运算符
自增、自减运算符是 C 语言特有的运算符
,自增运算符的符号为++,自减运算符
的符号为――,可以放在变量前和变量后
,共有 4 种使用形式。
2.4.4 sizeof( )
运算符
在前面我们介绍了在不同的系统中,同一种数据类型所占内存空间的字节数 数不同的。那么如何确定一个数据类型在某一确定系统中所占的字节数呢? 实际上, C 语言提供的运算符 sizeof 可以以字节为单位给出数据类型的大 小。例如: 例 2.7 数据类型强制转换示例。 程序清单如下:(文件名 2_7.c ) #include <stdio.h> int main() { printf("Type int has a size of %u bytes.\n", sizeof(int)); printf("Type char has a size of %u bytes.\n", sizeof(char)); printf("Type long has a size of %u bytes.\n", sizeof(long)); printf("Type float has a size of %u bytes.\n", sizeof(float));
printf("Type double has a size of %u bytes.\n", sizeof(double));
return 0;
2.5 C
语言的基本语句
2.5.1 C
语言语句概况
2.5.1 C
语言语句概况
程序是下达给计算机的系列指令,这些指令的各
种组合可以完成各种工作。在高级语言中,这些
指令是通过语句来实现的。
C
语言的语句可以分为五类:
( 1 )表达式语句
( 2 )函数调用语句
( 3 )控制语句
( 4 )复合语句
( 5 )空语句
语句的功能各有不同,但在格式上必须以分号
(;)结尾。
2.5.2
赋值语句
1
.基本赋值运算符
赋值运算符(=)的左侧必须是变量,右
侧是表达式。赋值运算符的功能是先计算
右侧表达式的值,然后把表达式的值赋给
左侧的变量。
例如, a=5 ,就是将常量 5 放在变量 a 中
存储, a 中如果以前有值会被覆盖。
2.5.2
赋值语句
2
.复合赋值运算符
赋值运算符(=)前加上其他运算符,可
以构成复合赋值运算符。
如果在“=”前加“+”就成为复合赋值运算符
“ +=” ,“ +=” 的功能是先计算右侧的表达
式的值,然后加上左侧变量的值,再将值
赋给左侧的变量。其他复合赋值运算符与
之类似 。
2.5.2
赋值语句
3
.赋值表达式
由赋值运算符将一个变量和一个表达式连接起来
的算式称为复制表达式。它的一般形式为:
变量 赋值运算符 表达式
赋值表达式的功能是先计算一个表达式的值,后
将值赋给一个变量。例如,赋值表达式 a=2*3 的
执行过程是先求出赋值运算符右侧的表达式“ 2*3”
的值,再将“ 2*3” 的结果值赋给变量 a ,这里赋
值运算符右侧的表达式“ 2*3” 的值为 6 ,变量 a
的值为 6 ,整个赋值表达式 a=2*3 的值也为 6 ,
即赋值运算符左侧的变量的值就是整个赋值表达
式的值。
2.6
输入输出函数
2.6.1 printf( )
函数
2.6.2 scanf( )
函数
2.6.3 putchar( )
函数
2.6.1 printf( )
函数
1
. printf( ) 函数的一般格式
printf()
函数的一般格式为:
2.6.1 printf( )
函数
2
.格式字符
( 1 )格式字符 d
( 2 )格式字符 c
( 3 )格式字符 s
( 4 )格式字符 f
( 5 )格式字符 e
( 6 )格式字符 I
( 7 )格式字符 o
( 8 )格式字符 x
( 9 )格式字符 u
( 10 )格式字符 g
2.6.2 scanf( )
函数
1
. scanf( ) 函数的一般形式
scanf( )
函数的一般格式为:
scanf("<
格式化字符串 >", < 地址参数列
2.6.2 scanf( )
函数
2 . scanf( ) 函数的格式控制 scanf( )函数与 printf( ) 函数格式类似,用 % 加上格式字符结束,中间可以插入附加 的字符。例 2.19 printf( ) 函数格式字符 e 示例。 程序清单如下:(文件名 2_19.c ) #include <stdio.h> int main() { float a , b; int c , d; char e , f; scanf("%f,%f", &a , &b);
getchar( );
scanf("c=%d d=%d", &c, &d);
getchar( );
scanf("%c%c", &e , &f);
printf("a=%f\nb=%f\nc=%d\nd=%d\ne=%c\nf=%c\n", a, b, c, d, e, f);
return 0;
2.6.3 putchar( )
函数
putchar( )
函数是字符输出函数,一般用
于向标准输出设备输出一个字符。
putchar( )
函数的一般形式为:
putchar(ch)
putchar
为函数名, ch 为字符型量,即将
ch
变量中的字符显示在屏幕上。
2.6.4 getchar( )
函数
getchar ( )
函数是字符输入函数,一般用
于向标准输入设备输入一个字符。
getchar ( )
函数的一般形式为:
getchar ( )
getchar
为函数名,括号内没有参数,读
取屏幕上的一个字符。
2.7
程序举例
例 2.23 求二次方程 ax2+bx+c=0 的根,其中 a , b , c 由键盘输 入。 程序清单如下:(文件名 2_23_1.c ) #include <stdio.h> #include <math.h> int main() { double a, b, c, x1, x2; scanf(“%lf%lf%lf”, &a, &b, &c);
x1 = (-b+sqrt(b*b-4*a*c)) / (2*a);
x2 = (-b- sqrt(b*b-4*a*c)) / (2*a);
printf(“x1=%6.2f\nx2=%6.2f\n”, x1, x2);
return 0;
2.7
程序举例
例 2.23 改进解法 程序清单如下:(文件名 2_23_2.c ) #include <stdio.h> #include <math.h> int main() { double a, b, c, x1, x2, sq; scanf("%lf%lf%lf", &a, &b, &c);
sq = sqrt(b*b-4*a*c); x1 = (-b+sq) / (2*a); x2 = (-b-sq) / (2*a); printf("x1=%6.2f\nx2=%6.2f\n", x1, x2); return 0; }
2.7
程序举例
例 2.24 从键盘输入一个大写字母,在屏幕上输出对应的小写字母。 例 2.24 解法 1 程序清单如下:(文件名 2_24_1.c ) #include <stdio.h> int main() { char ch1, ch2; scanf(“%c”, &ch1); ch2 = ch1 + 32; printf(“%c\n”, ch2); return 0; }2.7
程序举例
例 2.24 解法 2
程序清单如下:(文件名 2_24_2.c )
#include <stdio.h>
int main()
{
char ch1, ch2;
ch1 = getchar( );
ch2 = ch1 + 32;
putchar(ch2);
putchar(‘\n’);
return 0;
}
2.8
小结
本章主要介绍了以下几方面内容:
1
.变量与常量的基本概念。
2
. C 语言中的数据类型。 C 有多种数据类型,本章介
绍了整型、浮点型和字符型数据,对每种数据类型介绍了
它在内存中的存储形式以及具体分类。
3
.运算符与表达式。本章介绍了常用的算术运算符、自
增自减运算符、 sizeof( ) 运算符用法。
4
. C 语言的基本语句。本章介绍了赋值语句的用法。
5
.输入输出函数。本章介绍了部分输入输出函数,包括
printf( )
函数、 scanf( ) 函数、 putchar( ) 函数、 getch
ar( )
函数的用法。
3.1
关系运算符和关系表达式
3.1.1
关系运算符及其优先级别
3.1.1
关系运算符及其优先级别
在 C 语言中提供了 6 种关系运算符,前 4
种关系运算符(<、<=、>、>=)的
优先级别相同,后两种(==、 ! =)的
优先级别也相同,且前 4 种高于后两种。
关系运算符的优先级别低于算数运算符,
高于赋值运算符。
3.1.2
关系表达式
用关系运算符将两个表达式连接起来的式子就称
其为关系表达式。
关系表达式也有一个值,与算数表达式不一样,
关系表达式所描述的条件只有两种情况,“成立”或
者“不成立”。所以在 C 语言中用“真”或者“假”来描
述这两种情况。例如,“ 5 < 6” 的值是“真”而“ 4
>= 10” 的值是“假”。
在 C 语言中没有逻辑型数据来描述“真”或“假”,而
是采用“ 1” 或“ 0” 来反映关系表达式的结果。如
果某个关系表达式的值为“真”,则这个关系表达式
的值就是“ 1” ,如果为“假”,则值为“ 0” 。
3.2
逻辑运算符和逻辑表达式
3.2.1
逻辑运算符及其优先级别
3.2.1
逻辑运算符及其优先级别
C
语言中提供了 3 种逻辑运算符 .“&&” 和
“ ||” 是双目运算符,要求有两个运算量,
如( a < b ) && ( c > d )、( a < b )
||
( c > d )。“!”是单目运算符,只需要
一个运算量,如!( a < b )。
逻辑运算符的优先级别由高到低是:“!”、
“ &&” 、“ ||” 。其中“ &&” 和“ ||” 低于关系
运算符,而“!”高于算数运算符。
3.2.2
逻辑表达式
用逻辑运算符将关系表达式或逻辑量连接起来的
式子就是逻辑表达式。跟关系表达式一样,逻辑
表达式的值也是一个逻辑量“真”或“假”。在表示逻
辑表达式的计算结果的时候,仍然使用数值“ 1”
代表逻辑真,以数值“ 0” 代表逻辑假。但在判断
某一个量是否是真的时候,则是以“ 0” 值代表假
,以“非 0” 值代表真。如:
若 a = 5 , b = 0 , c = 2 ,则! a 的值为 0 ,因
为 a 的值为 4 ,是一个非 0 值,被认作“真”。同
理! b 的值为 1 , a && c 的值为 1 。
3.3 if
语句
3.3.1
简单的 if 语句
3.3.2
在 if 语句中添加 else 子句
3.3.3
多重选择 else if
3.3.1
简单的 if 语句
最为简单的 if 语句,是用来决定是否执行
某个语句或者语句组。格式如下:注意:
这里没有“;”。
if
(表达式)
{
语句组;
}
3.3.1
简单的 if 语句
如果表达式的值为“真”(或者非零),就执行语
句组,否则程序就会跳过该语句组,直接执行 if
语句之后的其他语句。其程序流程如图 3.1
( a )所示。通常,表达式是一个关系表达式或
者逻辑表达式,根据表达式值的真假来判断是否
执行语句组。更一般的情况,表达式可以是任意
的表达式,表达式的值为 0 就被视为假,非 0 就
被视为真。
当语句组只有一个语句的时候,这时候 if 语句的
一对花括号可以省略。
3.3.1
简单的 if 语句
例 3.1 在键盘上输入两个不同的整数,并输出较大的那个整数。 程序清单如下:(文件名 3_1.c ) #include <stdio.h> int main(){ int a,b; printf(" 请输入两个不同的整数: "); scanf("%d,%d",&a,&b); if (a > b) { // 如果 a 的值大于 b 的值 printf(" 较大的数是: %d\n",a); // 输出 a 的值 return 0; // 结束程序 } printf(" 较大的数是: %d\n",b); // 当 a 大于 b 的情况不成立,输出 b 的 值。 return 0; }3.3.2
在 if 语句中添加 else 子句
简单形式的 if 语句可以让我们根据条件的成立与否来判断是执行还是忽略某 种操作。更多的时候,我们需要根据条件的成立与否在两个操作中选择一个 来执行,这时候如果只是使用 if 语句,程序就显得笨拙,我们可以在 if else 的形式来解决这个问题。 if else 语句的一般格式如下:注意:这里没有“;”。 if (表达式) { 语句组 1 ; } 注意:这里也没有“;”。 else { 语句组 2 ; } if else 语句的执行过程是:如图 3.11 ( b )所示,表达式的值为“真”,则执 行语句组 1 ,否则,执行语句组 2 。同样,当语句组 1 只有一句语句时, if 后面的一对花括号可以省略,语句组 2 只有一句语句时, else 后面的一对3.3.2
在 if 语句中添加 else 子句
例 3.2 在键盘上输入三个实数,表示一个三角形三条边的边长,判断这三条边能否构 成一个三角形。 程序清单如下:(文件名 3_2.c ) #include <stdio.h> int main(){ float a,b,c; printf(" 请输入三角形三边的边长: "); scanf("%f,%f,%f",&a,&b,&c); if (a+b>c && a+c>b && b+c>a){ // 判断任意两个数是否大于第三个数
printf(" 此三条边能构成一个三角形。 \n"); } else{ printf(" 此三条边不能构成一个三角形。 \n"); } }
3.3.2
在 if 语句中添加 else 子句
例 3.3 在键盘上输入一个正整数,判断该数是否能同时被 3 和 7 整除。 程序清单如下:(文件名 3_3.c ) #include <stdio.h> int main(){ int n; printf(" 请输入一个正整数: "); scanf("%d",&n); if (n % 3 ==0 && n % 7 == 0){ printf(" 该数可以被 3 和 7 整除。 \n"); } else{ printf(" 该数不可以被 3 和 7 整除。 \n"); } return 0;3.3.2
在 if 语句中添加 else 子句
在 C 语言中有一个条件运算符“ ? : ”。条件运算符的作用相当于一 条 if 语句。如下例: ; 其中“”是一个“条件表达式”。它的执行过程是:如果( a > b )为真 ,则条件表达式取值 a ;否则取值 b 。无论表达式“ a > b” 成立与否 ,都在执行一个赋值语句,并且向同一个变量 max 赋值。 条件运算符要求有 3 个操作对象,称三目运算符,它是 C 语言中唯 一的一个三目运算符。其一般形式为: 表达式 1 ?表达式 2 :表达式 3 其执行顺序为:先求解表达式 1 ,若为真(非 0 ),则求解表达式 2 ,并把表达式 2 的值作为整个条件表达式的值。若表达式 1 为假 ( 0 ),则求解表达式 3 ,并把表达式 3 的值作为整个条件表达式 的值。3.3.3
多重选择 else if
在解决实际问题的时候,我们经常也会遇到多重选择的时候,这个时候就可以使用 else if 来扩展 if else 结构来适 应这种情况。其一般格式如下: if(表达式 1 ) { 语句组 1 ; } else if(表达式 2 ) { 语句组 2 ; } else if(表达式 3 ) { 语句组 3 ; }图 3.5 多重选择 else if 结构流程图 … else if(表达式 n-1 ) { 语句组 n ; } else { 语句组 n ; }3.3.3
多重选择 else if
例 3.4 学生成绩测评等级规则如下: 90 分以上为“优秀”, 80—89 为“良好”, 70—79 为“中等”, 60—69 为“及格”,低于 60 分为“不及格”。 程序清单如下:(文件名 3_4.c ) #include <stdio.h> int main(){ int s; printf("请输入学生的成绩( 0-100 ): "); scanf("%d",&s); if (s >= 90 && s <= 100){ printf("优秀 !\n"); } else if (s >= 80){ printf("良好 !\n"); } else if (s >= 70){ printf("中等 !\n"); } else if (s >= 60){ printf("及格 !\n"); } else{ printf("不及格 !\n"); } return 0; }3.3.4 if
语句的嵌套
在 if 语句的语句组中又包含一个或多个 if 语句称为 if 语句的嵌套。其一般形式如下: if(表达式) { if(表达式) { 语句组 1 ;内嵌 if 语句 } else {同理,在每一个语句组里还可以继续嵌套 if 语句。 语句组 2 ; } } else { if(表达式) { 语句组 3 ;内嵌 if 语句 } else { 语句组 4 ; } }3.3.4 if
语句的嵌套
例 3.5 将例 3.4 用 if 语句的嵌套形式编写。 程序清单如下:(文件名 3_5.c ) #include <stdio.h> int main(){ int s; printf("请输入学生的成绩( 0-100 ): "); scanf("%d",&s); if (s >= 60 && s <= 100){ if (s >= 90){ printf("优秀 !\n"); } else{ if (s >= 80){ printf("良好 !\n"); } else{ if (s >= 70){ printf("中等 !\n"); } else{ printf("及格 !\n"); } } } } else{ printf("不及格 !\n"); } return 0; }3.4 switch
语句
在 C 语言中还可以使用 switch 语句来直接处理
多分支选择的情况。它的一般形式如下:
switch
(表达式)
{
case
常量表达式 1 :语句组 1 ;
case
常量表达式 2 :语句组 2 ;
…
case
常量表达式 n :语句组 n ;
default
: 语句组 n+1 ;
}
3.4 switch
语句
对 switch 语句做以下几点说明: ( 1 ) switch 后面括号内的表达式可以是任意类型的表达式,当表达 式的值与某一个 case 后面的常量表达式的值相等时,就执行此 case 后面的语句,如果所有 case 后面的常量表达式的值都没有与表达式匹 配的,则执行 default 后面的语句。 default 可以省略。 ( 2 )每一个 case 的常量表达式的值必须互不相同,否则就会出现互 相矛盾的现象。而且其值必须是一个常量(在程序运行过程中,值不 会发生改变的量)。各个 case 和 default 的出现次序不影响执行结果 。 ( 3 )执行完一个 case 后面的语句后,程序流程转移到下一个 case 继续执行,直到 switch 语句执行结束或者遇见 break 语句的时候才结 束 switch 语句的执行。“ case 常量表达式”只是起语句标号的作用, 并不是在该处进行条件判断。在执行 switch 语句时,根据 switch 后 面表达式的值找到匹配的入口标号,就从此标号开始执行,不再进行 判断。因此应该在需要跳出 switch 结构的 case 分支处使用“ break” 语句来终止 switch 语句的执行。3.4 switch
语句
例 3.6 有一个函数: x+1 (1<x<10) y= x (10<x<20) x+2 (20<x<30) 编写一程序,从键盘上输入 x 的值,根据上面的函数,求出 y 的值,并输出。 程序清单如下:(文件名 3_6.c ) #include <stdio.h> int main() { float x,y; int c; printf("请输入 x 值: "); scanf("%f",&x); c = (int) x / 10; switch (c){ case 0: y = x + 1; break; case 1: y = x; break; case 2: y = x + 2; break; } printf("y的值为: %f\n",y); return 0; }3.4 switch
语句
例 3.7 为运输公司对客户计算运费。路程
s
(单位: km )越远,每吨每千米运费越
3.4 switch
语句
#include <stdio.h> int main() { int c, s; float p, w, d, f; scanf("%f%f%d", &p, &w, &s);
if(s >= 3000) { c = 12; } else { c = s / 250; } switch(c) { case 0: d = 0; break; case 1: d = 0.02; break; case 2: case 3: d = 0.05; break; case 4: case 5: case 6: case 7: d = 0.08; break; case 8: case 9: case 10: case 11: d = 0.1; break; case 12: d = 0.15; break; } f = p * w * s * (1 - d); printf("freight = %15.4f\n", f); return 0;
4.1 while
语句
while 语句通过对于某个条件的判断,来决定是否继续执行重复的操作。 例 4.1 使用 while 循环来求“ 1+2+3+…+100” 的值。 #include <stdio.h> int main() { int i = 1, sum = 0;while 循环语句,循环体为“ sum+=i ; i+
+ ;”。其中“ i++” 等价于“ i= i+1” 。 while(i <= 100) { sum += i; i++; } printf("1+ 2 + 3 + … + 100 = %d\n", sum); return 0; }
4.1 while
语句
例 4.2 通过循环变量来控制 while 循环的循环次数。 程序清单 4.2 4_2.c 程序 #include <stdio.h> void main() { int n = 1; while(n < 5) { printf(" 这是第 %d 次循环 \n", n); n++; printf(" 在 n++; 执行之后 n = %d\n", n); printf("__________________________\n"); } printf(" 程序结束! \n"); }4.2 do…while
语句
例 4.3 使用 do…while 循环来求“ 1+2+3+…+100” 的值。
程序清单 4.3 4_3.c 程序
#include <stdio.h>
void main()
{
int i = 1, sum = 0;
do
{
sum += i;
分号“;”不能少
i++;
}while(i <= 100);
printf("1 + 2 + 3 + ... + 100 = %d\n", sum);
}
4.2 do…while
语句
do…while
语句的一般形式如下:注意分号“;”不能少。
do
{
循环体语句组;
}while
(表达式);
可以看到,对于同一个问题,可以使用 while 语句,也可
以使用 do…while 语句,二者可以互相替换。但是它们
还是有区别的, while 语句先判断条件是否成立,然后根
据条件的结果来决定是否执行循环体,而 do…while 语
句先执行循环体一次,然后再判断表达式成立与否。即 d
o…while
语句至少要执行循环体一次。
4.3 for
语句
4.3.1 for
语句
4.3.2
逗号运算符和逗号表达式
4.3.3 continue
语句和 break 语句
4.3.1 for
语句
C 语言中的 for 语句是使用最为灵活的语句。同样,我们先使用 for 语句来改写程序 4.1 求“ 1+2+3+…+100” 的值。 例 4.5 通过 for 语句求“ 1+2+3+…+100” 的值。 程序清单 4.5 4_5.c 程序 #include <stdio.h> void main() { int i, sum = 0; for(i = 0; i <= 100; i++) 循环体语句 { sum += i; } printf("1 + 2 + 3 + ... + 100 = %d\n", sum); }4.3.1 for
语句
程序的运行结果与图 4.2 相同。可以看出, for 语句的一般形式如下: for (表达式 1 ;表达式 2 ;表达式 3 ) { 循环体语句组; } 当循环体语句组只有一句的时候,花括号可以省略。建议初学者不要省略, 避免出错。 for 语句的流程如图 3.22 所示。从图中可以看出,其执行过程如 下: ( 1 )求解表达式 1 ; ( 2 )求解表达式 2 ,如果为真,则执行循环体语句组,执行结束后转步骤 ( 3 );如果表达式的结果为假,则结束循环,转步骤( 5 ); ( 3 )求解表达式 3 ; ( 4 )转步骤( 2 );图 4.6 for 语句执行流程 ( 5 )循环结束,执行循环语句之后的其他语句。 for 语句的 3 个表达式均可省略,但是里面的分号“;”不能省略。需要注意的 是,省略相应的表达式,就需要在其他地方弥补相应表达式的功能,以保证 程序的正常运行。4.3.2
逗号运算符和逗号表达式
逗号运算符扩展了 for 循环语句的灵活性,它可以使 for
循环语句使用多个初始化或循环变量更新表达式。
例 4.6 通过 for 语句以及逗号运算符求“ 1+2+3+…+100”
的值。
程序清单 4.6 4_6.c 程序
#include <stdio.h>
void main()
逗号表达式
{
有“;”,表示 for 语句没有循环体语句。
int i, sum;
for(i = 1, sum = 0; i <= 100; sum += i,i++);
printf("sum = %d\n", sum);
4.3.2
逗号运算符和逗号表达式
逗号表达式,其一般形式如下: 表达式 1 ,表达式 2 ,…,表达式 n 逗号表达式的求解过程为:按照先后顺序,依次求解表达式 1 ,表 达式 2 ,……,最后求解表达式 n 。并将最后求解的表达式 n 的值 作为整个逗号表达式的值。如程序 3.15 中的: i = 1, sum = 0; 先 求解赋值表达式 i = 1 ,然后在求解表达式 sum = 0 ,并将表达式 s um = 0 的值作为整个逗号表达式的值,所以该逗号表达式的值为 0 。 逗号运算符是所有运算符中级别最低的,所以“ a = 3 * 5, a * 2” 应理 解成“ (a = 3 * 5), (a * 2)” 而不是“ a = (3 * 5, a * 2)” 。在逗号表达式 的子表达式可以是任意的表达式,包括逗号表达式。如: (a = 3 * 5, a * 2), a - 4 。 逗号运算符并不只限于在 for 语句中使用。同时,需要引起注意的是 ,在定义时变量之间的分隔符,以及在 printf() 函数和 scanf() 函数 中一些分隔符不属于逗号运算符。4.3.3 continue
语句和 break 语
句
continue语句用于在循环中提前结束本次循环。 例 4.7 编写程序把 100 以内不能被 3 整除的正整数输出。程序清单如下: 程序清单 4.7 4_7.c 程序 #include <stdio.h> int main() { int i, count = 0; for(i = 1; i <= 100; i++) { if(i % 3 == 0) { continue; } count++; //对输出的数据个数进行计数 printf("%5d", i); if(count % 10 == 0) //使输出结果每行 10 个数据 { printf("\n"); } } return 0; }4.3.3 continue
语句和 break 语
句
例 4.8 输入一正整数 m ,判断 m 是否是素数(只能被 1 和它本身整除的数),并输出结果。 程序清单 4.8 4_8.c 程序 #include <stdio.h> int main() { int i, m, k=0; // i为循环变量, m 是要判断的整数, k 用于记录循环执行次数 printf("请输入一个整数 : "); // 在屏幕上提示用户输入数据 scanf("%d", &m); for(i = 2; i <= m-1; i++) { k++;如果“ m % i == 0” 成立,则表明有一个 i 能整除 m 。 m 不是素数,后面的没有必要再判 断,直接结束循环。 if(m % i == 0) { break; } }“i ==m”表明在 for 语句中没有执行“ break” 语句,即没有一个 i 能整除 m , m 是素数。 if(i== m) { printf("%d 是一个素数 .\n", m); } else { printf("%d 不是一个素数 .\n", m); } printf("循环共执行了 %d 次 .\n",k); return 0; }
4.3.3 continue
语句和 break 语
句
例 4.9 对例 4.8 进行改进。 程序清单 4.9 4_9.c 程序 #include <stdio.h>
#include <math.h> //程序中使用了 sqrt ()函数,所以要包含 math.h 文件 int main() { int i, m, n,k=0; printf("请输入一个整数 : "); // 在屏幕上提示用户输入数据 scanf("%d", &m); n = (int)sqrt(m); //将函数 sqrt ()的返回值强制转化成 int 型 for(i = 2; i <= n; i++) { k++; if(m % i == 0) { break; } } if(i > n) { printf("%d 是一个素数 .\n", m); } else { printf("%d 不是一个素数 .\n", m); } printf("循环共执行了 %d 次。 \n",k); return 0; }
4.3.4
循环的嵌套
例 4.10 求 200—500 之间所有的素数之和。 程序清单 4.10 4_10.c 程序 #include <stdio.h> #include <math.h> int main() {外循环,控制 i 的范围。这里 i 的增量为 2 ,对偶数不进行判断。 int i,j,n,sum = 0; for(i = 201; i < 500; i += 2) { n = (int)sqrt(i);内循环,判断 i 是否是素数。 for(j = 2; j <= n; j++) { if(i % j == 0) { break; } } if(j > n) { sum += i; } } printf("200-500之间的素数之和为 %d\n",sum); return 0; }4.4
循环结构程序举例
例 4.11 编写程序,计算并输出 k 以内最大的 10 个能被 13 或者 17 整除的自然数之和。 k 值由键盘输入。 程序清单 4.11 4_11.c 程序
#include <process.h> //此头文件用于支持系统函数 system( ) 。 #include <stdio.h> int main() { int m = 0; //用于存放符合条件的自然数之和,初始值为 0 。 int mc = 0; //用于计数,记录出现了第几个符合题意的数。 //程序中 mc 从 0 到 9 ,共取 10 个数。 int k; system("cls"); //清屏函数。 printf("请输入 k 的值: "); scanf("%d",&k); while((k>=13) && (mc<10)) { if((k%13==0)||(k%17==0)) { m = m + k; mc++; } k--; } printf("结果为: %d\n",m); return 0; }