77范文网 - 专业文章范例文档资料分享平台

浙江大学刘加海C语言课件1

来源:网络收集 时间:2018-11-11 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

16 #include void main() {

unsigned int a=65535; int b=-2;

C语言程序设计 printf(\}

(A)-1,65535; -2,65534 (B)65535,65535; -2,65534 (C)65535,65535; 65534,65535 (D)-1,65535; 65534,65534

解析:一个有符号整数(int型)可以用%u格式输出;反之,一个unsigned型数据也可以用%d格式输出。其处理方式按相互赋值的规则处理,即将非unsigned数据赋给长度相同的unsigned型变量,连原有符号位也作为数值一起原样照赋。因此,-2用unsigned型格式输出时,结果为65534。同理,unsigned型数据65535用整型格式输出时,结果为-2。答案(A)。 1.5.4 实型变量

在C语言中可以用两种形式表示一个实型变量或实型常量。 1.小数形式表示

即在数学中常用的实数形式,由数字和小数点组成(注意:必须要有小数点),如 0.123、.123、23.、0.0等都是合法的实型常量。

2.指数形式表示

这种形式类似数学中的指数形式。在数学中,一个数可以用幂的形式来表示,如2.3026可以表示为0.23026e1,0.0002345可以表示为2.345e-4等形式。C语言的语法规定,字母e(或E)前后必须要有数字,且e或E后面的指数必须为整数。如果写成e3 、.5e3. 、.e3 、e等都是不合法的指数形式。注意:在字母e(或E)的前后以及数字之间不得插入空格。

C语言中实型变量分为单精度型和双精度型两类,分别用类型名float和double进行定义。

注意:

(1)在整型变量的空间不能存放一个实数,也不能在实型变量的空间存放一个整数。 (2)在计算机内存中可以精确地存放一个整数,但不能精确地存放一个实型数。 (3)在程序中一个实数可以用小数形式表示,也可以用指数形式表示。但在内存中,一律是以浮点数指数形式存放的。

例1.16 实型变量输入、输出的例子。

#include void main() {

第1章 C程序设计基础

double x,y,z;

17 scanf(\/* 由键盘输入两个double型数据,输入时两个数据用空格隔开*/ printf(\/* 输出时除格式控制符外其他原样输出*/ z=x+y;

printf(\}

思考: 定义三个整型数x、y、z,用键盘输入x、y,输入的的两个数据用逗号隔开,然后求出出两个数的乘积。如键盘输入:2,3 程序输出为2*3=6。 提示:输入格式应该为:scanf(“%d,%d”,&x,&y); 输出语句为:printf(“%d*%d=%d\\n”,x,y,z); 1.5.5 字符变量与字符串

C语言中,一个字符常量代表ASCII字符集中的一个字符,在程序中用单引号括起来作为字符常量。例如:‘A’、‘C’、‘t’、‘!’、‘?’都是合法的字符常量。

C语言中,字符变量用关键字char进行定义,在定义的同时可以赋初值。

1.字符变量

定义形式:

char 变量名1,变量名2,???,变量名n; 例:char ch;

注意:

一个字符变量占用一个字节的内存空间,只能存放一个字符,以单引号表示。 例: char c1, c2;

c1=’a’; c2=’b’;

字符变量的值是该变量所代表的字符ASCII代码、与整数的存储形式相似,如字符‘a’的ASCII代码为97,其存储形式为01100001。同理98也可代表字符‘b’,它的存储形式为二进制的01100010。

因而在0~127范围内的字符与整型数可以互相赋值,并且所有字符常量都可作为整型量来处理。

例1.17 字符与整型数互相赋值的例子。

#include void main()

18 {

C语言程序设计 int i; /*定义一个整型变量*/ char c; /*定义一个字符变量*/ i=’a’; /*字符赋值给整型变量 */ c=97; /*整型数赋值给字符变量*/ printf(\

c=c+1; /*加1后c为98,字符’b’的ASCII码为98*/ printf(\变量c分别以整型、字符型输出*/ i=i+1; /*’a’+1为’b’*/

printf(”%d %c\\n\变量i分别以整型、字符型输出*/ }

程序运行的结果如图1.9所示,请同学们自行分析输出结果。

图1.9 例1.17程序运行结果

注意:

(1)单引号中的大小写字符代表不同的字符常量,例如,‘B?和‘b’是不同的字符常量。

(2)单引号中的空格符也是一个字符常量。

(3)字符常量只能包含一个字符。因此‘abc’是非法的。

(4)字符常量只能用单引号括起来,不能用双引号。例“a”不是字符常量而是一个字符串。

(5)字符变量在内存中占一个字节,字符变量可以存放ASCII字符集中的任何字符。当把字符放入字符变量中时,字符变量中的值就是该字符的ASCII代码值。所以字符变量可以作为整型变量来处理,也可以参与对整型变量所允许的任何运算。例如:

68-?A? 的值为3

?A?+32 的值为‘a’ ?1?-?0? 的值为1

在C语言中,字符常量也可以进行关系运算。如:‘a’<‘b’,由于在ASCII代码表中,‘a’的值97小于‘b’的值98.所以关系运算的结果为1。

第1章 C程序设计基础

思考: 程序中定义一个字符变量ch,并初始化为?a?,通过运算把ch的值转化为?B?输出。 提示:考虑表达式ch=ch-32+1 19 2.转义字符

转义字符又称反斜线字符,这些字符常量总是以一个反斜线开头后跟一个特定的字符来代表某一个特定的ASCII字符,这些字符常量也必须括在一对单引号内。例如:‘\\n’表示换行符。表1.3列出了C语言中的转义字符。

表1.3 转义符

字符形式 \\n \\b \\v \\” \\\\ \\a \\r \\t \\f \\' \\0 \\ddd \\xhh 功 能 换行 退格 垂直跳格 双引号 斜杠 报警 回车 水平跳格 换页 单引号 空字符 三位8进制数ddd所代表的字符 二位16进制数hh所代表的字符 注意:

转义字符常量,如‘\\n’、‘\\101’、‘\\141’只代表一个字符。反斜线后的八进制数可以不用0开头。如:‘\\101’代表的就是字符常量‘A’。反斜线后的十六进制数只可由小写字母x开头,不允许用大写字母X,也不能用0x开头。如:‘x41’代表字符常量‘A’。 例1.18 转义字符输出的例子。

#include void main() {

printf(\}

先显示My mane is 然后“嘟”,显示Liu。

思考:

20 C语言程序设计 编写一个程序,屏幕输出字符串:”c:\\Visual C++ 文件”,要求应用转义字符?\\\\?、?\\x20?、?\\t? ,请考虑字符串:\文件\。 注意:

‘\\n’与‘\\r’的区别。 3.字符串

字符串常量是由双引号括起来的一串字符。如“string”就是字符串常量,在C语言中,系统在每个字符串的最后自动加入一个字符‘\\0’作为字符串的结束标志。请注意字符常量和字符串常量的区别,例如:‘z’是字符常量,在内存中占一个字节;而“abcd”,“z”是字符串常量,前者占五个字节,后者占两个字节的存储空间,其中一个字节用来存放‘\\0’。两个连续的双引号“”也是一个字符串常量,称作“空串”。但要占一个字节的存储空间来存放‘\\0’。

例1.19 下列数据中,为字符串常量的是( )。

(A)‘A’ (B)“house” (C)How do you do. (D)$abc

解析:字符串常量是用一对双引号括起来的字符序列。答案:B。

注意:

(1)字符串的结束符‘\\0’占内存空间,但在测试字符串长度时不计在内,也不输出。

(2)‘\\0’为字符串的结束符,但遇到‘\\0’不一定是字符串的结束,可能是八进制数组成的转义字符常量,如字符串“abc\\067de”表示6个字符,并非为3个,因?\\067?为一个转义字符。

例1.20 求字符串?m\\x42\\\\\\tp\\101qy?的长度。

解析:\\x42、\\\\、\\t、\\101分别代表一个字符,因而此字符串的长度为8。可以用以下程序在机器上测试此字符串的长度。

#include

#include /*字符串长度测试函数strlen在string.h 库中*/ void main() { int x;

x=strlen(\printf(\}

输出结果为:x=8

第1章 C程序设计基础

? 本章重点

1.C语言程序的结构。 2.变量与常量的表示方法。 3.运算符与表达式。

4.指针的概念及变量地址与指针的关系。 5.指针与数组的初步基本概念。

? 本章难点

1.C语言中常量的表示方法。 2.整型数在计算机中存储的形式。 3.不同类型数据的转换。 4.转义字符。

5.各种运算符与表达式的正确理解。 6.指针的运算与数组的赋值。

1.1 C程序的结构

1.1.1 程序的概念

程序是指人们将需要计算机做的工作写成一定形式的指令,并把它们存储在计算机的内部存储器中。当人们给出命令之后,它就按指令操作顺序自动进行,把这种可以连续执行的一条条指令的集合称为“程序”。目前,正在使用的计算机程序设计语言有上百种,有些语言是面向机器的,如二进制语言,而多数是面向问题的语言。面向问题的语言都被称为计算机的“高级语言”,如C语言等。当然把C++等称为面向对象的语言。这些语言都是用接近人们习惯的自然语言和数学语言作为语言的表达形式,人们学习和操作起来感到十分方便。目前的程序设计一般可分为非结构化程序设计、结构化程序设计和面向对象的程序设计,C语言是结构化程序设计语言。

程序设计的过程一般包括:

(1)问题的提出、要求及所采用的数据结构。 (2)算法的确定、程序的编制。 (3)程序的调试及修改。

2 C语言程序设计 (4)整理并写出文档资料。

结构化程序设计由三种结构组成:顺序结构、选择结构、循环结构。

(1) 顺序结构:顺序结构的程序是一条语句接一条语句顺序地往下执行的。例如

在图1.1中,先执行语句1,然后执行语句2,最后执行语句3,顺序结构的程序是最简单的程序。

图1.1 顺序结构的程序段

语句1 语句2 语句3 (2)

分支结构:若在程序执行过程中,程序的流程可由多路分支组成,根据不同

的条件去执行不同的任务。例如在图1.2中程序执行到条件表达式时,首先判断条件是否为“真“,如为真执行语句1,否则执行语句2。

假 条件真 语 句2

图1.2 分支结构的程序段 (3)

语句1

循环结构:如在程序中需要根据某项条件重复地执行某项任务若干次或直到满足或不满足某条件为止,这就构成循环结构。例如在图1.3中程序执行到循环条件表达式时,首先判断循环条件是否为“真“,如循环条件为“真“,执行循环语句,循环语句执行完成后,又转去判断循环条件,如循环条件仍为真,再次执行循环语句,如此反复,直到循环条件为假,退出此循环。

思考:同学起床后,先穿衣、洗脸、吃饭,然后看看课表,根据课表带上所需的课本,去教室,上午上五节课,先上一节课,还没到五节课,再上一节,还没到五节,再上一节课,......,直到五节课上完,

第1章 C程序设计基础

3 早上的学习任务结束。根据此段话,用程序流程来分析的话,经历了哪些程序结构?请画出程序流程图。 假 循环条件真 循 环 语 句

图1.3 循环结构的程序段

用C语句所写的序列称为C源程序,它的后缀为.c,C源程序经过编译(compile)后生成一个后缀为.obj的二进制文件,最后由连接程序(link)把此.obj文件与C语言提供的各种库函数连接起来生成一个.exe文件,它就是可执行文件。

因而程序的设计过程如图1.4所示。

问题的提出及分析 确定该问题的算法 用C语言描述算法建立C语言源程序 编译生成.obj文件 连接有关库函数后生成.exe文件 运行程序并输出正确的结果 图1.4 程序的设计过程

1.1.2 C函数的构成

C语言是结构化的程序设计语言,C程序由一个或多个文件组成,而一个文件可由一个或多个函数组成。C程序中必须有一个函数名为main的函数,且只能有一个main函数。程序运行时从main函数开始,最后回到main函数。

C语言源程序可由一个或一个以上文件组成,而每个文件至少有一个函数,函数是C语言的最基本的单位。

C函数由语句构成,语句结束符用“;”表示,语句由保留字、标识符、运算符和表达式构成。其中“{”和“}”分别表示函数执行的起点与终点或程序块的起点与终点。

C程序中书写格式自由,一行内可写几个语句,但区分大小写字母。用C语言写成的函数结构图如1.5所示。

4 C语言程序设计 类型 函数名(形式参数声明) 函 数 体 数据声明部分 语句部分 图1.5 C函数定义的结构示意图

例1.1 函数结构的例子。

int add(int x,int y) /*函数返回值类型、函数名及形式参数的声明*/ { /*函数体开始*/

int z; /* 数据定义部分,给变量分配内存空间*/ z=x+y; /*执行语句*/

return z; /*函数结束前返回一个整型值*/ } /*函数体结束*/

在程序中可以对程序进行注释,注释的目的主要是为了人们能读懂您的程序。注释部分必须用符号“/*”和“*/”来界定,“/”和“*”之间不可以有空格。注释可以用西文,也可以用中文。注释可以出现在程序中任意合适的地方,注释部分对程序的运行不起作用。在注释中可以说明变量的含义、程序段的功能,以便帮助人们阅读程序。因此一个好的程序应该有详细的注释。

在上例中,如要在机器上运行必须要有一个main函数,通过main调用函数add函数,例如完整的程序代码为:

#include /*文件预处理,包含标准输入输出库,程序可调用输入、输出函数*/ int add(int x,int y) { int z; z=x+y; return z; } void main( )

{

int add(int,int); /* 函数的说明,告诉系统在主函数中要调用add函数 */ int a=1,b=2,c; /* 变量的定义*/ c=add(a,b); /* 函数调用 */ printf(\

/* 调用系统输出函数printf,%d为格式控制符,依次用后面的变量值填充,以整数形式输出 */ }

此程序的执行结果如下:

1+2=3

分析:程序执行的步骤:

1) 从main函数中的符号?{?开始执行;

第1章 C程序设计基础

5 2) 分配三个变量a、b、c的存储空间,并给a、b赋初值,分别为1、2,如图所示;

main函数中变量 a b c 1 2 图1.6 main函数中变量

3) 调用add函数,此时实在参数a、b的值传递给add函数中的形式参数x、y,此时

x的值为1、y的值为2;

4) 在add函数中给变量z分配内存空间;

add函数中变量 x y z 1 2 图1.7 add函数中变量

3

5) 在add函数中,形参x与y的和赋给形参变量z;

6) 返回形参z的值给main函数中的变量c,同时释放形式参数x、y、z的内存空间; 7) 在main函数中输出变量a、b、c的值。 8) 当遇?}?时程序执行结束。

请读者仔细思考,有关问题将在以后学到。 思考:编写一个程序,main函数中定义三个整型数x、y、z,并分别给x、y赋初值10、20,调用函数f返回x与y的乘积。 良好的编程风格有助于对程序的阅读、理解和记忆,因而编程时应养成良好的习惯,并注意以下各点:

(1)用“;”作为语句的结束记号,但main()、#include< >、#define不是语句,后面不能用“;”号。

(2)注解“/*”和“*/”及程序或复合语句的开始与结束“{”和“}”必须成对使用。

(3)程序中代码区分大小写。

(4)要有预处理,如 #include、#include、#include等。 (5)程序中必须有一个main函数,且只能有一个main函数。 (6)函数中定义的变量,含形式参数的作用范围只限在本函数内。

6 C语言程序设计 1.2 最简单的C程序

C语言程序可由表达式、系统函数及自定义函数组成,程序可以很复杂,也可以很简单,但即使很简单的程序也应由main()及“{”、“}”组成,例如:

例1.2 最简单的C程序。

/*最简单的C程序*/ #include void main( ) { ; }

此程序没有什么意义,执行后什么也没做,可以认为是最简单的C程序了。 例1.3 字符串的输出。

/*功能 打印字符,在屏幕上输出:Hello,world */ #include void main() {

printf(\ /*调用系统函数printf,\\n为换行符*/ }

此程序执行后在屏幕上输出:

Hello,world

在C语言中,printf为格式输出函数,它是C语言的库函数。包含在stdio.h库中,因而凡是用到printf函数都要包含函数库stdio.h。在此函数中,除了格式控制符外,其他字符原样输出,因而此程序的运行结果为:Hello,world。

思考:编写一个程序在屏幕上显示: ************************* C语言的学习要努力! *************************

下面用一些例子来说明此printf函数在整型数、实型数、字符输出方面的应用。 例1.4 整型数输出的例子。

/*功能 输出整型数 */ #include void main() {

int x=2; /* 定义一个整型数x,并赋予初值2 */

第1章 C程序设计基础

printf(\* printf为输出函数,%d为整型数的输出格式 */ }

7 此程序执行后在屏幕上输出:

2 5

在此例子中,语句int x=2; 表示定义一个整型x,并赋予初值2。为什么在程序设计中要定义变量后才能使用呢?这是因为变量的数值存放在内存空间,因而必须给变量分配存储空间,而变量的定义就是给变量分配存储空间。

在程序设计中,经常要通过键盘输入,显示器输出。在C语言中用于格式输入、输出函数分别为scanf、printf ,它们常用格式有:

%d 用于十进制的输入、输出。 %f 用于实型数的输入、输出。 %lf 用于双精度数的输入、输出。 %c 用于字符的输入、输出。 %s 用于字符串的输入、输出。 更详细的一些细节见附录。

思考:初始化两个双精度变量,并输出这两个变量值的程序。 提示:初始化表示定义变量的同时给变量一个最初的值,例:double x=10.2 , y=20;输出格式为:%lf 输出语句可写为:printf(“x=%lf y=%lf\\n”,x,y); 例1.5 从键盘输入一个双精度数,然后输出。

/*功能 从键盘输入一个双精度数,然后输出 */

分析:C语言中用于格式输入的函数为:scanf(“格式符序列”,变量地址序列); 变量的地址表示为:&变量名;

因而程序在设计时先定义一个双精度数:double x;然后用语句:scanf(\输入。 #include void main( ) {

double x ;

scanf(\ /* &x 表示变量x的地址 */ printf(\}

程序在运行时会出现一个空屏,此时您应输入一个数据,然后按回车键后在屏幕上输出结果。 思考:定义两个整型数,值从键盘读入,输出这两个数的差的程序。 提示:假定定义的两个变量为x、y,键盘输入语句为:scanf(“%d %d”,&x,&y);键盘输入时两个整型之间用空格隔开。 输出语句为:printf(“%d-%d=%d\\n”,x,y,x-y); 例1.6 从键盘输入一个字符串,然后输出的程序。

8 C语言程序设计 解析:在程序中先定义一个字符数组,然后提示输入,输入一个字符串后,最后输出在屏幕上。

分析:C语言中可用于存放字符串的为字符数组,字符数组的定义为: char 数组名[元素个数] ; 例:char name[10];它表示在内存中分配10个字节的连续空间,这个连续空间的首地址用name表示。

/*功能:从键盘输入一个字符串,然后输出字符串的程序 */ #include void main() {

char name[10] ; /* name表示存放字符串的首地址,可存放10个字符*/ printf(\请输入您的姓名\\n\* 屏幕输出 */

scanf(\/* 键盘读入字符串,以空格分隔,格式符为%s */ printf(\您的姓名是:%s\\n\

/*表示输出以name为首地址上的内容,直到字符串结束*/

}

程序运行结果如图1.8所示。

图1.8 程序运行结果

注意:

(1) char name[10] ;表示定义一个字符数组,它可以存放10个字符,name表示内存空间的首地址,数组的元素可用name[i]表示,其中10>i≥0。

(2)当用格式符%s时,对应的参数为字符变量的地址,表示输出以此地址上的内容开始,直到字符串结束。 思考:定义一个能存放20字符的字符数组,屏幕提示?请输入您的家乡:?,如键盘输入?山东济南?,此时程序输出:?您来自:山东济南?,请编写此程序。 提示:假定字符数组定义为:char str[20]; 键盘读入语句可写成:scanf(“%s”,str); 输出语句为:printf(“您来自:%s\\n”,str);

第1章 C程序设计基础

9 1.3 标识符与保留字

在C语言中,标识符可用作变量名、符号名、函数名、数组名、文件名以及一些具有专门含义的名字。合法的标识符由字母、数字和下划线组成,并且第一个字符必须为字母或下划线,不能跨行书写,自定义标识符不能与关键字同名。下面的标识符都是合法的:

are、PI、liu_123、liu、e_array; 以下都是非法的标识符: 456P、cade-y、w.w、a&b

C语言的标识符可以分为3类:保留字、预定义标识符、用户自定义标识符。 1.3.1 保留字

保留字也叫关键字,在C语言中用来表示某种特点含义的英文单词,如include、int、char、for等,关键字含义特定,不允许随意书写或拼写错误 。它们不能再用作变量名或函数名。

例:C语言中的关键字有:

auto、break、case、char、const、continue、default、do、double、else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedef、union、unsigned、void、volatile、while。 1.3.2 标识符

1.预定义标识符

有些标识符在C语言中都有特定的含义,如C语言提供的库函数的名字(printf)和预编译处理命令(如define)等。C语言语法允许用户把这类标识符另作它用,但这将使这些标识符失去系统规定的原意。为了避免误解,建议用户不要把这些预定义标识符另作它用。

2.用户标识符

由用户根据需要定义的标识符称为用户标识符。一般用来给变量、函数、数组或文件等命名。程序中使用的用户标识符除要遵循命名规则外,还应注意做到“见名知义”,即采用具有相关含义的英文单词或汉语拼音,以增加程序的可读性。

如果用户标识符与关键字相同,程序在编译时将给出出错信息;如果与预定义标识符相同,系统并不报错,只是该预定义标识符将失去原定含义,代之以用户确认的含义;或者会引发一些运行时错误。

例1.7 下列各组字符序列中,可用作C语言程序标识符的一组字符序列是( )。 (A)S.b,sum,average,_above (B)Class,day,lotus_1,2day (C)#md,&12x,month,student_n1 (D)D56,r_1_2,name,_st_1

解析:C语言规定标识符只能由字母、数字和下划线三种字符组成,而且第一个字符

10 C语言程序设计 必须是字母或下划线。因而答案D是正确的。

1.4 常量

在程序运行过程中,其值不能被改变的量,称为常量。在C语言中,常量有不同的类型,有整型常量(int),实型常量(float或double),字符常量(char)和字符串常量。即使是整型常量也还有短整型(short int)、长整型(long int)和无符号型(unsigned int)等等。 1.4.1 整型常量

整型常量的定义格式:

int const 常量名=常量值; 或:const int 常量名=常量值; 例如:int const x=10;

基本整型常量只用数字表示,不能带小数点,如:12、-l、0等都是合法的整型常量。应该注意常量的值一旦指定,在程序中就不能再改变,在上例程序中如果您试图改变x的值,编译器就会报错。

整型常量通常可分为十进制、八进制和十六进制常量。

十进制常量用一串连续的数字来表示,如:32767、-32768、0等。

八进制常量用数字0开头。如: 05、012、01都是八进制数,它们分别代表十进制数5、10、1。

十六进制常量用数字0和字母x(或大写字母X)开头。如:0x10、0xff、0X8均是十六进制数,它们分别代表十进制数的16、255、8。

注意:

(1)十六进制数只能用合法的十六进制数字表示,字母a、b、c、d、e、f既可用大写字母也可用小写字母。

(2)常量的长度及表示数据的范围通常与机器类型有关。 例1.8 在C语言中,错误的int类型的常数是( )。

(A)32 (B)078 (C)037 (D)0xAF

解析:选项A为int型数,选项B应该为八进制数,而八进制数中无8,选项C为八进制,选项D为是十六进制,所以答案为B。 1.4.2 实型常量

实型常量定义:float const 常量名=常量值; 例如:float const x=2.1;

实型常量也称数值型常量,它们有正值和负值的区分。实型常量通常用带小数点的数字及指数形式表示,如:3.14159、2.71828、0.0、.54、0.3e2等。

第1章 C程序设计基础

11 1.4.3 字符常量

字符常量定义:char const 常量名=常量值; 例如:char const ch=‘A’;

字符常量用单引号括起来,例‘A’是字符型常量,而字符串常量用双引号括起来,例“asfgTYN”是合法的无名字符串常量。

由此可见,常量的类型从字面形式即可区分是整型常量、字符型常量还是实型常量。C编译程序就是以此来确定数值常量的类型的。

可以用一个符号名来代表一个常量,但是这个符号名必须在程序中进行特别的“指定”,即符号常量。

例1.9 下列常量中,不能作为C语言常量的是( )。

(A)0xA5 (B)2.5e-2 (C)57 (D)?ab?

解析:D用单引号的应为字符常量,字符常量只能是单个字符,但D包含了2个字符,所以答案为D。

例1.10 下列形式的常数,在C程序中不允许出现的是( )。 (A).45 (B)±123 (C)25.6e-2 (D)4e3

解析:C程序允许出现的常数为一个确定的整数、实数(可用小数形式或指数形式)等。±123不允许出现。答案:B。

1.5 变量

变量是指在程序运行过程中,其值可以发生变化的量。变量通常是用来保存程序运行过程中的输入数据、计算获得的中间结果和最终结果。变量的取名规则与用户标识符相同,给变量取名时,为了便于阅读和理解程序,一般都采用代表变量的含义或用途的标识符。

当程序运行时,每个变量都要占用连续的若干个字节,所占用的字节数由变量的数据类型及机器确定。其中第1个字节的地址称为变量的地址。C语言规定,程序中变量的地址是用“&变量名”来表示的。 1.5.1 变量的数据类型及其定义

C语言规定,变量可以是任何一种数据类型。例如,整型、短整型、长整型、无符号整型、无符号短整型、无符号长整型、单精度型、双精度型、字符型等基本类型,也可以是数组型、结构型、共用体型等构造类型和指针型、枚举型。

通常把具有某种数据类型的变量叫做该类型变量。例如,短整型变量、长整型变量、单精度型变量、双精度型变量、字符型变量等等。基本数据类型符及其含义如表1.1所示。

表中,整型和无符号整型所占用的字节数是随计算机的不同而不同的,在大部分计算机上都是和短整型占用相同的字节数。需要注意的是,字符串只能是常量,C语言中没有字符串变量。被定义为整型数的变量,若其值在0~127之间,可以当作字符型变量使用。

12 C语言程序设计 每个变量在使用前都必须定义,定义的含义是给变量分配存储空间。

表1.1 基本数据类型符(Visual C++6.0)

数据类型 整型 短整型 长整型 无符号整型 无符号短整型 无符号长整型 单精度实型 双精度实型 字符型 数据类型符 int short long unsigned int unsigned short unsigned long float double char 占用字节数 4 2 4 4 2 4 4 8 1 定义变量的格式如下:

数据类型符 变量名1,变量名2,?, 变量名n; 例如: int x ; int y; 或等效为: int x , y ;

注意

(1)定义变量的语句必须以“;”号结束,在定义变量的一个语句中也可以同时定义多个变量,变量之间用逗号隔开。

(2)对变量的定义可以在函数体之外,也可以放在函数体中或复合语句中。 例如:定义两个整型变量及一个字符变量可写为:

int x,y; char ch;

例1.11 变量的定义及输出的例子。

#include void main( ) {

int x=2,y; /*定义x、y为整型变量,并赋x的初值为2 */ y=3; /* 并赋y的值为3 */ printf(\}

1.5.2 变量的存储类型

当说明了一个变量的数据类型,C语言编译系统就要给该变量安排若干个字节,用来存放该变量的值。在计算机的寄存器和内存中都可以存放数据,而内存中又可以分为一般数

第1章 C程序设计基础

13 据区和堆栈区。把变量存放在何处称为变量的存储类型。用户可以通过说明变量的存储类型来选择变量的具体存储地点。

定义变量存储类型的语句格式如下:

存储类型符 数据类型符 变量名1,变量名2,?; 存储类型符及其含义如表1.2所示。

表1.2 存储类型符表

存储类型 自动型 寄存器型 静态型 外部参照型 存储类型符 auto register static extern 存储地点 内存堆栈区 CPU的通用寄存器 内存数据区 内存静态存储区 1.自动型auto

自动型又称堆栈型。自动型变量是分配在内存的堆栈区。堆栈区内存在程序运行中是重复使用的。当在某个函数中定义了自动型变量,C语言就在堆栈区中给该变量分配字节,用于存放该变量的值。当退出该函数时,C语言就释放该变量,即从堆栈区中收回分配给该变量的字节,以便重新分配给其他自动型变量,这样做的目的是节省内存。

用户对于只在某函数中使用的变量应该将其定义成自动型变量,以便充分利用内存。当定义自动型变量时,通常省略存储类型符auto。

2.寄存器型register

寄存器型变量是分配在CPU的通用寄存器中。由于CPU具有的通用寄存器数量有限,C程序中允许定义的寄存器型变量一般以2个左右为宜。如果定义为寄存器型变量的数目超过所提供的寄存器数目,编译系统自动将超出的变量设为自动型变量。对于占用字节数多的变量,如long、float、double类型的变量不能定义为寄存器型变量。

寄存器型变量一般是在函数中定义的,退出该函数后就释放它所占用的寄存器。

3.静态型static

静态型变量是分配在内存的数据区中,它们在程序开始运行时就分配了固定的字节,在程序运行过程中不释放。只有程序运行结束后,才释放所占用的内存。

4.外部参照型extern

C语言允许将一个源程序清单分放在若干个程序文件中,采用分块编译方法编译生成一个目标程序。其中每个程序文件称为一个“编译单位”。

外部参照型变量是专门用于多个编译单位之间传递数据用的。当编译单位甲中要使用在编译单位乙中已定义的变量,则在编译单位甲中就要说明该变量是外部参照型,以便C语言编译系统在编译单位甲之外的其他编译单位中寻找该变量的定义。将某个变量说明为其他编译单位定义的变量的方法就是将它说明为“外部参照型”。被说明成外部参照型的变

14 C语言程序设计 量的存储类型和数据类型都由定义该变量的那个编译单位来说明。 1.5.3 整型数在计算机中的存储方式

计算机中,内存储器的最小存储单位称为“位(bite)”,每一个位中或者存放0,或存放1,因此称为二进制位。大多数计算机把8个二进制位组成一个“字节(byte)”,并给4个字节分配一个地址。若干字节组成一个“字(word)”,用一个字来存放一条机器指令或一个数据。一个字含多少个字节随机器而不同。如果一台计算机系统字长为4个字节(l个字节为8个二进制位),就称这台计算机的字长为32位。

一个字节有8个二进制位,本书中把最右边的一位称为最低位,把最左边的一位称最高位。在C语言中,一个int数通常用两个字节存放。其中最高位(最左边的一位)用以存放整数的符号。若是正整数,最高位放置0;若是负整数,最高位放置1。因此,从最高位就立刻能判别出存放的一个整数是正整数还是负整数。

在Visual C++环境中,当用四个字节存放一个整数时,例如整数5在内存中的二进制码为:

0000 0000 0000 0000 0000 0000 0000 0101 对于正整数的这种存储形式称为用“原码形式”存放。因此用两个字节存放的最大正整数是:

0111 1111 1111 1111 1111 1111 1111 1111 它的值为231-1。为简单起见,对于整数如用二个字节表示,把5表示成

0000 0000 0000 0101 在计算机中,对于负整数在内存中是以“补码”形式存放的。求某个二进制码的补码,步骤如下:

(1)求原码:

把数的绝对值用二进制表示,最高位用于表示符号,0表示正数,1表示负数。 (2)求反码。除符号位外把1转换成 0,把0转换成l。 (3)把所求得的反码在最低位加l,结果即为所求的补码。

例1.12 求十进制整数-5在计算机中的存储形式。

分析:在计算机中数是以补码的形式表示的,因而先计算: -5的原码:5的二进制表示为: 0000 0000 0000 0101 最高位用于表示符号,所以-5原码为: 1000 0000 0000 0101 -5的反码:除符号位外,按位取反,即得-5反码为: 1111 1111 1111 1010 -5的补码:所求得的反码加l,即得-5补码为:

1111 1111 1111 1011

第1章 C程序设计基础

思考:有程序段: int x=-2; printf(“%d %x\\”,x ,x); 问执行程序后的输出。 15 提示:十六进制格式%x输出,是以整型数在内存中的形式按四个二进制位输出一个十六进制位,因而应分析-2在内存中的存放形式。 例1.13 要把内存中以补码形式存放的二进制码 1111 1111 1111 1011 转换成十进制整数。

解题步骤如下:由于对负数的补码求补即为原码。 (1)除符号位外,先对补码 1111 1111 1111 1011 按位取反,取反后为

1000 0000 0000 0100 (2)将最低位加1得

1000 0000 0000 0101 (3)除最高位外的二进制数转换成十进制数,因最高位仍表示符号位。得:

1000000000000101的十进制数为-5。 由以上分析可知,由两个字节存放的最小负数是 1000 0000 0000 0000 它的十进制数为-32768;而-1的二进制代码为 1111 1111 1111 1111 用两个字节存放一个整数时,若说明为无符号整数,其中最高位不再用来存放整数的符号,8个二进制位全部用来存放整数,因此无符号整数不可能是负数,这时16个二进制位中全是1时,它所代表的整数就不再是-1而是65535。

例1.14 以下程序段,则b、c的值是( )。

long a=0xffffff; int b;char c; b=a; c=’b’+b;

(A)0xffffff和0x61 (B)-1和98

(C)-1和97 (D)指向同一地址

解析:由于a为长整型,在微机中前者为32位,后者为16位。在将a的值赋给变量b时,系统会自动截断,b的值为-1,而字符'b'的ASCII码为98,因此c的ASCII码值为97。答案(C)。

例1.15 以下程序的输出结果为( )。

第1章 C程序设计基础

21 1.6 变量与地址

若在程序中定义了一个变量,这个变量在内存中的地址也就确定了。C语言中所说的每个变量的地址是指该变量所占存储单元中第一个字节的地址。每一个变量都对应一个或几个存储单元,也就有一个存储单元的首地址与之相对应,这个地址称为“变量的地址”,计算机根据地址对变量进行操作。

例如:

int a = 10,b = 20 ; long int c =3000;

变量a、b、c的地址分别用&a、&b、&c表示。

注意:

变量的地址由操作系统给定,非人为所定。即把某个地址赋给变量地址是错误的,如语句:&a=2000H;是非法的。但是一旦定义一个变量后,可以得到这个变量的地址。 例1.21 当程序中定义某个变量j后,用以下程序可以输出变量j的地址。

#include void main() { int j;

printf(\ }

思考: 地址输出格式中可用十六进制或无符号数,而不用十进制数形式。 注意:

(1)求地址运算符‘&’只能应用于变量和以后将要介绍的数组元素,不可以用于表达式、常量或者被说明为register的变量。

(2)变量之间的地址可能是连续的,也可能是不连续的,请分析以下程序。 例1.22 变量的地址举例。

#include void main() {

int a=1; char b='a'; float c=5.6; double d=3.2;

22 printf(\printf(\printf(\printf(\}

C语言程序设计 运行程序后请思考:

(1)程序运行后变量a、b、c、d的地址如何?

(2)变量a、b、c、d的地址是否存储在一个连续的空间。 (3)再次运行时的地址与前一次是否相同。

1.7 运算符与表达式

在C语言中基本运算符有算术运算符、关系运算符、逻辑运算符、位运算符、自反运算符、逗号运算符、条件运算符等。算术运算符有:+、-、*、/、%,分别为加、减、乘、除、求余运算符。这些运算符需要两个运算对象,称为双目运算符。除求余运算符外,运算对象可以是整型,也可以是实型。

求余运算符的运算对象只能是整型数。在“%”运算符左侧的运算数称为被除数,右侧的运算数称为除数,运算结果是两数相除后所得的余数。当运算对象为负数时,所得结果的符号随机器而不同,在Visual C++6.0中,符号与被除数相同。

例1.23 余数符号举例。

#include void main() {

printf(\}

程序运行的结果为: 2 2 -2 -2

注意:

(1)双目运算符两边运算数的类型必须一致才能进行操作。所得结果的类型与运算数的类型一致。

(2)如果双目运算符两边运算数的类型不一致,如一边是整型数,另一边是实型数时,系统将自动把整型转换为实型数,使运算符两边的类型达到一致后,再进行运算。

例如:

1/2.0;表达式1/2.0自动把1转化为1.0,然后再运算1.0/2.0;其运算结果为0.5。而表达式l/2;由于类型相同,运算结果为整型数,其值为0。

第1章 C程序设计基础

23 1.7.1 赋值运算符及赋值表达式

在C语言中,“=”符号称为赋值运算符,由赋值运算符组成的表达式称为赋值表达式, 它的形式如下:

变量名=表达式;

或,变量名1=变量名2=变量名3=??=变量名n=表达式;

赋值号的左边必须是一个代表某一存储单元的变量名,或是代表某存储单元的表达式,对于初学者来说,只要记住等号左边必须是变量名即可。赋值号的右边必须是C语言中合法的表达式。

赋值运算的功能是先求出右边表达式的值,然后把此值赋给等号左边的变量,确切地说,是把数据放入以该变量为标识的存储单元中去。

在程序中可以多次给一个变量赋值,因此每赋一次值,与它相应的存储单元中的数据就被更新一次,内存中当前的数据就是最后一次所赋的那个数据。

注意:

(1)赋值运算符的优先级别只高于逗号运算符,比其他任何运算符的优先级都低,且具有自右向左的结合性。因此,对于如下的表达式:

a=2+7/3;

先计算赋值运算符右边表达式的值,再把此值赋给变量a。

(2)赋值运算符不同于数学中的等于号?=?,这里不是等同的关系,而是进行?赋予?的操作。赋值表达式x=y的作用是:将变量y所代表的存储单元中的内容赋给变量x所代表的存储单元,赋值后,y变量中的内容保持不变。读作?把y的值赋予x变量?,而不应读作?x等于y?。 (3)赋值表达式x=x的含义是取变量x中的值放入到变量x中去,表达式n=n+l是合法的赋值表达式,其作用是取变量n中的值加1后再放入到变量n中,即,使变量n中的值增1。

(4)赋值运算符的左侧只能是变量不能是常量或表达式。如4+b=c是不合法的赋值表达式;赋值号右边的表达式也可以是一个赋值表达式,如c=b=7+l,按照运算符的优先级进行运算。 1.7.2 表达式类型的转化

如果运算符两侧的数据类型不一致,在赋值前,系统将自动先把右侧表达式求得的值,按赋值号左边变量的类型进行转换,也可以用强制类型转换的方式人为地进行转换。在这里,特别需要指出的是:在进行混合运算时,整型数据类型之间的转换问题。

1.表达式类型的自动转化

在C语言的表达式中(不包括赋值表达式),如果运算符两边的整数类型不相同,将进行类型之间的转换。转换规则如下:

24 C语言程序设计 (l)运算符两边一个是短整型,一个是长整型,则短整型转换成长整型,然后进行运算。 (2)运算符两边一个是有符号整型,一个是无符号整型,则有符号整型转换成无符号型,然后进行运算。

在C语言的赋值表达式中,赋值号右边的值先转换成与赋值号左边的变量相同的类型,然后进行赋值。

注意:

当赋值号左边的变量为短整型,右边的值为长整型时,短整型变量只能接受长整型数的低位上两个字节中的数据,高位上两个字节中的数据将丢失;也就是说,右边的值不能超出短整型的数值范围,否则将得不到预期的结果。 例1.24 无符号数转化为有符号数的例子。

#include void main() {

short int a; unsigned long b; b=98304;

a=b; /*长整型数b赋值给短整型数a*/ printf(\,a); }

程序运行后输出为: a=-32768

解析:无符号数b在内存中占4字节,在内存中表示为: 0000 0000 0000 0001 1000 0000 0000 0000 a为2字节,b赋给a,高位上两个字节中的数据将丢失,a在内存中的表示为:

1000 0000 0000 0000 则a中的值为-32768。 注意:

当赋值号左边的变量为无符号整型数,右边的值为有符号整型数时,把内存中的内容原样复制。赋值号右边数值的范围不应该超出左边的变量可以接受的数值的范围。同时需要注意,这时负数将转换为正数。

例如:变量b被说明为unsigned类型,在将a的值-1赋给b后,将使b中的值变为4294967295。

例1.25 有符号数转化为无符号数的例子。

#include void main( ) {

short int a=-1;

第1章 C程序设计基础

unsigned long b; b=a;

printf(\}

25 2.表达式类型的强制转换

强制类型转换表达式的形式如下: 转换格式:(类型名)<变量>;

其中(类型名)称为强制类型转换运算符,可以利用强制类型转换运算符,将一个表达式的值转换成指定的类型,这种转换是根据人为要求而进行的。

例1.26 表达式类型强制转换的例子。

#include void main() {

float x; int i; x=3.6; i=(int)x;

printf(\}

结果为:x=3.600000,i=3

注意:语句i=(int)x;把x强制转换后的结果赋给i,而x本身的类型并不改变。

例1.27 设x=2.5、a=7、y=4.7,算术表达x+a%3*(int)(x+y)%2/4的值为( )。 (A)2.5 (B)7 (C)4.7 (D)2.75

解析:取模运算只能在整型数据之间进行,a为整型变量。因为%、*、/这三个运算符的优先级别相同,而类型转换符优先于*、/运算符,a的值为7,7%3=1,又因为(int)(2.5+4.7)=7,1*7=7,7%2=1,1/4=0,所以表达式x+a%3*(int)(x+y)%2/4=x+0=2.5。答案:A。

1.7.3 自反算术赋值运算

在C语言中,如进行某一类运算: i=i+1;或j=j*(x+1);

在C语言中可以分别表示为:i+=1; j*=x+1;把这类运算称为自反算术赋值运算。其格式为:

<变量><运算符>=<表达式> 它等效为:

<变量>=<变量><运算符><表达式> 例如:

a+=表达式; 等效为:a=a+(表达式);

26 C语言程序设计 a-=表达式; 等效为:a=a-(表达式); a*=表达式; 等效为:a=a*(表达式); a/=表达式; 等效为:a=a/(表达式); a%=表达式; 等效为:a=a%(表达式);

注意:

y*=a+b;应等价于y=y*(a+b);而不是:y=y*a+b; 例1.28 分析以下程序执行的结果。

#include void main() {

int a=10;

a/=a+a; /*此表达式等效为a=a/(a+a) */ printf(\}

解析:先做a+a为20,然后做a=a/20;由于在a/20中都为整型,不作类型转换,即a=0,所以执行的结果为0。 1.7.4 连续赋值运算

在C语言中,可以对变量连续赋值,其格式为: <变量1>=<变量2>=??<变量n>=<表达式>;

先计算<表达式>值,再将其值赋给<变量n>,从右到左。 例如:a=b=c=1等效于a=(b=(c=1)); 例如:int a=1,b=2;

a+=b+(c=8); 求a的值。

解析:8赋给c,b+a+c赋给a,所以a的值为11。

例1.29 如有定义:int a=12 ; 求表达式a+=a-=a*=a的值为( )。 (A)12 (B)144 (C)0 (D)132

解析:表达式a+=a-=a*=a的运算方向是自右向左,即先计算a*=a,a值为a*a=144,再计算a-=a,a值为a-a=0,再计算a+=a,故表达式和a的值都为a+a=0。答案:C。 1.7.5 自加++、自减运算--

自加运算符“++”和自减运算符“--”的运算结果是使运算对象的值增1或减1。如: i++; 相当于 i= i+l; i--; 相当于 i= i-l;

因此,自加或自减运算本身也是一种赋值运算。

注意:

第1章 C程序设计基础

27 (1)自加、自减运算符是单目运算符,运算对象可以是整型变量,也可以是实型变量,不能是常量和表达式,因为不能给常量或表达式赋值;因此,如++3、(i+j)++等都是不合法的。

(2)自加、自减运算符既可做为前缀运算符,也可做为后缀运算符而构成一个表达式,如++i、i--等都是合法的表达式。但无论是作为前缀,还是作为后缀运算符,对于变量本身来说自增1或自减1都具有相同的效果,但作为表达式来说却有着不同的值。

例1.30 分析程序的执行结果。

#include void main() {

int i,j=10; i=j++;

printf(\}

解析:在语句i=j++;中要做两件事,一是自增,二是赋值,而++为后缀,此语句相当于:i=j,j++;先赋值后自增,因而i的值为10,j的值为11。程序运行的结果为:

i=10 j=11 。

注意:

++和--运算符的结合方向是?自右至左?。

例如,如有定义:int i=3;执行语句j=-i++;后,求i,j的值。在此语句中,i左边是负号运算符,右边是自加运算符。负号运算符和自加运算符优先级相同,但结合方向为自右至左。即相当于对表达式j=-(i++)进行运算。但此时读者不要错误理解为先做括号,此时括号只不过表示i与++相结合,它与运算的优先级是两码事。因而j的值为-3,i的值为4,此问题的程序设计为:

#include void main() { }

例1.31 分析程序的执行结果。

#include

int i=3,j; j=-i++;

printf(\

28 void main() {

int x=2 ,i; i=++x;

printf(\printf(\}

C语言程序设计 解析:++i是在使用i之前,先使i的值加1;i++是在使用i之后,使i的值加1。当执行语句i=++x;后i的值为3,因为此语句等同于++x,i=x;语句printf(\,\,++i);相当于++i;printf(\,\,i);i的值及输出均为4。语句printf(\,\,i++);相当于printf(\,\,i),++i;输出的值为4,i的值为5,不过程序运行后的结果为4,4。

思考: 请设计一个程序,检验以下说法,在int i=4; printf(“i=%d\\n”,i++); 输出为i=4,内存中i的值为5。 提示:可再次输出内存中i的值。 1.7.6 长度测试运算符sizeof

长度测试运算符sizeof可用测试某个类型变量所占用计算机内存空间的字节长度。

格式:sizeof(类型名) 例如下面的程序段:

int a;

a=sizeof(float); printf(\

其输出的值为4,因为它是测试float型的数据长度。在Visual C++6.0中一些基本类型的数据长度如下:

int : 4字节 char 1字节 short int 2字节 long int 4字节 float 4字节

double 8字节 思考: 编写一个程序,在Visual C++6.0环境下分别测试int、double型数据的长度。 1.7.7 逗号运算符与逗号表达式

“,”是C语言提供的一种特殊运算符。用逗号将表达式连接起来的式子,称为逗号表达式。

逗号表达式的一般形式为:

第1章 C程序设计基础

29 表达式1,表达式2,?,表达式n 注意

(1)逗号运算符的结合性为从左到右,因此逗号表达式将从左到右进行运算。即,先计算表达式1,最后计算表达式n。最后一个表达式的值就是此逗号表达式的值。

如:(i=3,i++,++i,i+5)这个逗号表达式的值是10,i的值为5。 (2)在所有运算符中,逗号运算符的优先级别最低。 例:x=5*8,6+9;x值为40,整个表达式值为15。 例:x=(i=10,j=5,i*j);x值为50,也是逗号表达式值。 (3)逗号表达式可以嵌套。 例:z=(x=0,(y=100,y*3+6),(x+9,y-27)) 解析:(y=100,y*3+6)值为306。

(x+9,y-27)值为73,也是整个表达式值。 1.7.8 关系运算

关系表达式其运算结果会得到一个逻辑值。逻辑值只有两个,在很多高级语言中,用“true”和“false”来表示真与假。在C语言中,没有专门的“逻辑值”,而是用非零值来表示“真”,用零表示“假”。因此,对于任意一个表达式,如果值为0时,就代表一个“假”值;只要值是非零,无论是正数还是负数,都代表一个“真”值。

关系运算是逻辑运算中比较简单的一种。所谓关系运算,实际上是“比较运算”,将两个数进行比较,判断比较的结果是否符合指定的条件。

1.C语言中的关系运算符

C语言提供了6种关系运算符,如表1.4所示。

表1.4 关系运算符

符 号 <(小于),> (大于),<= (小于或等于),>= (大于或等于) ==,!= (不等于) 优先级 高 低 注意:

(1)关系运算符为双目运算符,结合方向为自左至右。 (2)关系运算符的结果为真(1)或假(0),C语言中没有逻辑值。 (3)算术运算符高于关系运算符。 (4)判断两个数是否相等用双等号”==”

当关系运算符两边的值类型不一致时,若一边是整型,一边是实型,系统将自动把整

型数转换为实型数,然后进行比较。其类型转换规则,与附录二中所列双目算术运算中的类型转换规则相同。若x和y都是实型数,应当避免使用x==y这样的关系表达式。因为通

30 C语言程序设计 常存放在内存中的实型数是有误差的。因此不可能精确相等,这将导致关系表达式x==y的值总为0。

2.C语言中的关系表达式。

由关系运算符组成的表达式,称为关系表达式。关系运算符两边的运算对象可以是C语言中任意合法的表达式。

例如:c>a+b 等同于 c>(a+b)

a=b>c 等同于 a=(b>c) a>b!=c 等同于 (a>b)!=c

例1.32 下列程序运行后的结果为( )。

#include void main() { int x; x=10>5>3;

printf(\}

解析:关系运算符优先级高于赋值运算符,同样级别的关系运算符,运算方向从左到右。先判定10>5为真,结果为1。然后判定1>3为假,输出0。

例1.33 已知a=3、b=2、c=1,则表达式a>b==c的值为( )。 解析:此关系表达式中“>”的优先级高于“==”,相当于(a>b)==c,由a>b为真,其值为1,实际上判断1==1,结果为“真”用1表示。答案:1。 思考: 键盘输入两个整数,判断这两个数是否相等,如相等输出1,否则输出0。 提示:假设此两个数为a、b,考虑表达式c=a==b,它的运算情况是c=(a==b),先判断a与b是否相等,相等结果为1,再赋值给c。 1.7.9 逻辑运算

本小节介绍的逻辑表达式,其运算结果也会得到一个逻辑值1或0。 1.C语言中的逻辑运算符

C语言提供了3种逻辑运算符。逻辑运算符具有自左至右的结合性,表1.5列出了3种逻辑运算符的含义及运算级别。

表1.5 3种逻辑运算符的含义及运算级别

运算符 && 意 义 与 级 别 中

第1章 C程序设计基础

|| ! 或 非 低 高 31 其中,&&和||运算符是双目运算符,!运算符是单目运算符,应该出现在运算对象的左边,如:!a。

以上运算符的优先级次序是:!(逻辑非)级别最高,&&(逻辑与)次之,||(逻辑或)最低。逻辑运算符与赋值运算符、算术运算符、关系运算符之间从高到低的运算优先次序是:!(逻辑非)、算术运算、关系运算、&&(逻辑与)、||(逻辑或)、赋值运算,见附录。

2.C语言中的逻辑表达式

用逻辑运算符将关系表达式连接起来的表达式就构成逻辑表达式。逻辑运算的对象可以是C语言中任意合法的表达式。逻辑表达式的运算结果或者为1(“真”),或者为0(“假”)。

例:a>b&& x>y 等同于 (a>b)&&(x>y) a==b||x==y 等同于 (a==b)||(x==y) !a||a>b 等同于 (!a)||(a>b) 例1.34 逻辑表达式!(5>3)&&(2<4)的值为( )。 解析:该表达式相当于(!(5>3))&&(2<4)得0&&1结果为0。答案:0。

值得注意的是,在数学上关系式5>x>2表示x的值应在大于2、小于5的范围内。但在C语言中不能用5>x>2这样一个关系表达式来表述以上的逻辑关系。因为无论x是什么值,按照C语言的运算规则,表达式5>x>2的值总是0。只有采用C语言提供的逻辑表达式x>2&&x<5才能正确表述以上关系。

例1.35 已知year为整型变量,不能使表达式(year%4==0&&year%100!=0)||year%400==0的值为?真?的数据是( )。

(A)1990 (B)1992 (C)1996 (D)2000

解析:表达式为“真”时有两种情况:第一,year能被4整除,但不能被100整除;第二,year能被400整除。故在所选项中不符合上面两种情况的只有(A)。答案:A。 思考: 键盘输入一个字符给ch,如是大写字母或小写字母输出1,否则输出0。 提示:考虑表达式c=ch>=?a?&&ch<=?z?||ch>=?A?&&ch<=?Z?。 思考: 键盘输入三个整数,当三个整数相等时输出1,否则输出0。 提示:假设三个整数分别为a、b、c,考虑表达式d=(a==b)&&(a==c)。

在C语言中,应注意如有以下逻辑表达式:

a++&&b++

若a的值为0,表达式首先去求a++的值,由于表达式a++的值为0,系统完全可以确

32 C语言程序设计 定逻辑表达式的运算结果总是为0。因此将跳过b++不再对它进行求值。在这种情况下,a的值将自增,由0变成1,而b的值将不变。若a的值不为0,则系统不能仅根据表达式 a++的值来确定逻辑表达式的运算结果。因此必然再对运算符“&&”右边的表达式b++进行求值,这时将进行b++的运算,使b的值改变。又如以下逻辑表达式:

a++||b++

若初始a的值为1,表达式首先去求a++的值。由于表达式a++的值为1,无论表达式b++为何值,系统完全可以确定逻辑表达式的运算结果总是为1。因此也将跳过b++不再对它进行求值。在这种情况下a的值将自增1,b的值将不变。若a的值为0,则系统不能仅根据表达式a++=0的值来确定逻辑表达式的运算结果,因此必然再对运算符“||”右边的表达式b++进行求值,将进行b++的运算,使b的值改变。

例1.36 定义:int i=10,s=0;分别执行下列语句后,s和i的值是多少? s=++s||++i;

解析:因||的运算级较低,逻辑式||右边的表达式在最后运算,如||运算符的左边为真,其运算结果与右边无关,因而此时计算机不对右边的表达式进行运算。答案为:s=1,i=10。

例1.37 定义:int x=0,y=0,z=0;分别执行下列语句后,各变量的值是多少? ++x&&++y||++z;

解析:因||的运算级较低,逻辑式||右边的表达式在最后运算,它相当于:++x,++y,x&&y,如x&&y的值为假,再执行++z,x&&y的结果与z进行逻辑式||运算;如果x&&y的值为真,将不再与z作逻辑||运算,因而本题的答案为:x=1,y=1,z=0。 思考: 编写一个程序,输出本例中的x、y、z的值。

注意:

关系运算符、算术运算符和赋值运算符之间,优先级的次序是:算术运算符优先级别最高,关系运算符次之,赋值运算符最低。 1.7.10 条件运算符与条件运算

条件运算符的格式为: ? : 由条件运算符组成的表达式为:

条件运算符表达式=表达式1?表达式2∶表达式3; 功能如图1.10所示。

条件表达式的执行顺序为:先求解第一个表达式,若为非0,再求解第二个表达式,该表达式的值就为整个表达式的值;若第一个表达式的值为0,则求解第三个表达式,该表达式的值就作

0 1 为整个表达式的值。 表达式1

表达式3 表达式2

第1章 C程序设计基础

33

图1.10 条件运算符

例如:如从键盘读入一个整数赋给x,如果x大于等于0,把x的平方赋给y,否则把x的2倍赋给y。

解析:按题意程序流程图如图1.11所示:

0 1 x>=0

2*xx*x

图1.11 流程图

写成C语言的语句为:y=x>=0?x*x∶2*x; 程序设计为:

#include void main() {

int x,y;

scanf(\y=x>=0?x*x:2*x; printf(\}

例1.38 从键盘读入一个字符,如果是小写字符则转化为大写输出,如果是大写字符则转化为小写输出。

解析:假如从键盘读入字符到ch1中,它的结构如图1.12所示。

1 0

ch1为小写字符

ch2=ch1-32 ch2=ch1+32 34 C语言程序设计

图1.12 大小写母转换

程序设计如下:

#include void main() {

char ch1,ch2; scanf(\

ch2=ch1>=’a’&&ch1<=’z’?ch1-32:ch1+32; printf(\}

注意:

(1)条件运算符优先级高于赋值运算符,而关系、算术运算符优于条件运算符,因而:max=a>b?a:b等效于max=((a>b)?a:b)

x=a>b?a: b+1等效于x=((a>b)?a:(b+1)) (2)条件运算符结合方向为?自右至左?。 如a>b?a:c>d?c:d 等效于a>b?a∶(c>d?c:d)

在此再次提醒读者在上式中并不表示先运算括号内,它只不过表示结合性。 (3)条件表达式中类型可以不一样,如x?‘a’:‘b’ 若x=0 条件表达式值为‘b’。 例1.39 已定义int x=4,b=5,y;执行下面语句:

y= ++x > b ? x∶b--> ++x ? ++b∶x后,x、b、y的值分别为( )。 解析:条件运算符的结合方向为“自右而左”,条件运算符的优先级别仅高于赋值运算符,比关系运算符和算术运算符都低。是否需要求解表达式b-->++x?++b∶x,取决于++x>b?的真假,如为真使得该表达式的值y为x,如b-->++x为假,即再求解表达式b-->++x?++b:x,本题++x>b为假,由于在判断++x>b时x值为5,判断b-->++x时x值为6,所以整个表达式的值为6。答:6。

例1.40 分析下列程序的输出结果。

#include void main()

第1章 C程序设计基础

{

int i,j,k,a=3,b=2; i=(--a==b++)?--a:++b; j=a++; k=++b;

printf(\}

35 解析:因为--a==b++相当于--a,a==b,b++;因而表达式--a==b++为真,所以i的值为--a,即a=1,i=1,b=3。而执行表达式j=a++;后j=1,a=2,k=4。最后i=1,j=1,k=4。 1.7.11 位运算

位运算的作用是对运算对象按二进制位进行操作的运算。它能够对字节或字中的实际位进行检测,设置或移位。它只适用于字符型或整数型变量,以及它们的变体,对其他的数据类型不适用。

1.位运算符

C语言中的位运算符、位自反运算符及其功能如表1.6和表1.7所示。

表1.6 位运算符及其功能

运算符 ~ << 、>> & ^ | 作 用 位反 左移、右移 按位与 按位异或 按位或 优先级 1 2 3 4 5 表1.7 位自反运算符

位自反运算符 <<= >>= &= ^= |= 表达式 a<<=n b>>=n a&=b a^=b a|=b 等价的表达式 a=a<>n a=a&b a=a^b a=a|b 例1.41 若有运算符“<<”、“sizeof”、“^”、“&=”,按优先级从高到低的排序是( )。 (A)sizeof,&=,<<,^ (B) sizeof, <<, ^ ,&= (C) ^,<<,sizeof,&= (D) <<,^,&=,sizeof 解析:“<<”为位移位运算符,“sizeof”为字节运算符、“^”为位逻辑运算符,“&=”

46 C语言程序设计 指针是内存中的一个地址,所以它是一个整数。但它又不同于一般的整数,它必须是具体类型的特定变量地址所允许的整数。因此,指针的运算有很大的特殊性,对指针可以进行如下的一些运算:算术运算、关系运算、赋值运算。

例1.53 两个同类指针之间的算术减运算。

#include void main() {

int a[5]; int *p1,*p2; p1=a; p2=&a[3];

printf(\请思考p2+p1的运算是否有意义?*/ }

例1.54 两个同类指针之间的算术运算。

#include void main() {

int a[10]; int *p1,*p2; p1=a; p2=&a[3]; p2++; p2=p2+2;

printf(\}

例1.55 两个同类指针之间的算术运算。

#include void main() {

int a[5],x,y; int *p1,*p2; p1=a; x=(int)p1; p2=&a[3]; y=(int)p2;

printf(\printf(\

第1章 C程序设计基础

printf(\printf(\,y-x); }

47 例1.56 两个同类指针之间的关系运算。

#include void main() {

int a[5]; int *p1,*p2; p1=a; p2=&a[3];

printf(\

}

习 题

一、选择题

1.( )是构成C语言程序的基本单位。

(A)函数 (B)过程 (C)子程序 (D)文件

2.在下述程序段中,( )是错误的程序注释方法(注:本例多个选择)。

(A)

#in/*包含*/clude void main() {

printf(\}

(B)

#include void main() {

int i=3; /*整型数*/ }

(C)

#include void main() {

int x/*初始化*/=10;

48 /*打印*/printf(\}

C语言程序设计 (D)

#include void main() { int x=10; printf(\/*打印x/*x=10*/的值*/ }

3.( )是C语言提供的合法的数据类型关键字。

(A)Float (B)signed (C)integer (D)Char 4.以下选项中不合法的用户标识符是( )。

(A)abc.c (B)file (C)Main (D)PRINTF 5.以下选项中不合法的用户标识符是( )。

(A)l23 (B)printf (C)A$ (D)Dim 6.合法的C语言字符常数是( )。

(A)‘\\084’ (B)\ (C)‘ab’ (D)‘\\x43’ 7.合法的C语言字符常数是( )。

(A)‘\\t’ (B)\ (C)54 (D) A 8.合法的C语言长整型常数是( )。

(A)0L (B)5712700 (C)0.054838743 (D)2.1869e10 9.C语言中,要求运算数必须是整型的运算符是( )。

(A)% (B) / (C)< (D)! 10.以下选项中正确的整型常量是( )。

(A)12. (B)-20 (C)l,000 (D)0458 11.以下选项中正确的实型常量是( )。

(A)0 (B)3.1415 (C)0.329×102 (D).871 12.以下选项中不正确的实型常量是( )。

(A)2.607E-1 (B)0.8103e2. (C)77.77 (D)456e-2

第1章 C程序设计基础

13.C语言中运算对象必需是整型的运算符是( )。

(A) \\ (B) + (C) * (D) % 14.有关下述语句输出的判断中,正确的是( )。 char x='\\xe0'; printf(\,x);

(A)赋值非法 (B)输出值不确定 (C)输出值为-32 (D)输出值为224 15.设有语句 char a=‘\\72’; 即变量a( )。

(A)包含1个字符 (B)包含2个字符 (C)包含3个字符 (D)说明不合法 16.合法的C 语言赋值语句为( )。

(A)a=b=58 (B)i++ ; (C)a = 50 , b = 50 (D)k = int(a + b); 17.不合法的C语言赋值语句为( )。

(A)++a; (B)n1 =(n2 =(n3= 0)); (C)a = b= = c; (D)k = a + b=1 ; 18.合法的C语言赋值语句为( )。

(A)a = 7+b+c =a+ 5 (B)a = 7+b++ =a+ 5 ; (C)a = 7+b ,b++ , a+7 (D)a = 7+b,c =a+ 5; 19.int x=-1;

printf(\,%u,%o\,x,x,x); 输出为( )

(A)-1,-1,-1 (B)-1,32767,-177777 (C)-1,32768,177777 (D)-1,65535,177777

20.设有类型说明unsigned int a=65535,按%d格式输出a的值,其结果是((A)65535 (B)-1 (C)1 (D)-32767 21.正确的语句是( )。

(A)int x=y=z=0; (B)int z=(x+y)++; (C)x=+3==2; (D)x%=2.5; 22.( )是非法的c语言转义字符。

(A)‘\\b' (B)‘0xf’ (C)‘\\037’ (D)‘\\’ 23.下述程序的输出是( )。 #include void main() {

int x=023;

printf(\

49 。 )50 C语言程序设计 }

(A)17 (B)18 (C)23 (D)24 24.执行下述程序片段时输出的结果是( )。 int x=5;

int y=2+(x+=x++,x+8,++x); printf(\

(A)13 (B)14 (C)15 (D)16

25.设a,b,c均定义为 int 型,且已赋于大于1 的数,能正确表达1/(abc)的表达式是((A) 1/a*b*c (B)1/(a*b*c) (C)1.0/a*b*c (D)1.0/a/b/c 26.以下程序输出结果是( )。 #include void main() {

int a ; float b ,c;

scanf(\

printf(\}

如输入9876543210

(A)a=98 ,b=765 ,c=4321 (B)a=98 ,b=765.000000,c=4321.000000 (C)a=98 ,b= 765.0,c=4321.0 (D) a=1 ,b=432, c=8765 27.下列程序输出的结果是( )。 #include void p(int * x ) {

*x = 10 ; }

void main() {

int a, *x=&a; p(x);

printf(\,++(*x)); }

(A)输出的值是随机值 (B)因输出语句错误而不能执行者 (C)输出值为0 (D)输出值为11,但有警告 28.在C语言中,引用数组元素时,其数组下标的数据类型允许是( )。 (A)整型常数 (B)整型表达式

。 )

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库浙江大学刘加海C语言课件1在线全文阅读。

浙江大学刘加海C语言课件1.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/264832.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: