c++语言程序设计教程(第二版)习题解答 沈显军 杨进才 张勇

时间:2019-05-12 17:39:13下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《c++语言程序设计教程(第二版)习题解答 沈显军 杨进才 张勇》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《c++语言程序设计教程(第二版)习题解答 沈显军 杨进才 张勇》。

第一篇:c++语言程序设计教程(第二版)习题解答 沈显军 杨进才 张勇

1.1习题1解答

1.(1)机器语言是计算机直接理解执行的语言,由一系列(二进制)指令组成,其助符构成了汇编语言;接近人的自然语言习惯的程序设计语言为高级语言。

(2)结构化程序设计方法主要内容有:自顶向下,逐步求精;面向对象方法将现实世界中的客观事物描述成具有属性和行为的对象,抽象出共同属性和行为,形成类。

(3)C++程序开发通常要经过5个阶段,包括:编辑,编译,连接,运行,调试。首先是编辑阶段,任务是编辑源程序,C++源程序文件通常带有.cpp扩展名。接着,使用编译器对源程序进行编译,将源程序翻译为机器语言代码(目标代码),过程分为词法分析、语法分析、代码生成3个步骤。

在此之前,预编译器会自动执行源程序中的预处理指令,完成将其他源程序文件包括到要编译的文件中,以及执行各种文字替换等。

连接器的功能就是将目标代码同缺失函数的代码连接起来,将这个“漏洞”补上,生成可执行文件。程序运行时,可执行文件由操作系统装入内存,然后CPU从内存中取出程序执行。若程序运行进程中出现了错误,还在需要对程序进行调试。

(4)对象与对象之间通过消息进行相互通信。

(5)类是具有相同属性和行为的一组对象的抽象;任何一个对象都是某个类的一个实例。

(6)多态性是指在一般类中定义 的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。(7)面向对象的软件开发过程主要包括面向对象的方法分析、面向对象的设计、面向对象的编程、面向对象的测试和面向对象的维护。

(8)泛型程序设计是指在程序设计时,将数据类型参数化,编写具有通用性和可重用的程序。(9)# include 是一条预处理指令(语句),在编译(或预处理)时由编译器(或预编译器)执行,其功能是将iostream文件包含(复制)到指令处。

(10)C++中使用cin作为标准输入流对象,通常代表键盘,与提取操作符>>连用;使用cout作为标准输出流对象,通常代表显示设备,与<<连用。

2.(1)叙述机器语言、汇编语言、高级语言的特点。

机器语言是计算机直接执行的语言,由二进制的0和1构成的一系列指令组成;

汇编语言是机器语言的助记符;

高级语言是接近人的自然语言习惯的编程语言,通过编译变成机器语言。(2)结构化的语言与面向对象的语言是截然分开的吗?

不是截然分开的,面向对象的程序设计中也包含过程,含有结构化的思想。(3)C编写的程序不加修改就可以在C++编译器中编译。

(5)C++程序通过编译变成带扩展名.obj的目标文件;再通过连接变成带扩展名.exe的可执行文件。(6)如果要求不使用include包含头文件,有什么办法使程序正常编译运行?

在相应的文件夹(子目录)中,找到需要包含的头文件,将头文件复制到包含处。

3.(2)C++语言程序能够在不同操作系统下编译、运行,说明C++具有良好的移植性。(可以说C++语言完全兼容C语言,但是在这不能说C++语言程序能兼容不同的操作系统;对于计算机硬件,一般使用“兼容”一词,对于程序使用“移植”)。(3)#include语句在程序运行前就执行了。(4)C++程序运行时总是起始于main();(5)用C++写程序时一个语句可分几行写。(6)面向对象编程方法有:对象、继承、类等。

1.2习题2解答 1.(1)C++的基本数据类型可分为5大类:逻辑型(或布尔型)、字符型、整形、实型、空值型。分别用关键字bool,char,int,float/double,void 定义。长度分别为1,1,4,4/8,不定字节。整型、字符型的默认符号修饰为signed。(2)十进制数值、八进制数值、十六进制数值的前缀分别为1~9, 0, 0x(或0X)。(3)一个整数值的数据类型为int,一个带小数点的数据类型为double。

(4)C++预定义的常用转义序中,在输出流中用于换行、空格的转义序列分别为n,t。(5)布尔型数值只有两个;true, false。在C++的算术运算式中,分别当作1,0。

(6)字符由单引号’’括起来,字符串由双引号“”括起来。字符只能有1个字符字符串可以有多个字符。空串的表示方法为“”(或“ ”)。(7)标识符以英文字母,下划线开头。

(8)定义变量的同时赋初值的方法有赋值运算符=,括号。定义常变量初值的方法有赋值运算符=,括号。

(9)关系运算符操作数的类型可以是任何基本数据类型,对其中的实数类型不能进行直接比较(if(a

(-10)&&与||表达式按从左到右的顺序进行计算,以&&连接的表达式,如果左边的计算结果为false(或0),右边的计算不需要进行,就能得到整个逻辑表达式的结果:false;以||连接的表达式,如果左边的计算结果为true(或非0),就能得到整个逻辑表达式的结果:true。

(11)>>运算符将一个数右移n位,相当于将该数除以2,<<运算符将一个数左移n位,相当于将该数乘以2。(12)所有含赋值运算的运算符左边要求是左值。

(13)前置++、――的优先级高于后置++、――。

(14)按操作数数目分,运算符的优先级从高到低排列为单目、双目、三目,按运算符的性分,优先级从高到低排列为算术、移位、关系、按位、逻辑。

(15)在表达式中会产生副作用的运算符有++、--、各类赋值。2.1.3

习题3解答

1.(1)if语句中的表达式可以是任意表达式(关系表达式、逻辑表达式、算术表达式、常量)。1.4习题4解答

1.(1)一个C++程序就是由一个个函数组成的即使是最简单的程序也有一个main()函数。

(2)函数执行过程中通过return语句将函数值返回,当一个函数不需要返回值,此时需要使用void作为类型名。(3)在C++中,如果函数定义在后,调用在先,需要进行函数原型声明,告诉编译器函数的(返回)类型,函数名,形式参数。其格式和定义函数时的函数头的形式基本相同,它必须以分号 ;结尾。(4)函数调过程的3个步骤为:函数调用(或参数传递),函数体执行,返回。(5)函数参数传递过程的实质是将实参值通过堆栈一一传送给实参。(实参传给实叁?)(6)递归程序分两个阶段执行调用,回代。

(7)带inline关键字定义的函数为内联函数,在编译时将函数体展开到所有调用处。内联函数的好处是节省执行时间开销。

(8)函数名相同,但对应形参表不同的一组函数称为重载函数,参数表不同是指参数个数、类型不同。

(9)确定对重载函数中函数进行绑定的优先次序为精确匹配,对实参的类型向高类型转换后的匹配,实参类型向低类型及相容类型转换后的匹配。

(10)当既存在重载函数、又有函数模板,函数调用优先绑定重载函数,只有不能精确匹配重载函数时,才实例化类模板。

n

N(11)内联函数的展开、重载函数的绑定、类模板的实例化与绑定均在编译阶段进行。(12)在C++中,函数不允许嵌套定义,允许嵌套调用。

2.(1)void fun(void)的定义是正确的,double fun(int x;int y)和int fun();和double fun(int x,y)这都是不正确的(定义是不能以;结尾的)。(2)函数int fun(int x, int y)的声明形式可以是int fun(int, int)和int fun(int y,int x);和int fun(int i,int j);(int fun(int x, int y)是不正确的因为函数的声明必须以;结尾)。(3)C++语言中规定函数的返回值的类型是由定义该函数时所指定的数据类型所决定。(5)在C++中默认的形参值应该先从右边的形参开始向左边依次设置。(6)重载函数参数个数相同时,参数类型必须不同。

(7)系统在调用重载函数时,依据的是函数名称、实参个数、实参类型。(8)

(9)为了取代C中带参数的宏,在C++ 中使用内联函数。(10)函数模板定义的头部template(11)若fun(8,3.1)调用的可以是fun(double, double)――(当没有精确匹配时,优先进行向高类型转换后的匹配)(12)若fun(8,3.1)调用的可以是template fun(T1,T2)1.5 习题5解答

1.(-1)enum weekday {sun,mon,tue,wed=d,thu,fri,sat};

weekday workday =mon;

cout<

输出:5(怎么加的?)

(2)在C++中,引用数组元素时,其数组下标的数据类型允许是整形常量、整形表达式等非浮点型表达式。(整型表达式实际上包含了整型常量)

(3)设有数组定义:char array[]=”China”;则数组array所占的空间为6个字节(’’)。(4)若:int a[][3] = {1,2,3,4,5,6,7};

则a 数组高维的大小为:3。(-6)若二维数组a有m 列,则在a[i][j]前的元素个数为(i*m+j);

1.6习题六解答(1)从变量的定义位置分,可分为全局变量与局部变量。其中,局部变量定义在函数或复合语句中,供函数或复合语句中使用。

(2)变量的存储类型分为auto,extern,register,static。当声明一个静态(static)变量,它既具有局部变量的性质,又具有全局变量的性质。

(3)C++程序的内存分为4个区:全局数据区,代码区,栈区,堆区。全局变量,静态变量,字符串常量存放在全局数据区,所有在函数和代码存放在代码区,为运行函数而分配的函数参数,局部变量,返回地址存放在栈区。动态分配的内存在堆区。

(4)全局变量,静态变量具有静态生存期;局部变量生存期为动态。

(5)函数原型中形参标识符的作用域为为函数原型,函数的形参与函数体作用域为块作用域;函数,全局变量与常量有文件作用域。(6)C++源程序中以#开头,以换行符结尾的行称为预处理命令。预处理命令编译前由预处理器执行。

(7)可以通过3种方法使用名字空间,个别使用声明方式,全局声明方式,全局声明个别成员。

2.(1)在C++中,函数默认的存储类别为:auto。

(2)函数的形式参数是局部变量,在一个函数体内定义的变量只在本函数范围内有效,在函数的复合语句中定义的变量在此复合语句中有效。

(3)# define PI 3.14 预处理命令必须以#开头,凡是以#开头的都是预处理命令行,在程序执行前执行预处理命令。

(4)动态分配的内存要用delete释放,局部auto变量分配的内存在函数调用结束时释放,全局变量的内存在程序结束时释放。

1.7

习题7解答

1.(1)类的私有成员只能被该类的成员函数或友元函数访问。

(2)类的数据成员不能在定义的时候初始化,而应该通过构造函数初始化。(3)类成员默认的访问方式是private.(4)类的公有成员函数的集合是该类给外界提供的接口。

(5)类的公有成员可以被类作用域内的任何对象访问。

(6)为了能够访问到某个类的私有成员,必须在该类中声明该类的友元。(7)类的静态成员为该类的所有对象所共享。

(8)每个对象都有一个指向自身的指针,称为this指针,通过使用它来确定其自身的地址。(9)运算符new自动建立一个大小合适的对象并返回一个具有正确类型的指针。(-10)C++禁止非const成员函数访问const对象。

(-11)定义类的动态对象数组时,系统只能够自调用该类的构造函数对其进行初始化。(――12)C++中语句const char* const p=”hello”;所定义的指针p和它所指的内容都不能被以改变。

(――13)假定AB为一个类,则语句 AB(AB& x);为该类拷贝构造函数原型说明。

(14)在C++中访问一个对象的成员所用的运算符是.,访问一个指针所指向的对象的成员所用的运算符是->。(15)析构函数在对象的生存期结束时被自动调用,全局对象和静态对象的析构函数在程序运行结束时调用。

(16)设p是指向一个类的动态对象的指针变量,则执行 delete P;语句时,将自动调用该类的析构函数。

2.(1)数据封装就是将一组数据和与这组数据有关操作组装在一起,形成一个实体,这实体也就是类。

(2)类的实例化就是创建类的对象。

(-3)已知p是一个指向类Sample数据成员m的指针,s是类Sample的一个对象。如果要给m赋值为5:s.*p=5;(4)类与对象的关系和数据类型与变量的关系是相似的,一个对象只能属于一个具体的类。(5)封装要求对象就具有明确的功能,它使得一个对象可以像一个部件一样用在各种程序中。

(6)内联函数是在编译时(而不是运行时)将该函数的目标代码插入到每一个调用该函数的地方。

(7)类中的函数成员可以在类体中定义,也可以在类体之外定义。(8)C++中的对象并不是C语言中的结构体变量,它是一个状态和操作(或方法)的封装体,对象之间的信息传递是通过消息进行的。

(9)在建立类的对象时只为每个对象分配用于保存数据成员的内存 3.(1)类和数据类型有何关联?

类相当于一种包含函数的自定义数据类型,它不占内存空间,是一个抽象的“虚”体,使用已定义的类建立对象就像用数据类型定义变量一样。对象建立后,对象占据内存,变成了一个“实”体。类与对象的关系就像数据类型与变量的的关系一样。其实,一个变量就是一个简单的不含成员函数的数据对象。(2)类和对象的内存分配关系?

为节省内存,编译器在创建对象时,只为各对象分配用于保存各对象数据成员初始化的值,并不为各对象的成员函数分配单独的内存空间,而是共享类的成员函数定义,即类中成员函数的定义为该类的所有对象所共享,这是C++编译器创建对象的一种方法,实际应用中,我们仍将对象理解为由数据成员和函数成员两部分组成。

(3)什么是浅拷贝?什么是深拷贝?二者有何异同?

构造函数用于建立对象时给对象赋初值以初始化新建立的对象。如果有一个现存的对象,在建立新对象时希望利用现存对象作为新对象的初值,即用一个已存在的对象去初始化一个新建立的对象。C++提供的拷贝构造函数用于在建立新对象时将已存在的对象的数据成员值复制给新,以初始化新对象。拷贝构造函数在用类的一个对象去初始化该类的另一个对象时调用,以下3种情况相当于用一个已存在的对象去初始化新建立的对象,因此,调用拷贝构造函数:

① 当用类的一个对象去初始化该类的另一个对象时。② 如果函数的形参是类的对象,调用函数时,将对象作为函数实参传递给函数的形参时。③ 如果函数的返回值是类的对象,函数执行完成,将返回值返回时。

原因在于默认的拷贝构造函数实现的只能是浅拷贝,即直接将原对象的数据成员值依次复制给新对象中对应的数据成员,并没有为新对象另外分配内存资源。这样,如果对象的数据成员是指针,两个指针对象实际上指向的是同一块内存空间。

当类的数据成员中有指针类型时,我们就必须定义一个特定的拷贝构造函数,该拷贝构造函数不仅可以实现原对象和新对象之间的数据成员的复制,而且可以为新的对象分配单独的内存资源,这就是深拷贝构造函数。

(4)什么是this指针? 它的作用是什么?

一个类的成员函数中,有时希望引用调用它的对象,对此,C++采用隐含的this指针来实现。this指针是一个系统预定义的特殊指针,指向当前对象,表示当前对象的地址。系统利用this指针明确指出成员函数当前操作的数据成员所属的对象。实际上,当一个对象调用其成员函数时,编译器先将该对象的地址赋给this指针,然后调用成员函数,这样成员函数对对象的数据成员进行操作时,就隐含使用了this指针。

一般而言,通常不直接使用this指针来引用对象的成员,但在某些少数情况下,可以使用this指针,如重载某些运算符以实现对象的连续赋值等。

This指针不是调用对象的名称,而是指向调用对象的指针的名称。This的值不能改变,它总是指向当前调用对象。

(5)C++中静态成员有何作用?它有何特点?

C++提供了静态成员,用以解决同一个类的不同对象之间数据成员和函数的共享问题。

静态成员的特点是:不管这个类创建了多少个对象,其静态成员在内存中只保留一份副本,这个副本为该类的所有对象所共享。

面向对象方法中还有类属性(class attribute)的概念,类属性是描述类的所有对象的共同特征的一个数据项,对于任何对象实像实例,它的属性值是相同的,C++通过静态数据成员来实现类属性。

(6)友元关联有何性质?

①友元关联是不能传递的,不能被继承。如B类是A类的友元,C类是B类的友元,C类和A类之间如果没有声明,就没有任何友元关系,不能进行数据共享。

②友元关系是单向的,不具有交换性,如果声明B类是A类的友元,B类的成员函数就可以访问A类的私有和保护数据,但A类的成员函数却不能访问B类的私有和保护数据。(7)在C++程序设计中,友元关系的优点和缺点是什么?

友元概念的引入,提高了数据的共享性,加强了函数与函数之间、类与类之间的相互联系,大大提高了程序的效率,这是友元的优点,但友元也破坏了数据隐蔽和数据封装,导致程序的可维护性变差,给程序的重用和扩充埋下了深深的隐患,这是友元的缺点。(8)如何实现不同对象的内存空间的分配和释放?

当类被实例化成对象后,不同类别的对象占据不同类型的内存,其规律与普通变量相同: ① 类的全局对象占有数据段的内存。② 类的局部对象内存分配在栈中。

③ 函数调用时为实参建立的临时对象内存分配在栈中。④ 使用动态内存分配语句new建立的动态对象,内存在堆中分配。

虽然类(对象)是由数据成员与成员函数组成。但是,程序运行时,系统只为各对象的数据成员分配单独内存空间,而该类的所有对象则共享类的成员函数定义以及为成员函数分配的空间。对象的内存空间分配有下列规则:

① 对象的数据成员与成员函数占据不同的内存空间,数据成员的内存空间与对象的② ③ 存储类别相关,成员函数的内存空间在代码段中。

一个类所有对象的数据成员拥有各自的内存空间。

一个类所有对象的成员函数为该类的所有对象共享,在内存中,只有一个副本随着对象的生命周期的结束,对象所占的空间就会释放,各类对象内存空间释放时间与方法如下:

a. 全局对象的数据成员占有的内存空间在程序结束时释放。

b. 局部对象与实参对象数据成员的内存空间在函数调用结束时释放。c. 动态对象数据成员的内存空间要使用delete语句释放。

d. 对象的成员函数的内存空间在该类的所有对象生命周期结束时自动释放。

1.8

习题8解答1.(1)C++程序设计的关键之一是利用继承实现软件重用,有效地缩短程序的开发时间。

(2)基类的对象可以作为派生类的对象使用,这称为类型兼容(或赋值兼容)。

(3)在C++中,三种派生方式的说明符号为public, private, protected, 如果不加说明,则默认的派生方式为private。

(4)当私有派生时,基类的的公有成员成为派生类的私有成员;保护成员成为派生类的私有成员;私有成员成为派生类的不可访问成员。

(5)相互关联的各个类之间的关系主要分为组成关联和继承关联。

(6)在派生类中不能直接访问基类的私有成员否则破坏了基类的封装性。(-7)保护成员具有双重角色,对派生类的成员函数而言,它是公有成员,但对所在类之外定义的其它函数而言则是私有成员。

(-8)多继承时,多个基类中的同名的成员在派生类中由于标识符不唯一而出现二义性。在派生类中采用成员名限定或重定义具有二义性的成员来消除该问题。

(9)C++提供的多继承机制允许一个派生类继承多个基类。

2.(1)一个派生类可以作为另外一个派生类的基类;派生类至少有一个基类;派生类的成员除了它自己的成员外,还包含了它的基类的成员。

(2)在多继承中,公有派生和私有派生对于基类成员在派生类中的可访问性与单继承的规则是完全相同的。(3)友元关系是不能继承的。

(4)派生类一般都是公有派生;对基类成员的访问必须是无二义性的;赋值兼容规则也是适用于多重继承的场合。(5)基类的保护成员在公有派生中仍然是保护的;基类的保护成员在私有派生中却是私有的;对基类成员的访问必须是无二义性的。

(6)在公有派生的情况下,派生类中定义的成员函数只能访问原基类中的公有成员和保护成员。

(7)每个派生类的构造函数都要为虚基类构造函数提供实参;多继承时有可能出现对基类成员访问的二义性问题;建立派生类对象时,虚基类数的构造函数会首先被调用。

(8)在一个派生类对象结束其生命周期时先调用基类的析构函数后调用派生类的析构函数。

(9)当保护继承时,基类的公有成员和保护成员在派生类中成为保护成员,不能通过派生类的对象来直接访问。(10)若派生类的成员函数不能直接访问基类中继承来的某个成员,则该成员一定是基类中的私有成员。(11)设置虚基类的目的是消除二义性。

(12)继承具有传递性,即当基类本身也是某个类的派生类时,底层的派生类也会自动继承间接基类的成员。(13)在派生类构造函数的初始化列表中不能包含派生类中一般数据成员的初始化。

(14)在公有派生情况下,派生类的对象可以赋给基类的对象;派生类的对象可以初始化基类的引用;派生类的对象的地址可以赋给指向基类的指针。

3.(1)派生类如何实现对基类私有成员的访问?

无论使用哪一种继承方式,基类的私有成员都不允许外部函数直接访问,也不允许派生的成员函数直接访问,但是可以通过基类的公有成员函数间接访问该类的私有成员。(2)什么是赋值兼容?它会带来什么问题?

类型兼容是指在公有派生的情况下,一个派生类对象可以作为基类的对象来使用。类型兼容又称为类型赋值值兼容或类型适应。

在C++中,类型兼容主要指以下3种情况:

① 派生类对象可以赋值给基类对象; ② 派生类对象可以初始化基类的引用;

③ 派生类对象的地址可以赋给指向基类的指针;

由于派生类对象中包含基类子对象,所以这种引用方式是安全的,但是这种方法只能引用从基类继承的成员。如果试图通过基类指针引用那些只有在派生类中才有的成员,编译器将会报告语法错误。

(3)多重继承时,构造函数和析构函数的执行顺序是如何实现的?

多得继承时,构造函数的执行顺序是:先执行基类的构造函数,再执行对象成员的构造函数,最后执行派生类的构造函数。

在多个基类之间则严格按照派生类声明时从左到右的顺序来执行各基类的构造函数,而析构函数的执行顺序则正好与构造函数的执行顺序相反。

(4)继承与组合之间的区别和联系是什么?

继承描述的是一般类与特殊类的关系,类与类之间体现的是”is a kind of”,即如果在逻辑上A是B的一种,允许A继承B的功能和属性。例如汽车(automobile)是交通工具(vehicle)的一种,小汽车(car)是汽车的一种。那么类automobile可以从类vehicle派生,类car 可以从类automobile派生。

组合描述的是整体与部分的关系,类与类之间体现的是”is a part of ”,如果在逻辑上A是B的一部分,则允许A和其他数据成员组合为B。例如:发动机、车轮、电池、车门、方向盘、底盘都是小汽车的一部分,它们组合成汽车,而不能说汽车是发动机的一种。

在C++中,类的继承与类的组合很相似,继承和组合既有区别,也有联系,主要表现在描述的关系不同。某些比较复杂的类,既需要使用继承,也需要使用组合,二者一起使用。

在某些情况下,继承与组合的实现还可以互换。在多继承时,一个派生类有多个直接基类,派生类实际上是所有基类属性和行为的组合。派生类是对基类的扩充,派生类的成员一部分是从基类中来,因此派生类组合了基类。既然这样,派生类也可以通过组合类实现。什么时候用继承,什么时候使用组合,要根据问题中类与类之间的具体关系,顺其自然,权衡考虑。

(5)什么是虚基类?它有什么作用?

在多继承中,当派生类的部分或全部直接基类又是从另一个共同基类派生而来时,这些直接基类中从上一级共同基类继承来的成员就拥有相同的名称。在派生类的对象中,同名数据成员在内存中同时拥有多个副本,同一个成员函数会有多个映射,出现二义性,因此,C++将共同基类设置为虚基类。虚基类使得从不同的路径继承过来的同名数据成员在内存中只有一个副本,同一个函数也只有一个映射。这样不公解决了二义性的问题,也节省了内存,避免了数据不一致的问题。1.9习题9解答

1.(1)将一个函数调用链接上相应函数体的代码,这一过程称为联编(绑定)。(2)C++支持两种多态性:静态多态性和动态多态性。

(3)在编译时就确定的函数调用称为静态联编,它通过使用重载函数实现。(4)在运行时才确定的函数调用称为动态联编,它通过继承和虚函数来实现。(5)虚函数的声明方法是在函数原型前加上关键字virtual。(6)C++的静态多态性是通过重载函数实现的。

(7)C++的动态多态性是通过虚函数实现的。

(8)当通过基类指针使用虚函数时,C++会在与对象关联的派生类中正确地选择重定义的函数。

(9)如果一个类包含一个或多个纯虚函数,则该称为抽象类。

(10)若以非成员函数形式,为类Bounce重载!运算符,其操作结果为bool型数据,则该运算符重载函数的原型是:friend bool operate!(Bounce);2.(1)在C++中::运算符不能被重载。

(2)运算符重载不能改变运算数的个数、优先级、结合性和语法结构。

(3)如果表达式++i*k中的++和*都是重载的友元运算符,则采用运算符函数调用格式,该表达式还可表示为operator*(operator++(i),k).。

(4)5.0+2.0和2+5两个表达式中的+的意义不相同。(5)有的运算符只能作为成员函数重载。

(6)已知在一个类体中包含如下函数原型:VOLUME operator-(VOLUME)const。

这是运算符-的重载运算符函数;这是一个成员函数;这个函数不改变类的任何数据成员的值。(7)在表达式x+y*z中,+是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。

Operator+有一个参数,operator*有两个参数;

(8)在C++中,对象之间的相互通信通过调用成员函数来实现。

(9)Franction operator +(Franction,Franction);Franction &operator =(Franction&,Franction);Franction &operator +=(Franction&, Franction)以上是重载为非成员函数的运算符函数原型。(10)当一个类的某个函数被说明为virtual时,该函数在该类的所有派生类中都是虚函数。

(11)纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,但要求在任何派生类都必须定义自己的版本。(12)Virtual void vf()=0;这个基类中的成员函数表示纯虚函数。(13)如果一个类至少有一个纯虚函数,那么就称该类为抽象类。

(14)纯虚函数是一种特殊的虚函数,它没有具体的定义;抽象类是指具有纯虚函数的类;抽象类只能作为基类来使用,其纯虚函数的定义同派生类给出。

(15)抽象类的特性――不能定义其对象。

(16)抽象类至少应该含有一个纯虚函数。

(17)类B是类A的公有派生类,类A和类B中都定义了虚函数 fun(), p是一个指向类A对象的指针,则p->A:::func()将调用类A中的函数func()。

(18)在C++中,用于实现运行时多态性的是虚函数。(19)Class A{ Public: Virtual void func1(){} void func2(){} };Class B: public A{ Public: Void func1(){cout<<”class B func1”<

(20)抽象类中的成员函数都是虚函数。

(21)如果派生类没有实现基类的一个纯虚函数,则该派生类是一个抽象类。1.10

习题10解答

1.(1)模板是面向对象技术提高软件开发效率的重要手段,是C++语言的重要特征。

(2)类模板是能根据不同参数建立不同类型成员的类。

(3)STL中体现了泛型化程序设计的相思,它提倡使用现有的模板程序代码开发应用程序,是一种代码重用技术。(4)STL(Standard Template Library)是C++提供的标准模板库,它可以实现高效的泛型程序设计。

(5)STL容器包括顺序容器和关联容器利用容器适配器可以将顺序容器转换为新的容器。

(6)顺序容器(sequence container)以逻辑线性排列方式存储一个元素序列,在容器类型中的对象在逻辑上跑旱船认为是在连续的存储空间中存储的。

(7)关联容器(associate container)中的数据元素不存储在顺序的线性数据结构中,它们提供了一个关键字(key)到值的关联映射。

(8)容器适配器就是将某个底层顺序容器转换为另一种容器。即以顺序容器作为数据存储结构,交将其转换为一种某种特定操作特性的新容器。

(9)在STL中,迭代器如同一个特殊的指针(用以指向容器中某个位置的数据元素)。

(10)在STL中函数对象在STL中被广泛用作算法中子操作的参数,使算法变得更加通用。2.(1)类模板的使用实际上是将类模板实例化成一个类。

(2)类模板的模板参数能作为数据成员的类型;可作为成员函数的返回类型;可作为成员函数的参数类型。(3)类模板的实例化在编译时进行。(4)类模板的参数可以有多个。(5)类模板实例化时的实参值可以是0个。当类模板的模板参数均给出了初值时,类模板实例化时可以没有实例。(6)类模板的定义:template (7)类模板:

Template Class Tclass{…}

正确的实例化方式为:Tclass C!;(11)在调用模板函数时模板实参的使用:对于常规参数所对应的模板实参,任何情况下都不能省略。

1.1习题11解答

1.(1)标准输入流对象为cin,与>>(提取操作符)连用,用于输入;cout为标准输出流对象,与<<(插入操作符)连用,用于输出。

(2)用标准输入流对象cin与提取操作>>连用进行输入时,将空格与换行当作分隔符,使用getline()成员函数进行输入时可以指定输入分隔符。

(3)头文件iostream中定义了4个标准流对象cin, cout, cerr, clog。

(4)每一个输入/输出流对象都维护一个格式状态字,用它表示汉对象当前的格式状态并控制流的格式。C++提供了使用操纵符与格式状态字,来控制流的格式的方法。

(5)格式控制的成员函数通过流对象调用;操纵符直接用在流中,但使用函数形式的操纵符要包含iomanip头文件。(6)在ios类中,除了提供控制数据流格式标志、操纵符、成员函数,还提供了流的错误侦测函数与错误状态位,用于标识流的状态,常用的错误侦测函数有good(), eof(), fail(), bad()对应的错误状态位为goodbit, eof, bit, failbit, badbit。(7)文件输入是指从文件向内读入数据;文件输出则指从内存向文件输出数据。文件的输入输出首先要建立输入文件流,与打开的文件连接;然后从文件流中读入数据到内存;最后关闭文件流。在打开文件、对文件读写时要使用是否成功的判断来保证文件操作的正确。

(8)文本文件是存储ASSCII码字符的文件,文本文件的输入可用>>(提取操作符)从输入文件流中提取字符实现。文本文件的输出可用<<(插入操作符)将字符插入到输出文件流来实现。

(9)二进制文件是指含ASCII码字符外的数据的文件。二进制文件的输入输出分别采用read()、write()成员函数,这两个成员函数第一个参数的类型分别为char *, const char *, 如果实参类型不符,分别采用reinterpret_cast, reinterpret_cast进行转换。(10)设定、返回文件读指针位置的函数分别为seekg(), tellg();设定、返回文件写指针位置的函数分别为seekp(), tellp()。2.(1)要进行文件的输出,除了包含头文件iostream外,还要包含fstream头文件。(3)char *str;cin>>str;cout<

1.12习题12解答

1.(1)s0是一个string类串,定义串s1的方法有:string s1(s0,0,3);、string s1(“ABC”,0,3);、string s1=”ABC”;、string s1(3,’A’);(2)若char *s0=”12345”, 则有:string s1=s0;string s1(s0);string s1(s0,0,3);(3)求string类串S长度的表达式为:S.length();(4)S为string类对象,则S.size();sizeod(S);S.length();的编译不会出错。

(5)S、T为string类对象,则S=T;S[1]=T[1];S+=T;的编译不会出错。

(6)string s=(“ABCDEF”);char *q =”123456”;string::iterator p=s.begin();则有:p=q;*(p+1)=*(q+1);q[1]=p[1];

1.13

习题13解答 1.(1)运行错属于异常;硬件故障也可当异常抛出;只要是编程者认为是异常的都可以当异常抛出;

(2)throw语句必须在try语句块中直接运行或通过调用函数运行;一个程序中可以有try 语句而没有throw语句;throw语句抛出的异常可以不被捕获。

(3)函数声明 float fun(int a, int b)throw(),表明函数不抛出任何类型异常。(4)catch(….)语句可捕获所有类型的异常;一个try语句可以有多个catch()语句;程序中try语句与catch语句是一个整体,缺一不可。

(5)若定义int a[2][3], 那么a[2][3]=3;数组下标越界了但不会引发异常。

第二篇:《C语言程序设计教程(第二版)》习题答案

第1章 程序设计基础知识

一、单项选择题(第23页)1-4.CBBC 5-8.DACA

二、填空题(第24页)

1.判断条件 2.面向过程编程 3.结构化 4.程序 5.面向对象的程序设计语言 7.有穷性 8.直到型循环 9.算法 10.可读性 11.模块化 12.对问题的分析和模块的划分

三、应用题(第24页)2.源程序:

main()

{int i,j,k;/* i:公鸡数,j:母鸡数,k:小鸡数的1/3 */ printf(“cock hen chickn”);for(i=1;i<=20;i++)for(j=1;j<=33;j++)for(k=1;k<=33;k++)

if(i+j+k*3==100&&i*5+j*3+k==100)printf(“ %d %d %dn”,i,j,k*3);} 执行结果:

cock hen chick 4 18 78 8 11 81 12 4 84

3.现计算斐波那契数列的前20项。

递推法 源程序:

main()

{long a,b;int i;a=b=1;

for(i=1;i<=10;i++)/*要计算前30项,把10改为15。*/ {printf(“%8ld%8ld”,a,b);a=a+b;b=b+a;}}

递归法 源程序:

main(){int i;

for(i=0;i<=19;i++)printf(“%8d”,fib(i));} fib(int i)

{return(i<=1?1:fib(i-1)+fib(i-2));}

执行结果:

1 2 3 5 8 13 21 34 55

233 377 610 987 1597 2584 4181 6765 4.源程序:

#include “math.h”;main()

{double x,x0,deltax;x=1.5;

do {x0=pow(x+1,1./3);deltax=fabs(x0-x);x=x0;

}while(deltax>1e-12);printf(“%.10fn”,x);} 执行结果:

1.3247179572

5.源程序略。(分子、分母均构成斐波那契数列)结果是32.66026079864 6.源程序:

main()

{int a,b,c,m;

printf(“Please input a,b and c:”);scanf(“%d %d %d”,&a,&b,&c);if(a

printf(“%d %d %dn”,a,b,c);} 执行结果:

Please input a,b and c:123 456 789 789 456 123 7.源程序:

main(){int a;

scanf(“%d”,&a);

printf(a%21==0?“Yes”:“No”);} 执行结果:

Yes 第2章 C语言概述

一、单项选择题(第34页)1-4.BDCB 5-8.AABC

二、填空题(第35页)

1.主 2.C编译系统 3.函数 函数 4.输入输出 5.头 6..OBJ 7.库函数 8.文本

三、应用题(第36页)

5.sizeof是关键字,stru、_aoto、file、m_i_n、hello、ABC、SIN90、x1234、until、cos2x、s_3是标识符。

8.源程序: main(){int a,b,c;

scanf(“%d %d”,&a,&b);c=a;a=b;b=c;

printf(“%d %d”,a,b);} 执行结果:34 34 12 第3章 数据类型与运算规则

一、单项选择题(第75页)

1-5.DBACC 6-10.DBDBC 11-15.ADCCC 16-20.CBCCD 21-25.ADDBC 26-27.AB

二、填空题(第77页)

1.补码 2.±(10^-308~10^308)3.int(整数)4.单目 自右相左 5.函数调用 6.a或b 7.1 8.65,89

三、应用题(第78页)1.10 9

2.执行结果: 0 0 12 1 第4章 顺序结构程序设计

一、单项选择题(第90页)1-5.DCDAD 6-10.BACBB

二、填空题(第91页)

1.一 ;2.5.169000 3.(1)-2002500(2)I=-200,j=2500(3)i=-200 j=2500 4.a=98,b=765.000000,c=4321.000000 5.略 6.0,0,3 7.3 8.scanf(“%lf%lf%lf”,&a,&b,&c);9.13 13.000000,13.000000 10.a=a^c;c=c^a;a=a^c;(这种算法不破坏b的值,也不用定义中间变量。)

三、编程题(第92页)

1.仿照教材第27页例2-1。

2.源程序:

main(){int h,m;

scanf(“%d:%d”,&h,&m);printf(“%dn”,h*60+m);} 执行结果:

9:23 563

3.源程序:

main()

{int a[]={-10,0,15,34},i;for(i=0;i<=3;i++)

printf(“%d370C=%g370Ft”,a[i],a[i]*1.8+32);} 执行结果:

-10℃=14°F 0℃=32°F 15℃=59°F 34℃=93.2°F 4.源程序:

main()

{double pi=3.14***9,r=5;

printf(“r=%lg A=%.10lf S=%.10lfn”,r,2*pi*r,pi*pi*r);} 执行结果:

r=5 A=31.4159265359 S=49.3480220054 5.源程序:

#include “math.h”;main()

{double a,b,c;

scanf(“%lf%lf%lf”,&a,&b,&c);if(a+b>c&&a+c>b&&b+c>a){double s=(a+b+c)/2;

printf(“SS=%.10lfn”,sqrt(s*(s-a)*(s-b)*(s-c)));} else printf(“Data error!”);} 执行结果:5 6

SS=9.9215674165 6.源程序:

main()

{int a=3,b=4,c=5;float d=1.2,e=2.23,f=-43.56;

printf(“a=%3d,b=%-4d,c=**%dnd=%gne=%6.2fnf=%-10.4f**n”,a,b,c,d,e,f);} 7.源程序:

main()

{int a,b,c,m;

scanf(“%d %d %d”,&a,&b,&c);m=a;a=b;b=c;c=m;

printf(“%d %d %dn”,a,b,c);} 执行结果:6 7 6 7 5 8.源程序:

main(){int a,b,c;

scanf(“%d %d %d”,&a,&b,&c);

printf(“average of %d,%d and %d is %.2fn”,a,b,c,(a+b+c)/3.);执行结果: 7 9

average of 6,7 and 9 is 7.33 9.不能。修改后的源程序如下:

main()

{int a,b,c,x,y;

scanf(“%d %d %d”,&a,&b,&c);x=a*b;y=x*c;

printf(“a=%d,b=%d,c=%dn”,a,b,c);printf(“x=%d,y=%dn”,x,y);} 第5章 选择结构程序设计

一、单项选择题(第113页)1-4.DCBB 5-8.DABD

二、填空题(第115页)1.非0 0 2.k==0

3.if(abs(x)>4)printf(“%d”,x);else printf(“error!”);

4.if((x>=1&&x<=10||x>=200&&x<=210)&&x&1)printf(“%d”,x);5.k=1(原题最后一行漏了个d,如果认为原题正确,则输出k=%。)6.8!Right!11 7.$$$a=0 8.a=2,b=

1三、编程题(第116页)1.有错。正确的程序如下:

main(){int a,b,c;

scanf(“%d,%d,%d”,&a,&b,&c);

printf(“min=%dn”,a>b?b>c?c:b:a>c?c:a);} 2.源程序:

main()

{unsigned long a;scanf(“%ld”,&a);

for(;a;printf(“%d”,a%10),a/=10);} 执行结果:

12345 54321

3.(1)源程序: main(){int x,y;

scanf(“%d”,&x);if(x>-5&&x<0)y=x;if(x>=0&&x<5)y=x-1;if(x>=5&&x<10)y=x+1;printf(“%dn”,y);}(2)源程序:

main(){int x,y;

scanf(“%d”,&x);

if(x<10)if(x>-5)if(x>=0)if(x>=5)y=x+1;else y=x-1;else y=x;printf(“%dn”,y);}(3)源程序:

main(){int x,y;

scanf(“%d”,&x);

if(x<10)if(x>=5)y=x+1;else if(x>=0)y=x-1;else if(x>-5)y=x;printf(“%dn”,y);}(4)源程序:

main(){int x,y;

scanf(“%d”,&x);switch(x/5)

{case-1:if(x!=-5)y=x;break;case 0:y=x-1;break;case 1:y=x+1;} printf(“%dn”,y);}

4.本题为了避免考虑每月的天数及闰年等问题,故采用面向对象的程序设计。

现给出Delphi源程序和C++ Builder源程序。

Delphi源程序:

procedure TForm1.Button1Click(Sender: TObject);begin

edit3.Text:=format('%.0f天',[strtodate(edit2.text)-strtodate(edit1.text)]);end;

procedure TForm1.FormCreate(Sender: TObject);begin

Edit2.Text:=datetostr(now);button1click(form1)end;

C++ Builder源程序: void __fastcall TForm1::Button1Click(TObject *Sender){

Edit3->Text=IntToStr(StrToDate(Edit2->Text)-StrToDate(Edit1->Text))+“天”;}

void __fastcall TForm1::FormCreate(TObject *Sender){

Edit2->Text=DateToStr(Now());Button1Click(Form1);}

执行结果:(运行于Windows下)http://img378.photo.163.com/nxgt/41463572/1219713927.jpg

5.源程序:

main()

{unsigned a,b,c;

printf(“请输入三个整数:”);

scanf(“%d %d %d”,&a,&b,&c);

if(a&&b&&c&&a==b&&a==c)printf(“构成等边三角形n”);else if(a+b>c&&a+c>b&&b+c>a)

if(a==b||a==c||b==c)printf(“构成等腰三角形n”);else printf(“构成一般三角形n”);else printf(“不能构成三角形n”);} 执行结果:

请输入三个整数:5 6 5 构成等腰三角形

6.源程序:

main(){int x,y;

scanf(“%d”,&x);if(x<20)y=1;else switch(x/60)

{case 0:y=x/10;break;default:y=6;}

printf(“x=%d,y=%dn”,x,y);} 7.源程序:

main()

{unsigned m;float n;scanf(“%d”,&m);if(m<100)n=0;

else if(m>600)n=0.06;else n=(m/100+0.5)/100;

printf(“%d %.2f %.2fn”,m,m*(1-n),m*n);} 执行结果:

450 450 429.75 20.25

8.2171天(起始日期和终止日期均算在内)

本题可利用第4小题编好的程序进行计算。把起始日期和终止日期分别打入“生日”和“今日”栏内,单击“实足年龄”按钮,将所得到的天数再加上1天即可。

9.源程序:

#include “math.h”;main()

{unsigned long i;scanf(“%ld”,&i);

printf(“%ld %dn”,i%10,(int)log10(i)+1);} 执行结果:

99887 7 5

10.源程序:

main()

{unsigned long i;unsigned j[10],m=0;scanf(“%ld”,&i);

for(;i;){j[m++]=(i+2)%10;i/=10;} for(;m;m--)i=i*10+j[m-1];printf(“%ldn”,i);} 执行结果:

6987 8109

(注:要加密的数值不能是0或以0开头。如果要以0开头需用字符串而不能是整数。)第6章 循环结构程序设计

一、单项选择题(第142页)1-4.BCCB 5-8.CBCA

二、填空题(第143页)

1.原题可能有误。如无误,是死循环 2.原题有误。如果把b=1后面的逗号改为分号,则结果是8。3.20 4.11 5.2.400000 6.*#*#*#$ 7.8 5 2 8.①d=1.0 ②++k ③k<=n 9.①x>=0 ②x

三、编程题(第145页)1.源程序:

main()

{int i=1,sum=i;

while(i<101){sum+=i=-i-2;sum+=i=-i+2;} printf(“%dn”,sum);} 执行结果: 51

2.源程序: main()

{double p=0,n=0,f;int i;for(i=1;i<=10;i++){scanf(“%lf”,&f);

if(f>0)p+=f;else n+=f;}

printf(“%lf %lf %lfn”,p,n,p+n);} 3.源程序:

main()

{unsigned a;scanf(“%ld”,&a);

for(;a;printf(“%d,”,a%10),a/=10);printf(“b n”);} 执行结果:

23456 6,5,4,3,2 4.源程序:

main()

{unsigned long a,b,c,i;scanf(“%ld%ld”,&a,&b);c=a%1000;

for(i=1;i

57 009 5.略

6.原题提供的计算e的公式有误(前面漏了一项1)。正确的公式是e= 1 + 1 + 1/2!+ 1/3!+ … + 1/n!+ …(1)源程序:

main()

{double e=1,f=1;int n;

for(n=1;n<=20;n++){f/=n;e+=f;} printf(“e=%.14lfn”,e);} 执行结果:

e=2.7***05(2)源程序:

main()

{double e=1,f=1;int n;

for(n=1;f>1e-4;n++){f/=n;e+=f;} printf(“e=%.4fn”,e);} 执行结果:

e=2.7183 7.源程序:

main()

{unsigned long a=0,b=1,c=0;int i,d;scanf(“%d”,&d);

for(i=1;i<=(d+2)/3;i++)

printf(“%10ld%10ld%10ld”,a,b,(a+=b+c,b+=c+a,c+=a+b));} 本题还可以用递归算法(效率很低),源程序如下:

unsigned long fun(int i)

{return i<=3?i:fun(i-1)+fun(i-2)+fun(i-3);} main()

{int i,d;scanf(“%d”,&d);for(i=1;i<=d;i++)

printf(“%10ld”,fun(i));} 执行结果:

68

230 423 778 1431 2632 4841 8.源程序:

main(){int i;

for(i=1010;i<=9876;i+=2)

if(i/100%11&&i%100%11&&i/10%100%11&&i/1000!=i%10&&i/1000!=i/10%10&&i/100%10!=i%10)printf(“ %d”,i);} 执行结果:

1024 1026 1028 1032 1034 1036 …… …… 9874 9876 9.源程序:

main(){int i,j,k;

printf(“apple watermelon pearn”);for(i=1;i<=100;i++)for(j=1;j<=10;j++)

if((k=100-i-j)*2==400-i*4-j*40)printf(“%4d%7d%9dn”,i,j,k);} 执行结果:

apple watermelon pear 5 5 90 24 4 72 43 3 54 62 2 36 81 1 18 10.源程序:

#include “stdio.h”;

#define N 4 /* N为阶数,可以改为其他正整数 */ main(){int m=N*2,i,j;

for(i=1;i

putchar(N-abs(i-N)<=abs(j++-N)?' ':'*'));} 如果把N值改为5,则执行结果如下:

* *** ***** ******* ********* ******* ***** *** *

作者:宁西贯通 2006-5-7 23:41 回复此发言

------------------说明

注意:上面最后一题的输出结果应该是由星号组成的一个菱形,第7章 数 组

一、单项选择题(第192页)1-4.BBCC 5-8.AABA

二、填空题(第194页)

1.1 2 4 8 16 32 64 128 256 512

2.①a[age]++ ②i=18;i<26 3.①break ②i==8

4.①a[i]>b[j] ②i<3 ③j<5

5.①b[j]=a[j][0] ②b[j]

三、编程题(第196页)1.源程序:

main()

{int a[4][4],i,j,s=0;for(i=0;i<4;i++)for(j=0;j<4;j++)scanf(“%d”,&a[i][j]);for(i=0;i<4;i++)for(j=0;j<4;j++)

if(i==j||i+j==3)s+=a[i][j];

printf(“%dn”,s);} /* 注:5×5矩阵不能照此计算!*/ 执行结果: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 68

2.源程序:

main()

{int i,a[36];a[0]=2;

for(i=1;i<=29;i++)a[i]=a[i-1]+2;for(;i<=35;i++)a[i]=a[(i-30)*5+2];for(i=0;i<=35;i++)printf(“%dt”,a[i]);} 执行结果: 4 6 8 10 12 14 16 18 20 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 6 16 26 36 46 56 3.源程序:

#include “stdlib.h” #include “time.h” main()

{int a[30],i,m=0;randomize();

for(i=0;i<=29;i++){a[i]=rand();if(m

for(i=0;i<=29;i++)if(a[i]==m)a[i]=-1;printf(“n-----------------n”);for(i=0;i<=29;i++)

if(~a[i])printf(“%dt”,a[i]);printf(“n”);} 执行结果:

20679 29377 18589 9034 27083 4959 3438 5241 32278 23344 32499 29305 22340 5927 13031 2161 2583 31855 22977 14283 4851 22038 6992 11394 20887 27381 6293 18347 16414 10210-----------------

20679 29377 18589 9034 27083 4959 3438 5241 32278 23344 29305 22340 5927 13031 2161 2583 31855 22977 14283 4851 22038 6992 11394 20887 27381 6293 18347 16414 10210 4.源程序:

main()

{int i,n=0,b[16];scanf(“%d”,&i);

for(;i;i>>=1)b[n++]=i&1;for(;n;)printf(“%d”,b[--n]);} 执行结果:

9876

10011010010100

本题也可以不用数组。源程序如下:

#include “stdio.h” main(){int i,n;

scanf(“%d”,&i);for(n=16;n;n--){asm ROL i,1

putchar(i&1|48);}

} /* ROL是循环左移的汇编指令 */ 5.源程序:

#include “stdlib.h” #include “time.h” #define M 5 #define N 6 main()

{int a[M][N],i,j,t[M];randomize();

/*生成M行N列随机数*/

for(i=0;i

printf(“%4d”,a[i][j]=random(50));

/*找出每行的最小数,t[M]是第M行的最小数所在的列数*/ for(i=0;i

if(a[i][t[i]]>a[i][j])t[i]=j;

/*比较每个最小数在其所在的列上是否也是最小*/ for(j=0;ja[i][t[j]]){t[j]=-1;break;} }

printf(“-------------------n”);

/*输出在行和列上均为最小的数*/ for(i=0;i

printf(“a[%d,%d]=%dn”,i,t[i],a[i][t[i]]);}

执行结果:

13 20 0 1 20 41 6 16 35 30 3 5 37 8 23 15 6 36 24 29 18 1 1 5 28 21 46 34-------------------a[0,4]=0 a[1,2]=6 a[3,5]=1 a[4,0]=1 6.源程序:

#include “stdlib.h” #include “time.h” #define M 5 #define N 7 main()

{int a[M][N],i,j,t=0;randomize();for(i=0;i

for(j=0;j

{printf(“%4d”,a[i][j]=random(91)+10);a[i][N-1]+=a[i][j];}

printf(“%4dn”,a[i][N-1]);} for(i=1;i

if(a[i][N-1]>a[t][N-1])t=i;if(t)for(j=0;j

{i=a[0][j];a[0][j]=a[t][j];a[t][j]=i;} printf(“-----------------n”);for(i=0;i

第7章 数 组 for(j=0;j

执行结果:

17 32 95 35 20 288 39 48 22 27 73 22 231 51 87 39 71 84 46 378 84 94 97 77 27 26 405 69 50 56 89 37 46 347-----------------

77 27 26 405 39 48 22 27 73 22 231 51 87 39 71 84 46 378 89 17 32 95 35 20 288 69 50 56 89 37 46 347 7.源程序:

#include “stdlib.h” #include “time.h” #define M 5 #define N 6 main()

{int a[M][N],i,j;

struct data{int value,x,y;}max,min;max.value=0;min.value=100;randomize();

for(i=0;i

{printf(“%4d”,a[i][j]=random(100)+1);if(max.value

{max.value=a[i][j];max.x=i;max.y=j;} if(min.value>a[i][j])

{min.value=a[i][j];min.x=i;min.y=j;} }

printf(“-----------------n”);

i=a[0][N-1];a[0][N-1]=max.value;a[max.x][max.y]=i;i=a[M-1][0];a[M-1][0]=min.value;a[min.x][min.y]=i;for(i=0;i

执行结果:

65 30 40 30 26 50 6 61 27 47 16 54 58 76 19 57 74 44 92 71 48 73 57 60 32 73 67-----------------

65 30 92 30 26 50 73 61 27 47 16 54 58 76 19 57 74 44 40 71 48 6 57 60 32 73 67 9.源程序:

main()

{char s[255];int i,j,b=1;printf(“Input a string:”);scanf(“%s”,s);i=strlen(s);

for(j=1;j<=i/2;j++)b=b&&(s[j-1]==s[i-j]);printf(b?“Yesn”:“Non”);} 执行结果:

Input a string:level Yes

10.源程序:

main()

{char s[255],t,max=0,min=0,l,i;printf(“Input a string(length>4):”);gets(s);l=strlen(s);

for(i=0;i

{if(s[max]s[i])min=i;}

t=s[1];s[1]=s[max];s[max]=t;if(min==1)min=max;t=s[l-2];s[l-2]=s[min];s[min]=t;printf(“%sn”,s);} 执行结果:

Input a string(length>4):C++Builder Cu+Beild+r 11.源程序:

main()

{char m[13][10]={“****”,“January”,“February”,“March”, “April”,“May”,“June”,“July”,“August”,“September”, “October”,“November”,“December”};int i,j,k,a,s,n;

printf(“Please input an integer(100..999):”);scanf(“%d”,&n);

printf(“%d:%d+%d+%d=%d, %d%%13=%d, %sn”, n,i,j,k,s,s,a,m[a=((s=(i=n/100)+(j=n/10%10)+(k=n%10))%13)]);} 执行结果:

Please input an integer(100..999):539 539:5+3+9=17, 17%13=4, April 第8章 函 数

一、单项选择题(第241页)

1-5.BCCAA 6-10.CCDDD 11-15.ACACB

二、填空题(第243页)

1.看不出原题的意图。因为要计算1~n的累加和,n应是一个≥1的正整数。可是题目中却出现了n=0的情况。除非另加规定当n=0时1~n的累加和为0,或者把原题中的计算式改为计算0~n的累加和。据此猜测,原题应填为:①return(0)②return(n+sum(n-1))根据题意,如下程序较为合理:

int sum(int n)

{if(n<=0)return(-1);/*-1是出错标志 */ else if(n==1)return(1);else return(n+sum(n-1));}

2.①return(1)②return(n*facto(n-1))

三、编程题(第244页)3.源程序:

main()

{int i,a,b,c;

for(i=100;i<999;i++)

if((a=i/100)*a*a+(b=i/10%10)*b*b+(c=i%10)*c*c==i)printf(“%dt”,i);} 执行结果:

153 370 371 407

8.源程序(非递归算法):

#define P 13 /* P可以改为其他正整数 */

main()

{int a[P],r,c;

for(r=0;r<=P;r++){a[r]=1;

for(c=r-1;c>=1;a[c--]+=a[c-1]);printf(“%*d”,(P-r)*3+1,a[0]);

for(c=1;c<=r;printf(“%6d”,a[c++]));printf(“n”);} }

执行结果:

(应该排列成一个三角形,是贴吧造成现在这个样子的,不是程序有问题)1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1

126 84 36 9 1

210 252 210 120 45 10 1 1 11 55 165 330 462 462 330 165 55 11 1 1 12 66 220 495 792 924 792 495 220 66 12 1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1 9.源程序(递归算法):

#include “stdio.h”

void printOCT(unsigned long n){unsigned long i;

if(i=n>>3)printOCT(i);putchar((n&7)+48);} main()

{unsigned long i;scanf(“%ld”,&i);printOCT(i);} 执行结果:

1234567890 11145401322

本题也可以不用递归算法,源程序请参考第7章第三题4。回复:【C语言】《C语言程序设计教程(第二版)》习题答案

但是不同时间印刷的版本课后题不太一样呢,象我们的是1999年12月第2版,2005年12月第69次印刷的。没有选择填空,应用题和楼主不知道有多少相同的,因为看不到原题。这个比较麻烦呢。

作者:210.77.204.* 2006-5-9 18:38 回复此发言

------------------回复:【C语言】《C语言程序设计教程(第二版)》习题答案

你对照一下主编和出版社,看看对吗?(见说明的第一条。)14 第9章 指 针

一、单项选择题(第276页)

1-5.DCDAC 6-10.CCABC 11-16.AABBB 16-20.DCDBD

二、填空题(第278页)1.①int * ②*z

2.*p++

3.①'' ②++

4.①q=p+1 ②q

max ④*q

三、编程题(第280页)7.源程序:

main()

{int i=0;char c[20];

do{scanf(“%s”,&c);i++;} while(strcmp(c,“stop”));printf(“%dn”,i);} 执行结果:

This car ran form Nanyang to Luoyang without a stop 10

9.源程序:

main()

{char s[255],c[255]={0};int i;gets(s);

for(i=0;s[i];c[s[i++]]++);for(i=0;i<255;i++)

if(c[i])printf(“%c=%dt”,i,c[i]);} 执行结果:

abcedabcdcd

a=2 b=2 c=3 d=3 e=1

第三篇:《C语言程序设计教程(第二版)》习题答案

《C语言程序设计教程(第二版)》习题答案

1.本习题答案是我自己做的,错误和疏漏在所难免。编程题全部调试通过,但选择题和填空题不敢保证全对。

2.凡未指明解题所用的程序设计语言的,均指C语言。

3.凡未指明执行程序所需的操作系统的,均可在DOS下执行。4.本文中文字下面划线的表示输入。

第1章 程序设计基础知识

一、单项选择题(第23页)1-4.CBBC 5-8.DACA

二、填空题(第24页)1.判断条件 2.面向过程编程 3.结构化 4.程序 5.面向对象的程序设计语言 7.有穷性 8.直到型循环 9.算法 10.可读性 11.模块化 12.对问题的分析和模块的划分

三、应用题(第24页)2.源程序: main(){int i,j,k;/* i:公鸡数,j:母鸡数,k:小鸡数的1/3 */ printf(“cock hen chick ”);for(i=1;i<=20;i++)for(j=1;j<=33;j++)

for(k=1;k<=33;k++)

if(i+j+k*3==100&&i*5+j*3+k==100)

printf(“ %d

%d

%d ”,i,j,k*3);} 执行结果: cock hen chick

3.现计算斐波那契数列的前20项。

递推法 源程序: main(){long a,b;int i;a=b=1;for(i=1;i<=10;i++)/*要计算前30项,把10改为15。*/ {printf(“%8ld%8ld”,a,b);a=a+b;b=b+a;}} 递归法 源程序: main(){int i;for(i=0;i<=19;i++)printf(“%8d”,fib(i));} fib(int i){return(i<=1?1:fib(i-1)+fib(i-2));} 执行结果:

233 377 610 987 1597 2584 4181 6765 4.源程序:

#include “math.h”;main(){double x,x0,deltax;x=1.5;do {x0=pow(x+1,1./3);deltax=fabs(x0-x);x=x0;}while(deltax>1e-12);printf(“%.10f ”,x);} 执行结果: 1.3247179572

5.源程序略。(分子、分母均构成斐波那契数列)结果是32.66026079864 6.源程序: main(){int a,b,c,m;printf(“Please input a,b and c:”);scanf(“%d %d %d”,&a,&b,&c);if(a

Please input a,b and c:123 456 789 789 456 123 7.源程序: main(){int a;scanf(“%d”,&a);printf(a%21==0?“Yes”:“No”);} 执行结果: 42 Yes 第2章 C语言概述

一、单项选择题(第34页)1-4.BDCB 5-8.AABC

二、填空题(第35页)1.主 2.C编译系统 3.函数 函数 4.输入输出 5.头 6..OBJ 7.库函数 8.文本

三、应用题(第36页)5.sizeof是关键字,stru、_aoto、file、m_i_n、hello、ABC、SIN90、x1234、until、cos2x、s_3是标识符。

8.源程序: main(){int a,b,c;scanf(“%d %d”,&a,&b);c=a;a=b;b=c;printf(“%d %d”,a,b);} 执行结果: 12 34 34 12 第3章 数据类型与运算规则

一、单项选择题(第75页)1-5.DBACC 6-10.DBDBC 11-15.ADCCC 16-20.CBCCD 21-25.ADDBC 26-27.AB

二、填空题(第77页)1.补码

2.±(10-308~10308)3.int(整数)4.单目 自右相左

5.函数调用

6.a或b

7.1

8.65,89

三、应用题(第78页)1.10 9 2.执行结果: 11 0 0 12 1 第4章 顺序结构程序设计

一、单项选择题(第90页)1-5.DCDAD 6-10.BACBB

二、填空题(第91页)1.一 ;2.5.169000 3.(1)-2002500(2)I=-200,j=2500(3)i=-200 j=2500 4.a=98,b=765.000000,c=4321.000000 5.略 6.0,0,3

7.3

8.scanf(“%lf%lf%lf”,&a,&b,&c);9.13 13.000000,13.000000 10.a=a^c;c=c^a;a=a^c;(这种算法不破坏b的值,也不再定义中间变量。)

三、编程题(第92页)1.仿照教材第27页例2-1。2.源程序: main(){int h,m;scanf(“%d:%d”,&h,&m);printf(“%d ”,h*60+m);} 执行结果: 9:23 563 3.源程序: main(){int a[]={-10,0,15,34},i;for(i=0;i<=3;i++)printf(“%d370C=%g370Ft”,a[i],a[i]*1.8+32);} 执行结果:

-10℃=14°F

0℃=32°F

15℃=59°F

34℃=93.2°F 4.源程序: main(){double pi=3.14***9,r=5;printf(“r=%lg A=%.10lf S=%.10lf ”,r,2*pi*r,pi*pi*r);} 执行结果:

r=5 A=31.4159265359 S=49.3480220054 5.源程序:

#include “math.h”;main(){double a,b,c;scanf(“%lf%lf%lf”,&a,&b,&c);if(a+b>c&&a+c>b&&b+c>a){double s=(a+b+c)/2;printf(“SS=%.10lf ”,sqrt(s*(s-a)*(s-b)*(s-c)));} else printf(“Data error!”);} 执行结果: 4 5 6 SS=9.9215674165 6.源程序: main(){int a=3,b=4,c=5;float d=1.2,e=2.23,f=-43.56;printf(“a=%3d,b=%-4d,c=**%d d=%g e=%6.2f f=%-10.4f** ”,a,b,c,d,e,f);} 7.源程序: main(){int a,b,c,m;scanf(“%d %d %d”,&a,&b,&c);m=a;a=b;b=c;c=m;printf(“%d %d %d ”,a,b,c);} 执行结果: 5 6 7 6 7 5 8.源程序: main(){int a,b,c;scanf(“%d %d %d”,&a,&b,&c);printf(“average of %d,%d and %d is %.2f ”,a,b,c,(a+b+c)/3.);执行结果: 6 7 9 average of 6,7 and 9 is 7.33 9.不能。修改后的源程序如下: main(){int a,b,c,x,y;scanf(“%d %d %d”,&a,&b,&c);x=a*b;y=x*c;printf(“a=%d,b=%d,c=%d ”,a,b,c);printf(“x=%d,y=%d ”,x,y);}

第5章 选择结构程序设计

一、单项选择题(第113页)1-4.DCBB 5-8.DABD

二、填空题(第115页)1.非0 0

2.k==0 3.if(abs(x)>4)printf(“%d”,x);else printf(“error!”);4.if((x>=1&&x<=10||x>=200&&x<=210)&&x&1)printf(“%d”,x);5.k=1(原题最后一行漏了个d,如果认为原题正确,则输出k=%。)6.8!Right!11

7.$$$a=0

8.a=2,b=1

三、编程题(第116页)1.有错。正确的程序如下: main(){int a,b,c;scanf(“%d,%d,%d”,&a,&b,&c);printf(“min=%d ”,a>b?b>c?c:b:a>c?c:a);} 2.源程序: main(){unsigned long a;scanf(“%ld”,&a);for(;a;printf(“%d”,a%10),a/=10);} 执行结果: 12345 54321 3.(1)源程序: main(){int x,y;scanf(“%d”,&x);if(x>-5&&x<0)y=x;if(x>=0&&x<5)y=x-1;if(x>=5&&x<10)y=x+1;printf(“%d ”,y);}(2)源程序: main(){int x,y;scanf(“%d”,&x);if(x<10)if(x>-5)if(x>=0)if(x>=5)y=x+1;else y=x-1;else y=x;printf(“%d ”,y);}(3)源程序: main(){int x,y;scanf(“%d”,&x);if(x<10)if(x>=5)y=x+1;else if(x>=0)y=x-1;

else if(x>-5)y=x;printf(“%d ”,y);}(4)源程序: main(){int x,y;scanf(“%d”,&x);switch(x/5){case-1:if(x!=-5)y=x;break;case 0:y=x-1;break;case 1:y=x+1;} printf(“%d ”,y);} 4.本题为了避免考虑每月的天数及闰年等问题,故采用面向对象的程序设计。现给出Delphi源程序和C++ Builder源程序。Delphi源程序: procedure TForm1.Button1Click(Sender: TObject);begin edit3.Text:=format('%.0f天',[strtodate(edit2.text)-strtodate(edit1.text)]);end;procedure TForm1.FormCreate(Sender: TObject);begin Edit2.Text:=datetostr(now);button1click(form1)end;C++ Builder源程序:

void __fastcall TForm1::Button1Click(TObject *Sender){ Edit3->Text=IntToStr(StrToDate(Edit2->Text)-StrToDate(Edit1->Text))+“天”;} void __fastcall TForm1::FormCreate(TObject *Sender){ Edit2->Text=DateToStr(Now());Button1Click(Form1);} 执行结果:(运行于Windows下)

5.源程序: main(){unsigned a,b,c;printf(“请输入三个整数:”);scanf(“%d %d %d”,&a,&b,&c);if(a&&b&&c&&a==b&&a==c)printf(“构成等边三角形 ”);else if(a+b>c&&a+c>b&&b+c>a)if(a==b||a==c||b==c)printf(“构成等腰三角形 ”);

else printf(“构成一般三角形 ”);

else printf(“不能构成三角形 ”);} 执行结果:

请输入三个整数:5 6 5 构成等腰三角形 6.源程序: main(){int x,y;scanf(“%d”,&x);if(x<20)y=1;else switch(x/60){case 0:y=x/10;break;default:y=6;} printf(“x=%d,y=%d ”,x,y);} 7.源程序: main(){unsigned m;float n;scanf(“%d”,&m);if(m<100)n=0;else if(m>600)n=0.06;

else n=(m/100+0.5)/100;printf(“%d %.2f %.2f ”,m,m*(1-n),m*n);} 执行结果:

450 450 429.75 20.25 8.2171天(起始日期和终止日期均算在内)

本题可利用第4小题编好的程序进行计算。把起始日期和终止日期分别打入“生日”和“今日”栏内,单击“实足年龄”按钮,将所得到的天数再加上1天即可。9.源程序:

#include “math.h”;main(){unsigned long i;scanf(“%ld”,&i);printf(“%ld %d ”,i%10,(int)log10(i)+1);} 执行结果: 99887 7 5 10.源程序: main(){unsigned long i;unsigned j[10],m=0;scanf(“%ld”,&i);for(;i;){j[m++]=(i+2)%10;i/=10;} for(;m;m--)i=i*10+j[m-1];printf(“%ld ”,i);} 执行结果:

6987 8109(注:要加密的数值不能是0或以0开头)第6章 循环结构程序设计

一、单项选择题(第142页)1-4.BCCB 5-8.CBCA

二、填空题(第143页)1.原题可能有误。如无误,是死循环

2.原题有误。如果把b=1后面的逗号改为分号,则结果是8。

3.20

4.11

5.2.400000

6.*#*#*#$

7.8 5 2

8.①d=1.0 ②++k ③k<=n 9.①x>=0 ②x

三、编程题(第145页)1.源程序: main(){int i=1,sum=i;while(i<101){sum+=i=-i-2;sum+=i=-i+2;} printf(“%d ”,sum);} 执行结果: 51 2.源程序: main(){double p=0,n=0,f;int i;for(i=1;i<=10;i++){scanf(“%lf”,&f);

if(f>0)p+=f;else n+=f;} printf(“%lf %lf %lf ”,p,n,p+n);} 3.源程序: main(){unsigned long a;scanf(“%ld”,&a);for(;a;printf(“%d,”,a%10),a/=10);printf(“b ”);} 执行结果: 23456 6,5,4,3,2 4.源程序: main(){unsigned long a,b,c,i;scanf(“%ld%ld”,&a,&b);c=a%1000;for(i=1;i

6.原题提供的计算e的公式有误(前面漏了一项1)。正确的公式是e= 1 + 1 + 1/2!+ 1/3!+ „ + 1/n!+ „(1)源程序: main(){double e=1,f=1;int n;for(n=1;n<=20;n++){f/=n;e+=f;} printf(“e=%.14lf ”,e);} 执行结果:

e=2.7***05(2)源程序: main(){double e=1,f=1;int n;for(n=1;f>1e-4;n++){f/=n;e+=f;} printf(“e=%.4f ”,e);} 执行结果: e=2.7183 7.源程序: main(){unsigned long a=0,b=1,c=0;int i,d;scanf(“%d”,&d);for(i=1;i<=(d+2)/3;i++)printf(“%10ld%10ld%10ld”,a,b,(a+=b+c,b+=c+a,c+=a+b));} 本题还可以用递归算法(效率很低),源程序如下: unsigned long fun(int i){return i<=3?i:fun(i-1)+fun(i-2)+fun(i-3);} main(){int i,d;scanf(“%d”,&d);for(i=1;i<=d;i++)printf(“%10ld”,fun(i));} 执行结果: 15

125

230

423

778 1431 2632 4841 8.源程序: main(){int i;for(i=1010;i<=9876;i+=2)if(i/100%11&&i%100%11&&i/10%100%11&&i/1000!=i%10&&i/1000!=i/10%10&&i/100%10!=i%10)printf(“ %d”,i);} 执行结果:

1024 1026 1028 1032 1034 1036 …… …… 9874 9876 9.源程序: main(){int i,j,k;printf(“apple watermelon pear ”);for(i=1;i<=100;i++)for(j=1;j<=10;j++)

if((k=100-i-j)*2==400-i*4-j*40)

printf(“%4d%7d%9d ”,i,j,k);} 执行结果:

apple watermelon pear

10.源程序:

#include “stdio.h”;#define N 4

/* N为阶数,可以改为其他正整数main(){int m=N*2,i,j;for(i=1;i

putchar(N-abs(i-N)<=abs(j++-N)?' ':'*'));} 如果把N值改为5,则执行结果如下:

*

***

***** ******* ********* *******

*****

***

* 第7章 数 组

一、单项选择题(第192页)1-4.BBCC 5-8.AABA

二、填空题(第194页)1.1 2 4 8 16 32 64 128 256 512(每个数占一行)2.①a[age]++ ②i=18;i<26

3.①break ②i==8 4.①a[i]>b[j] ②i<3 ③j<5

5.①b[j]=a[j][0] ②b[j]

*/

三、编程题(第196页)1.源程序: main(){int a[4][4],i,j,s=0;for(i=0;i<4;i++)for(j=0;j<4;j++)scanf(“%d”,&a[i][j]);for(i=0;i<4;i++)for(j=0;j<4;j++)if(i==j||i+j==3)s+=a[i][j];printf(“%d ”,s);} /* 注:5×5矩阵不能照此计算!*/ 执行结果: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 68 2.源程序: main(){int i,a[36];a[0]=2;for(i=1;i<=29;i++)a[i]=a[i-1]+2;for(;i<=35;i++)a[i]=a[(i-30)*5+2];for(i=0;i<=35;i++)printf(“%dt”,a[i]);} 执行结果: 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 6 26 36 46 56 3.源程序:

#include “stdlib.h” #include “time.h” main(){int a[30],i,m=0;randomize();for(i=0;i<=29;i++){a[i]=rand();

if(m

printf(“%dt”,a[i]);} for(i=0;i<=29;i++)if(a[i]==m)a[i]=-1;printf(“-----------------”);for(i=0;i<=29;i++)if(~a[i])printf(“%dt”,a[i]);printf(“ ”);} 执行结果:

20679 29377 18589 9034 27083 4959 3438 5241 32278 23344 32499 29305 22340 5927 13031 2161 2583 31855 22977 14283 4851 22038 6992 11394 20887 27381 6293 18347 16414 10210-----------------20679 29377 18589 9034 27083 4959 3438 5241 32278 23344 29305 22340 5927 13031 2161 2583 31855 22977 14283 4851 22038 6992 11394 20887 27381 6293 18347 16414 10210 4.源程序: main(){int i,n=0,b[16];scanf(“%d”,&i);for(;i;i>>=1)b[n++]=i&1;for(;n;)printf(“%d”,b[--n]);} 执行结果: 9876 10011010010100 本题也可以不用数组。源程序如下: #include “stdio.h” main(){int i,n;scanf(“%d”,&i);for(n=16;n;n--){asm ROL i,1

putchar(i&1|48);} } /* ROL是循环左移的汇编指令

*/ 5.源程序:

#include “stdlib.h” #include “time.h” #define M 5 #define N 6 main(){int a[M][N],i,j,t[M];randomize();/*生成M行N列随机数*/ for(i=0;i

printf(“%4d”,a[i][j]=random(50));/*找出每行的最小数,t[M]是第M行的最小数所在的列数*/ for(i=0;i

if(a[i][t[i]]>a[i][j])t[i]=j;/*比较每个最小数在其所在的列上是否也是最小*/ for(j=0;j

for(i=0;i

{if(i==j)continue;

if(a[j][t[j]]>a[i][t[j]])

{t[j]=-1;break;}

} printf(“-------------------”);/*输出在行和列上均为最小的数*/ for(i=0;i

printf(“a[%d,%d]=%d ”,i,t[i],a[i][t[i]]);} 执行结果: 19 13 20

0 41 16 35 30 37 23 15

36 24 29 18 28 21 46 34-------------------a[0,4]=0 a[1,2]=6 a[3,5]=1 a[4,0]=1 6.源程序:

#include “stdlib.h” #include “time.h” #define M 5 #define N 7 main(){int a[M][N],i,j,t=0;randomize();for(i=0;i

for(j=0;j

{printf(“%4d”,a[i][j]=random(91)+10);

a[i][N-1]+=a[i][j];}

printf(“%4d ”,a[i][N-1]);} for(i=1;ia[t][N-1])t=i;if(t)for(j=0;j

printf(“%4d”,a[i][j]);} 执行结果:

17 32 95 35 20 288

48 22 27 73 22 231

87 39 71 84 46 378

94 97 77 27 26 405

50 56 89 37 46 347-----------------

94 97 77 27 26 405

48 22 27 73 22 231

87 39 71 84 46 378

17 32 95 35 20 288

50 56 89 37 46 347 7.源程序:

#include “stdlib.h” #include “time.h” #define M 5 #define N 6 main(){int a[M][N],i,j;struct data{int value,x,y;}max,min;max.value=0;min.value=100;randomize();for(i=0;i

for(j=0;j

{printf(“%4d”,a[i][j]=random(100)+1);

if(max.value

{max.value=a[i][j];max.x=i;max.y=j;}

if(min.value>a[i][j])

{min.value=a[i][j];min.x=i;min.y=j;}

} printf(“-----------------”);i=a[0][N-1];a[0][N-1]=max.value;a[max.x][max.y]=i;i=a[M-1][0];a[M-1][0]=min.value;a[min.x][min.y]=i;for(i=0;i

printf(“%4d”,a[i][j]);} 执行结果:

53 74 65 30 40 26 50 61 27

16 54 58 76 19

74 44 92 71 48

57 60 32 73 67-----------------

53 74 65 30 92 26 50 73 61 27

16 54 58 76 19

74 44 40 71 48

57 60 32 73 67 9.源程序: main(){char s[255];int i,j,b=1;printf(“Input a string:”);scanf(“%s”,s);i=strlen(s);for(j=1;j<=i/2;j++)b=b&&(s[j-1]==s[i-j]);printf(b?“Yes ”:“No ”);} 执行结果:

Input a string:level Yes 10.源程序: main(){char s[255],t,max=0,min=0,l,i;printf(“Input a string(length>4):”);gets(s);l=strlen(s);for(i=0;is[i])min=i;} t=s[1];s[1]=s[max];s[max]=t;if(min==1)min=max;t=s[l-2];s[l-2]=s[min];s[min]=t;printf(“%s ”,s);} 执行结果:

Input a string(length>4):C++Builder Cu+Beild+r 11.源程序: main(){char m[13][10]={“****”,“January”,“February”,“March”, “April”,“May”,“June”,“July”,“August”,“September”, “October”,“November”,“December”};int i,j,k,a,s,n;printf(“Please input an integer(100..999):”);scanf(“%d”,&n);printf(“%d:%d+%d+%d=%d, %d%%13=%d, %s ”, n,i,j,k,s,s,a,m[a=((s=(i=n/100)+(j=n/10%10)+(k=n%10))%13)]);} 执行结果:

Please input an integer(100..999):539 539:5+3+9=17, 17%13=4, April 第8章 函

一、单项选择题(第241页)1-5.BCCAA 6-10.CCDDD 11-15.ACACB

二、填空题(第243页)1.看不出原题的意图。因为要计算1~n的累加和,n应是一个≥1的正整数。可是题目中却出现了n=0的情况。除非另加规定当n=0时1~n的累加和为0,或者把原题中的计算式改为计算0~n的累加和。据此猜测,原题应填为:①return(0)②return(n+sum(n-1))根据题意,如下程序较为合理: int sum(int n){if(n<=0)return(-1);/*-1是出错标志 */ else if(n==1)return(1);

else return(n+sum(n-1));} 2.①return(1)②return(n*facto(n-1))

三、编程题(第244页)3.源程序: main(){int i,a,b,c;for(i=100;i<999;i++)if((a=i/100)*a*a+(b=i/10%10)*b*b+(c=i%10)*c*c==i)printf(“%dt”,i);} 执行结果:

153

370

371

407 8.源程序(非递归算法):

#define P 13 /* P可以改为其他正整数

*/ main(){int a[P],r,c;for(r=0;r<=P;r++){a[r]=1;

for(c=r-1;c>=1;a[c--]+=a[c-1]);

printf(“%*d”,(P-r)*3+1,a[0]);

for(c=1;c<=r;printf(“%6d”,a[c++]));

printf(“ ”);} } 执行结果:

126

126

120

210

252

210

120

165

330

462

462

330

165

220

495

792

924

792

495

220

286

715 1287 1716 1716 1287

715

286

9.源程序(递归算法): #include “stdio.h” void printOCT(unsigned long n){unsigned long i;if(i=n>>3)printOCT(i);putchar((n&7)+48);} main(){unsigned long i;scanf(“%ld”,&i);printOCT(i);} 执行结果: 1234567890 11145401322 本题也可以不用递归算法,源程序请参考第7章第三题4。第9章 指

一、单项选择题(第276页)1-5.DCDAC 6-10.CCABC 11-16.AABBB 16-20.DCDBD

二、填空题(第278页)1.①int * ②*z

2.*p++

3.①''

②++ 4.①q=p+1 ②q

max ④*q

三、编程题(第280页)7.源程序: main(){int i=0;char c[20];do{scanf(“%s”,&c);i++;} while(strcmp(c,“stop”));printf(“%d ”,i);} 执行结果:

This car ran form Nanyang to Luoyang without a stop 10 9.源程序: main(){char s[255],c[255]={0};int i;gets(s);for(i=0;s[i];c[s[i++]]++);for(i=0;i<255;i++)if(c[i])printf(“%c=%dt”,i,c[i]);} 执行结果: abcedabcdcd a=2

b=2

c=3

d=3

第10章

结构、联合与枚举类型

一、单项选择题(第326页)1-4.DDAA

e=1

第四篇:80X86语言程序设计教程(杨季文)课后习题答案

第二章 答案

题2.1 8086/8088通用寄存器的通用性表现在何处?8个通用寄存器各自有何专门用途?哪些寄存器可作为存储器寻址方式的指针寄存器? 答:8086/8088通用寄存器的通用性表现在:

这些寄存器除了各自规定的专门用途外,他们均可以用于传送和暂存数据,可以保存算术逻辑运算中的操作数和运算结果; 8个通用寄存器的专门用途如下: AX 字乘法,字除法,字I/O BX 存储器指针

CX 串操作或循环控制中的计数器 DX 字乘法,字除法,间接I/O SI 存储器指针(串操作中的源指针)DI 存储器指针(串操作中的目的指针)BP 存储器指针(存取堆栈的指针)SP 堆栈指针

其中BX,SI,DI,BP可作为存储器寻址方式的指针寄存器

题2.2 从程序员的角度看,8086/8088有多少个可访问的16位寄存器?有多少个可访问的8位 寄存器?

答: 从程序员的角度看,8086/8088有14个可访问的16位寄存器;有8个可访问的8位寄存器;

题2.3 寄存器AX与寄存器AH和AL的关系如何?请写出如下程序片段中每条指令执行后寄存器

AX的内容: MOV AX,1234H MOV AL,98H MOV AH,76H ADD AL,81H SUB AL,35H ADD AL,AH ADC AH,AL ADD AX,0D2H SUB AX,0FFH 答: MOV AX,1234H AX=1234H MOV AL,98H AX=1298H MOV AH,76H AX=7698H ADD AL,81H AX=7619H SUB AL,35H AX=76E4H ADD AL,AH AX=765AH ADC AH,AL AX=D15AH ADD AX,0D2H AX=D22CH SUB AX,0FFH AX=D12DH 题2.4 8086/8088标志寄存器中定义了哪些标志?这些标志可分为哪两类?如何改变这些标志的状态?

答: 8086/8088标志寄存器中定义了9个标志,如下: CF: Carry Flag ZF: Zero Flag SF: Sign Flag OF: Overflow Flag PF: Parity Flag AF: Auxiliary Carry Flag DF: Direction Flag IF: Interrupt-enable Flag TF: Trap Flag

这些标志可分为两类,分别为:

1、运算结果标志;

2、状态控制标志;

采用指令SAHF可把AH中的指定位送至标志寄存器低8位SF、ZF、AF、PF、CF;

采用CLC可清除CF,置CF到0 采用STC可置CF到1 采用CLD可置DF到0 采用sTD可置DF到1 采用CLI可置IF到0 采用STI可置IF到1 另外,在某些指令执行过程中会改变部分标志的状态; 题2.5 请说说标志CF和标志OF的差异。答: 如果把指令中处理的数据按照无符号数看待,则处理结果达到进位是,置CF为1;

如果把该处理中的数据按照有符号数看待,则处理结果超过有符号数表达范围的,置OF为1;两个标志同步进行,CPU并不知道该数的类型;

题2.6 8086/8088如何寻址1M字节的存储器物理地址空间?在划分段时必须满足的两个条件是什么?最多可把1M字节空间划分成几个段?最少可把1M字节地址空间划分成几个段? 答: 8086/8088通过对存储器分段和使用段寄存器的方式寻址1M字节的存储器物理地址空间;

在划分段时必须满足的两个条件是:

1、逻辑段的开始地址必须是16的倍数;

2、逻辑段的嘴道长度是64K;

1M的字节空间划分为64K个逻辑段;最少可把1M字节地址划分成16个逻辑段; 题2.7 在8086/8088上运行的程序某一时刻最多可访问几个段?程序最多可具有多少个段?程序至少几个段?

答: 在8086/8088上运行的程序某一时刻最多可访问4个当前段:代码段,数据段,堆栈段和附加段;程序最多可具有4种类型的段,最少要有一个代码段; 题2.8 存储单元的逻辑地址如何表示?存储单元的20位物理地址如何构成? 答: 存储单元的逻辑地址由段值和偏移两部分组成:段值:偏移;

存储单元的20位物理地址可以表示为:

物理地址=段值×16+偏移;

题2.9 当段重叠时,一个存储单元的地址可表示成多个逻辑地址。请问物理地址12345H可表示多少个不同的逻辑地址?偏移最大的逻辑地址是什么?偏移最小的逻辑地址是什么?

答: 12345H可表示1000H(4096)个不同的逻辑地址,偏移最大的逻辑地址是235:0FFF5H 偏移最小的逻辑地址是1234:0005H 题2.10 为什么称CS为代码段寄存器?为什么称SS为堆栈寄存器?

答: 因为在取指令的时候,规定的段寄存器就是CS,所以CS为代码段寄存器;

而堆栈操作时规定的寄存器是SS,所以SS为堆栈寄存器; 题2.11 请举例说明何为段前缀超越。什么场合下要使用段前缀超越? 答: 在存取一般存储器操作数时,段寄存器可以不是DS;当偏移设计BP寄存器时,段寄存器也可以不必是SS;如Mov AX,[si] 默认段地址在DS中,也可以改变:Mov AX, ES:[si] 当数据并不在默认的DS指定段时,可以采用段前缀超越; 题2.12 8086/8088的基本寻址方式可分为哪三类?他们说明了什么? 答: 8086/8088的基本寻址方式可分为以下三类:

1、存储器寻址;

2、立即寻址;

3、寄存器寻址;

他们说明了cpu有三类合计七种方式进行基本寻址;

题2.13 存储器寻址方式分为哪几种?何为存储器的有效地址? 答: 存储器寻址方式分为以下几种:

1、立即寻址;

2、直接寻址;

3、寄存器寻址;

4、寄存器间接寻址;

5、寄存器相对寻址;

6、基址加变址寻址;

7、相对基址加变址寻址;

存储器的有效地址是一个16bit的无符号数; 题2.14 什么场合下缺省的段寄存器是SS?为什么这样安排? 答: 当使用堆栈时,缺省的段寄存器是SS;

因为SS定义为堆栈段寄存器,配合SP堆栈指针,用来指向堆栈的栈顶; 题2.15 请说明如下指令中源操作数的寻址方式,并作相互比较: MOV BX,[1234H] MOV BX,1234H MOV DX,BX MOV DX,[BX] MOV DX,[BX+1234H] MOV DX,[BX+DI] MOV DX,[BX+DI+1234H] 答: MOV BX,[1234H] ;直接寻址 MOV BX,1234H :立即寻址 MOV DX,BX :寄存器寻址 MOV DX,[BX] :寄存器间接寻址 MOV DX,[BX+1234H] :寄存器相对寻址 MOV DX,[BX+DI] :基址加变址寻址 MOV DX,[BX+DI+1234H] :相对基址加变址寻址

题2.16 8086/8088提供了灵活多样的寻址方式,如何适当的选择寻址方式? 答: 每种寻址方式都有其特点,首先应该掌握不同寻址方式之间的区别,以及 适用的范围,结合程序中的需要进行灵活选择。

题2.17 设想一下这些寻址方式如何支持高级语言的多种数据结构? 答: 自己设想!

题2.18 为什么目标操作数不能采用立即寻址方式?

答: 立即寻址表示是一个操作数,并非一个存储空间,作为目标操作数是不合适的;

题2.19 处理器的通用寄存器是否越多越好?通用寄存器不够用怎么办?

答: 处理器的通用寄存器并非越多越好,因为如果处理器的通用寄存器数量太多,势必造成处理器的成本增加,同时也增加了处理器设计的复杂度;

如果通用寄存器不够用,应该采用内存中的存储单元代替,不过速度上要有所牺牲; 题2.20 哪些存储器寻址方式可能导致有效地址超出64K的范围?8086/8088如何处理这种 情况?

答: 寄存器相对寻址,基址加变址寻址,相对基址加变址寻址这三种寻址方式有可能导致有效地址超出64K的范围,8086/8088将取其64K的模进行访问;

题2.21 什么情况下根据段值和偏移确定的存储单元地址会超出1M?8086/8088如何处理这种情况?

答: 当物理地址的计算超过FFFFFH时,存储单元地址会超出1M,8086/8088将取其1M的模覆盖存取; 题2.22 8086/8088的指令集可分为哪6个子集? 答: 8086/8088的指令集可分为以下6个子集:

1、数据传输

2、算术运算

3、逻辑运算

4、串操作

5、程序控制

6、处理器控制

题2.23 8086/8088的指令集合中,最长的指令有几个字节?最短的指令有几个字节? 答: 8086/8088的指令集合中,最长的指令4个字节,最短的指令2个字节; MOV AX,[BX+SI+1234H]

题2.24 8086/8088的算术逻辑运算指令最多一次处理多少二进制位?当欲处理的数据 长度超出该范围怎么办?

答: 8086/8088的算术逻辑运算指令最多一次处理16bit的二进制位;如果处理的数据长度超出则分成若干部分进行逻辑运算,最后进行整合; 题2.25 如何时序数据段和代码段相同?

答: 将数据段的内容写入代码段中,并将代码段的段值赋给DS即可;

题2.26 通常情况下源操作数和目的操作数不能同时是存储器操作数。请给出把存储器操作

数甲送到存储器操作数乙的两种方法。答:

法一: MOV AX, [BX] MOV [SI],AX DS:[BX]=甲,DS:[SI]=乙

法二: MOV AX,[BX] XCHG AX,[SI] 法三:

PUSH WORD PTR [BX] POP WORD PTR [SI] 题2.27 请用一条指令实现把BX的内容加上123并把和送到寄存器AX。答: LEA AX, [BX+123H] 题2.28 堆栈有哪些用途?请举例说明。答: 堆栈的用途主要有:

1、现场和返回地址的保护; MOV AX, OFFSET ADDRESS PUSH AX JMP XXX...RET

2、寄存器内容的保护; PUSH AX PUSH BX...POP BX POP AX

3、传递参数; PUSH [BX] CALL XXX...XXX: POP AX...4、存储局部变量; PUSH DS PUSH CS POP DS...POP DS 题2.29 在本章介绍的8086/8088指令中,哪些指令把寄存器SP作为指针使用?8086/8088指令集中,哪些指令把寄存器SP作为指针使用? 答: 以下指令把寄存器SP作为指针使用:

1、PUSH

2、POP

3、PUSHF

4、POPF

5、PUSHA

6、POPA

7、RET

8、CALL

9、RETF

题2.30 请说说标志CF的用途。请至少给出使标志CF清0的三种方法。答: CF的用途主要有:

1、配合条件转移语句进行条件转移;

2、配合移位指令实现操作数之间的位转移;

3、常作为子程序的出口参数;如DOS磁盘文件管理功能调用等; CF清0的方法:

法一: CLC 法二: ADD AX,0FFFFH 法三: CMP AX,0 题2.31 请写出如下程序片段中每条算术运算指令执行后标志CF、ZF、SF、OF、PF和AF的状态。

MOV AL,89H ADD AL,AL ADD AL,9DH CMP AL,0BCH SUB AL,AL DEC AL INC AL 答:

INSTRUCTION CF ZF SF OF PF AF MOV AL,89H 0 0 0 0 0 0 ADD AL,AL 1 0 0 1 1 1 ADD AL,9DH 0 0 1 0 1 0 CMP AL,0BCH 1 0 1 0 1 0 SUB AL,AL 0 1 0 0 1 0 DEC AL 0 0 1 0 1 1 INC AL 0 1 0 0 1 1

题2.32 什么是除法溢出?如何解决16位被除数8位除数可能产生的溢出?

答: 除法溢出是指除数如果是0,或者在8位除数时商超过8位,或者在16位除时商超过16位,则认为是除法溢出,引起0中断;

首先要确定8位除数不能为0,其次要确定商的最大值不能超过8位,如果超过8位,则可 采用16位的除法;

题2.33 请写出如下程序片段中每条逻辑运算指令执行后标志ZF、SF、PF的状态: MOV AL,45H AND AL,0FH OR AL,0C3H XOR AL,AL

答: INSTRUCTION ZF SF PF MOV AL,45H 0 0 0 AND AL,0FH 0 0 1 OR AL,0C3H 0 1 0 XOR AL,AL 1 0 1

题2.34 “MOV AX,0”可寄存器AX清0。另外再写出三条可使寄存器AX清0的指令。答: 法一: XOR AX,AX 法二: AND AX,0 法三: SUB AX,AX

题2.35 请写出如下程序片段中每条移位指令执行后标志CF、ZF、SF和PF的状态。MOV AL,84H SAR AL,1 SHR AL,1 ROR AL,1 RCL AL,1 SHL AL,1 ROL AL,1 答:

INSTRUCTION CF ZF SF PF MOV AL,84H 0 0 0 0 SAR AL,1 0 0 1 0 SHR AL,1 0 0 0 0 ROR AL,1 1 0 0 0(该命令不影响SF位)RCL AL,1 1 0 0 0 SHL AL,1 0 0 1 0 ROL AL,1 1 0 1 0

题2.36 8086/8088中,哪些指令把寄存器CX作为计数器使用?哪些指令把寄存器BX作为基指针寄存器使用?

答: 8086/8088中,以下指令把寄存器CX作为计数器使用:

1、LOOP

2、LOOPE

3、LOOPZ

4、LOOPNZ

5、LOOPNE

6、JCXZ

以下指令把寄存器BX作为基指针寄存器使用:

1、MOV

2、XCHG

3、LEA

4、LDS

5、LES

6、ADD...题2.37 请不用条件转移指令JG、JGE、JL和JLE等指令实现如下程序片段的功能: CMP AL,BL JGE OK XCHG AL,BL OK:......答: 如下命令可实现同样功能: PUSH CX;Reserve CX XOR CX,CX;CX=0 MOV CH,02H;CH=02H MOV CL,AL;CL=AL MOV BH,0H;BH=0 SUB CX,BX;If CH=2, AL>=BL;If CH=1, AL

题2.39 8086/8088的条件转移指令的转移范围有多大?如何实现超出范围的条件转移? 答: 8086/8088的条件转移指令的转移范围只能从-126到+129之间,如果出现超出 范围的条件转移,要借助无条件转移命令JMP;

题2.40 相对转移和绝对转移的区别是什么?相对转移的有何优点?

答: 相对转移和绝对转移的区别是相对转移记录了目标地址与当前地址的差值,而绝对转移在转移命令中直接包含了目标地址;

相对转移有利于程序的浮动,比如说增加了命令语句等; 题2.41 请指出下列指令的错误所在: MOV CX,DL XCHG [SI],3 POP CS MOV IP,AX SUB [SI],[DI] PUSH DH OR BL,DX AND AX,DS MUL 16 AND 7FFFH,AX DIV 256 ROL CX,BL MOV ES,1234H MOV CS,AX SUB DL,CF ADC AX,AL MOV AL,300 JDXZ NEXT

答: MOV CX,DL XCHG [SI],3 POP CS MOV IP,AX SUB [SI],[DI] PUSH DH OR BL,DX AND AX,DS MUL 16 AND 7FFFH,AX DIV 256 ROL CX,BL MOV ES,1234H 转

MOV CS,AX SUB DL,CF ADC AX,AL MOV AL,300

POP指令的对象不能是CS,PUSH可以 IP不能是源也不能是目的

PUSH和POP只能处理16位的操作数(8086/8088)

BL不可以作为操作数

CS不能为目的 CF是Flag中的一个bit,不能如此

300超过0FFh,Over 8bit

;寄存器大小不一;不能与立即数进行交换;;;如果参与的操作数有两个,只能有一个是存储器操作数 ;;寄存器大小不一;段寄存器不可以是操作数;不可以使用立即数;立即数不能是目的操作数;不可以使用立即数;;段寄存器为目的时,源不能是立即数,需由通用寄存器;代码段寄存器;;寄存器大小不一; JDXZ NEXT ;JCXZ

题2.42 请指出如下指令哪些是错误的,并说明原因: MOV [SP],AX PUSH CS JMP BX+100H JMP CX ADD AL,[SI+DI] SUB [BP+DI-1000],AL ADD BH,[BL-3] ADD [BX],BX MOV AX,BX+DI LEA AX,[BX+DI] XCHG ES:[BP],AL XCHG [BP],ES

答: MOV [SP],AX ;SP非有效寄存器间接寻址之寄存器 PUSH CS ;对 JMP BX+100H ;对 JMP CX ;对

ADD AL,[SI+DI] ;SI和DI只能出现一个,与BX,BP一致 SUB [BP+DI-1000],AL ;对

ADD BH,[BL-3] ;BL只是一个8bit寄存器 ADD [BX],BX ;对 MOV AX,BX+DI ;对 LEA AX,[BX+DI] ;对 XCHG ES:[BP],AL ;对

XCHG [BP],ES ;段寄存器不能是操作数

题2.43 下列程序片段完成什么功能,可否有更简单的方法实现同样的功能: XCHG AX,[SI] XCHG AX,[DI] XCHG AX,[SI]

答: 程序实现[SI]和[DI]中的内容交换;AX中内容不变;

有,如下: PUSH [SI] PUSH [DI] POP [SI] POP [DI]

题2.44 请比较如下指令片段: LDS SI,[BX]

MOV SI,[BX] MOV DS,[BX+2]

MOV DS,[BX+2] MOV BX,[BX]

答: LDS SI,[BX] ;DS=[BX+2],SI=[BX]

MOV SI,[BX];DS=[BX+2],SI=[BX] MOV DS,[BX+2]

MOV DS,[BX+2];DS=[BX+2],BX=[BX] MOV BX,[BX] 第一组和第二组功能一致;

第三章答案

题3.1 伪指令语句与指令语句的本质区别是什么?伪指令的主要作用是什么?

答: 伪指令语句与指令语句的本质区别是指令语句有其对应的机器指令,而伪指令没有;

伪指令的主要作用是指示汇编程序如何汇编源程序;

题3.2 汇编语言中的表达式与高级语言中的表达式有何相同点和不同点? 答: 汇编语言中的表达式与高级语言中的表达式的相同点是都采用运算符、操作符以及括号把常数和符合连起来;

不同点是汇编语言的表达式除了数值表达式外还有地址表达式;

题3.3 汇编语言中数值表达式与地址表达式有何区别? 答: 汇编语言中数值表达式在汇编过程中由汇编程序计算出数值,而地址表达式中部分相对地址的地方,在汇编时无法确定其确定地址;

题3.4 汇编语言中的变量和标号有何异同之处?

答: 汇编语言中的变量和标号的相同之处是都代表着一个地址; 不同之处是变量表示的地址中存放的是数据,而标号表示的地址中存放的是代码;

题3.5 请计算如下各数值表达式的值:

23H AND 45H OR 67H 1234H/16+10H NOT(65535 XOR 1234H)1024 MOD 7+3 LOW 1234 OR HIGH 5678H 23H SHL 4 “Eb” GE 4562H XOR-1 1234H SHR 6 'a' AND(NOT('a'-'A')'H' OR 00100000B 76543Q LT 32768 XOR 76543 3645H AND 0FF00H

答: 23H AND 45H OR 67H;67H 1234H/16+10H;133H NOT(65535 XOR 1234H);1234H 1024 MOD 7+3;5 LOW 1234 OR HIGH 5678H;D6H 注意1234 不是1234H 23H SHL 4;30H “Eb” GE 4562H XOR-1;0 1234H SHR 6;0048H 'a' AND(NOT('a'-'A');41H or 'A' 'H' OR 00100000B;68H or 'h' 76543Q LT 32768 XOR 76543;题目最后的76543有错,按照76543Q处理:829CH 3645H AND 0FF00H;3600H

题3.6 请计算如下程序片段中各地址表达式的值,设BX=1000H,SI=2000H,DI=3000H,BP=4000H [BX+100H] [DI][BP] 2000H[SI] 10H[BX][SI] [BP-128] [BX][DI-2]

答: [BX+100H];[1100H] [DI][BP];[7000H] 2000H[SI];[4000H] 10H[BX][SI];[3010H] [BP-128];[3F80H] [BX][DI-2];[3FFEH]

题3.7 设在某个程序中有如下片段,请写出每条传送指令执行后寄存器AX的内容:

ORG 100H VARW DW 1234H,5678H VARB DB 3,4 VARD DD 12345678H BUFF DB 10 DUP(?)MESS DB 'HELLO' BEGIN: MOV AX,OFFSET VARB + OFFSET MESS MOV AX,TYPE BUFF + TYPE MESS + TYPE VARD MOV AX,SIZE VARW + SIZE BUFF + SIZE MESS MOV AX,LENGTH VARW + LENGTH VARD MOV AX,LENGTH BUFF + SIZE VARW MOV AX,TYPE BEGIN MOV AX,OFFSET BEGIN

答: ORG 100H VARW DW 1234H,5678H VARB DB 3,4 VARD DD 12345678H BUFF DB 10 DUP(?)MESS DB 'HELLO' BEGIN: MOV AX,OFFSET VARB + OFFSET MESS;AX=0218H MOV AX,TYPE BUFF + TYPE MESS + TYPE VARD;AX=0006H MOV AX,SIZE VARW + SIZE BUFF + SIZE MESS;AX=000DH MOV AX,LENGTH VARW + LENGTH VARD;AX=0002H MOV AX,LENGTH BUFF + SIZE VARW;AX=000CH MOV AX,TYPE BEGIN;AX=FFFFH MOV AX,OFFSET BEGIN;AX=0119H

题3.8 设如下两条指令中的符号ABCD是变量名,请说明这两条指令的异同。

MOV AX,OFFSET ABCD LEA AX,ABCD

答: 两条指令都是将ABCD的偏移地址放入AX寄存器中;

不同之处是OFFSET只能取得用数据定义伪指令的变量的有效地址,而不能取得一般操作数的有效地址;

题3.9 请指出如下指令的不明确之处,并使其明确:

MOV ES:[BP],5 ADD CS:[1000H],10H DEC SS:[BX-8] JMP CS:[SI+1000H] MUL [BX+DI+2] DIV [BP-4]

答: MOV ES:[BP],5 ;未指定存储单元属性 MOV WORD PTR ES:[BP],5 ADD CS:[1000H],10H ;同上 ADD WORD PTR CS:[1000H],10H DEC SS:[BX-8] ;同上 DEC WORD PTR SS:[BX-8] JMP CS:[SI+1000H] ;无法确定段间还是段内转移

JMP WORD PTR CS:[SI+1000H] MUL [BX+DI+2] ;无法确定是8位乘法还是16位乘法

MUL WORD PTR [BX+DI+2] DIV [BP-4] ;同上 DIV WORD PTR [BP-4]

题3.10 设在某个程序中有如下片段,请改正其中有错误的指令语句:

VARW DW 1234H,5678H VARB DB 3,4 VARD DD 12345678H......MOV AX,VARB MOV VARD,BX MOV VARD+2,ES MOV CL,VARW+3 LES DI,VARW

答: MOV AX,VARB ;VARB是8bit量,应该修改AX到AL or AH MOV VARD,BX ;VARD是32bit量,要分两次传

MOV VARD+2,ES ;同上

MOV CL,VARW+3 ;同上,CL改为CX LES DI,VARW ;VARW非32位量,应改为VARD

题3.11 请举例说明伪指令ASSUME的作用。

答: ASSUME的作用是声明现在开始CS寄存器对应于哪个段,DS对应于哪个段,SS和ES分别对应哪个段,可以相同也可以不同;如:

ASSUME CS:CSEG,DS:DSEG,SS:SSEG,ES:ESEG 可以根据需要重新建立对应关系;

题3.12 设在某个程序片段中有如下语句,请说明各符号的属性:

SYMB1 LABEL BYTE SYMB2 EQU THIS BYTE SYMB3 DW ? SYMB4 EQU BYTE PTR SYMB3

答: SYMB1:BYTE SYMB2:BYTE SYMB3:WORD SYMB4:BYTE 题3.13 为什么说汇编语言中的等价语句EQU可理解为简单的宏定义?请举例说明。答: EQU可以用符号定义常数,表达式,指令助记符,字符串等;

而宏定义是指定一个宏指令名,宏指令可表示相对应的程序片段。

如:

HELLO EQU “How are you!” 与:

HELLO MACRO 'How are you!' ENDM 一致;

题3.14 设在某个程序片段中有如下语句,请说明各符号所表示的值:

SYMB1 = 10 SYMB2 = SYMB1*2 SYMB1 = SYMB1 + SYMB2 + 4 SYMB3 EQU SYMB1

答: SYMB1 = 22H SYMB2 = 14H SYMB3 = 22H

题3.15 请改写3.3.3的程序T3-1.ASM,使其只有一个段。答:;程序名:T3-1.ASM;功能 :显示信息“HELLO" cseg segment assume cs:cseg mess db 'HELLO',0dh,0ah,'$' start: mov ax,cseg mov ds,ax mov dx,offset mess mov ah,9 int 21h mov ah,4ch int 21h cseg ends end start

题3.16 请说明指令”JMP $+2“指令的机器码中的地址差值是多少? 答: 2H 题3.17 源程序是否一定要以END语句结束?程序是否一定从代码段的偏移0开始执行?

如果不是,那么如何指定?

答: 源程序可以不以END语句结束,不过END之后的内容汇编程序将忽略。程序不一定要从代码的偏移0开始执行,一个比较简单的方法是利用END语句,如END XXX,程序将从XXX标号处开始执行;

题3.18 利用查表的方法实现代码转换有何特点?利用查表的方法求函数值有何特点? 答: 利用查表的方法实现代码转换的特点是:

1、转换代码间不需要直接的算术或逻辑关系,只需要安排好表的组织即可;

2、对于部分代码,其转换效率比较高,主要时间用在寻址上;

利用查表的方法求函数值的特点是:

1、对于大部分的数学函数值的求值,直接计算困难较大,采用查表法可祢补

不足;

2、程序比较简单;

3、能够得到十进制或者十六进制格式的高精度函数值。

4、函数值必须事先计算好;

5、精度无法由程序控制;

题3.19 利用地址表实现多向分支有何特点?请举例说明。答: 利用地址表实现多向分支的特点有:

1、对于实现5路以上的多向分支,使用地址表既方便又高效;

2、对于如何确定地址的位置,需要采用不同的方法实现;

例子看书。

题3.20 请举例说明如何避免条件转移超出转移范围。

答: 如果出现条件转移超出了范围,则可以利用无条件转移指令帮助跳转;

如:

cmp ax,'A' jb out_program

如果超出范围:

cmp ax,'A' jb out_com...out_com: jmp far ptr out_program

题3.21 请写一个程序片段统计寄存器AX中置1的个数。答: count db ?,?,0dh,0ah,'$'......call countAX

cmp bl,9 ja sub10 jmp go sub10: sub bl,10 mov count,31h go: add bl,30h mov count+1,bl mov dx,offset count mov ah,9 int 21h mov ah,4ch int 21h;==============================;入口:AX;出口:BL=AX中1的个数

countAX proc mov cx,16 mov bl,0 count1: shl ax,1 jnc ADDAX1 add bl,1 ADDAX1: loop count1 ret countAX endp;=============================

题3.22 设一个32位有符号数存放在DX:AX中,请写一个求其补码的程序片段。

答: Invert proc mov bx,dx and bx,8000h cmp bx,0 jz out_1 not dx not ax add ax,1 adc dx,0 or dx,8000h out_1: nop ret Invert endp

题3.23 写一个程序片段实现如下功能:依次重复寄存器AL中的每一位,得到16位的结果存

放到DX寄存器中。

答: Expand proc mov cx,7 xor dx,dx

S0: shl dx,1 shl dx,1 shl al,1 jnc CF0 add dx,3h CF0: nop loop S0 ret Expand endp

题3.24 写一个程序片段实现如下功能:依次重复四次寄存器AL中的每一位,得到32位的结果

存放到DX:AX寄存器中。

答: Expand proc mov cx,3 xor dx,dx xor bx,bx S0: shl al,1 jnc CF0 add dx,0Fh CF0: shl dx,1 shl dx,1 shl dx,1 shl dx,1 loop S0

mov cx,4 S1: shl al,1 jnc CF0_1 add bx,0Fh CF0_1: shl bx,1 shl bx,1 shl bx,1 shl bx,1 loop S1 mov ax,bx ret Expand endp

题3.25 写一个程序片段实现如下功能:把寄存器AL和BL中的位依次交叉,得到的16位结果

存放到DX寄存器中。

答: Expand proc mov cx,8 xor dx,dx S0: shl dx,1 shl al,1 jnc CF0 add dx,1h CF0: shl dx,1 shl bl,1 jnc CF0_1 add dx,1h CF0_1: loop S0 ret Expand endp

题3.26 写一个优化的程序片段,实现把字符串中的小写子母变换为对应的大写子母。设字符串

以0结尾。

答: InvertC proc begin: mov al,mess[si] cmp al,'0' jz exit_1 cmp al,61h jb next cmp al,7AH ja next and al,11011111b mov mess[si],al next: inc si jmp begin exit_1: nop ret InvertC endp

题3.27 写一个优化的程序片段,统计字符串的长度。设字符串以0结尾。答: count proc mov al,mess[si] cmp al,'0' jz exit_2 inc si jmp count exit_2: nop ret count endp;si=数量

题3.28 写一个程序片段,滤去某个字符串中的空格符号(ASCII码20H),设字符串以0结尾。

答: DeleteSpace proc;设si=0,bx=0,Mess为字符串首地址

mov al,mess[si] cmp al,'0' jz exit_2 cmp al,' ' jz next3 xchg al,mess[bx] xchg al,mess[si] inc bx next3: inc si jmp DeleteSpace exit_2: nop ret DeleteSpace endp 题3.29 请写一个把两个字符串合并的示例程序。答: dseg segment string1 db 'Welcome to $' string2 db 'Beijing!$' dseg ends

cseg segment assume cs:cseg,ds:dseg start: mov ax,dseg mov ds,ax

xor bx,bx xor si,si

keepfind: mov al,string1[bx] cmp al,'$' jz combine inc bx jmp keepfind combine: mov al,string2[si] mov string1[bx],al cmp al,'$' jz exit inc si inc bx jmp combine exit:

mov dx,offset string1 mov ah,09h int 21h

mov ah,4ch int 21h cseg ends end start 题3.30 请写一个可把某个字变量的值传唤为对应二进制数ASCII码串的示例程序。答:;Name : Show_hex_ascii;input : ah=Hex;output: dx='Hex' show_hex_ascii proc

mov dh,ah and dh,0f0h;reserve high 4bit shr dh,4 add dh,30h;change 0-9 to '0-9' cmp dh,39h ja add_dh_7 dh_ok: mov dl,ah and dl,0fh;reserve low 4bit add dl,30h cmp dl,39h ja add_dl_7 dl_ok: nop ret add_dl_7: add dl,7h;revert A-F to 'A-F' jmp dl_ok

add_dh_7: add dh,7h jmp dh_ok

show_hex_ascii endp 题3.31 请写一个可把某个十进制数ASCII码串转换成对应非压缩BCD何压缩BCD的示例程序。

答:;非压缩BCD码

;Input ah=十进制数ASCII码

;Output al=非压缩BCD码

TEST1 proc cmp ah,'0' jb exit cmp ah,'9' ja exit sub ah,30h mov al,ah exit: nop ret TEST1 endp

;压缩BCD码

;Input ax=两个十进制数ASCII码

;Output bl=压缩BCD码

TEST2 proc

cmp ah,'0' jb exit cmp ah,'9' ja exit sub ah,30h mov bl,ah shl bl,4

cmp al,'0' jb exit cmp al,'9' ja exit1 sub al,30h add bl,al exit1: nop ret TEST2 endp 题3.32 请写一个可把某个十进制数ASCII码转换为对应的二进制的示例程序。答: table db '0000','0001','0010','0011','0100','0101','0110','0111' db '1000','1001'......;Input bl=一个十进制数ASCII码

;Output dx:ax=二进制ASCII码

;程序未检验该十进制数是否在范围以内

TEST3 proc sub bl,30h xor bh,bh shl bx,1 shl bx,1 mov dh,table[bx] mov dl,table[bx+1] mov ah,table[bx+2] mov al,table[bx+3]

ret TEST3 endp

题3.33 请写出一个可把某个十六进制数ASCII码转换为对应的二进制的示例程序。答: table db '0000','0001','0010','0011','0100','0101','0110','0111' db '1000','1001','1010','1011','1100','1101','1110','1111'......;Input bl=一个十六进制数ASCII码

;Output dx:ax=二进制ASCII码

TEST3 proc cmp bl,30h jb exit1;小于30H的不在范围内

sub bl,30h cmp bl,0Ah;如果在9以内,开始转换0-9 jb change1

sub bl,0Ah cmp bl,6h;如果在‘9’-‘A’之间,不在范围内

jb exit1

sub bl,6h;‘A’=0 cmp bl,7h;如果在‘A’-‘F’之间,开始转换

jb change2

cmp bl,21h;如果大于‘F’,看是否在‘F’和‘a’之间

jb exit1;如果在,则不在范围内

sub bl,20h;'a'=0 cmp bl,6h;如果大于‘f’,则不在范围内

ja exit1 change2: add bl,9h;按照table表,如果A=0还需要加9才可以

change1: xor bh,bh shl bx,1 shl bx,1 mov dh,table[bx] mov dl,table[bx+1] mov ah,table[bx+2] mov al,table[bx+3] exit1: ret TEST3 endp

题3.34 请写一个实现数据块移动的示例程序。答: data segment data1 db 'Hello!!.....$'....data2 db 128 dup(?)data ends

....xor ax,ax xor bx,bx mov1: mov al,data1[bx] cmp al,'$' jz out1 mov data2[bx],al inc bx jmp mov1 out1:......题3.35 请编一个程序求从地址F000:0000H开始的64K字节内存区域的检验和,并转换为

十六进制的数的ASCII码串。

答:;F000:0000H 字检验和

;Output: BX=字检验和

TEST5 proc

mov ax,0F000H mov es,ax

mov cx,0ffffh xor si,si xor bx,bx ADD0: add bx,es:[si] inc si inc si loop add0

ret TEST5 endp

table1 db '0','1','2','3','4','5','6','7','8','9' db 'A','B','C','D','E','F';Input bx=字检验和

;Output dx:ax=字检验和ASCII码

TEST4 proc push cx

mov cx,bx push cx mov cl,12 shr bx,cl pop cx mov dh,table1[bx] mov bx,cx and bx,0F00h push cx mov cl,8 shr bx,cl pop cx mov dl,table1[bx] mov bx,cx and bx,00f0h push cx mov cl,4 shr bx,cl pop cx mov ah,table1[bx] mov bx,cx and bx,000fh mov al,table1[bx]

mov bx,cx pop cx ret TEST4 endp

题3.36 设已在地址F000:0000H开始的内存区域安排了100个字节的无符号8位二进制数。

请编写一个程序求它们的和,并转换为对应十进制数的ASCII码串。

答:;从 F000:0000H开始100个byte无符号数相加

;output BX=Sum TEST6 proc push cx push ax push si mov ax,0f000h mov es,ax xor bx,bx xor si,si xor ax,ax mov cx,100 ADD2: mov al,es:[si] add bx,ax inc si loop ADD2

pop si pop ax pop cx ret TEST6 endp

......Dec_ASC db ' $';在数据区

......;Name:Convert1;function: Hex convert to Dec;Input: BX=a word of Hex;Output: DS:Dec_ASC Convert1 proc push ax push cx push dx mov ax,bx xor dx,dx mov cx,2710h;2710H=10000 div cx add ax,30h mov dec_asc[0],al;[0]=万位

mov ax,dx xor dx,dx mov cx,3E8h;3E8H=1000 div cx add ax,30h mov dec_asc[1],al;[1]=千位

mov ax,dx mov cl,64h;64H=100 div cl add al,30h mov dec_asc[2],al;[2]=百位

mov al,ah mov ah,0 mov cl,0ah;0A=10 div cl add ax,3030h mov dec_asc[3],al;[3]=十位

mov dec_asc[4],ah;[4]=个位

pop dx pop cx pop ax ret Convert1 endp

题3.37 设已在地址F000:0000H开始的内存区域安排了1024个16位有符号数。请编写一个程序

统计其中的正数、负数和零的个数,并分别转换为对应的十进制数的ASCII码串。

答:;从 F000:0000H开始1024个Word有符号数统计

;output Di=0的个数

;Bx=正数的个数

;DX=负数的个数

TEST7 proc push cx push ax push si mov ax,0f000h mov es,ax xor bx,bx xor si,si xor ax,ax xor di,di xor dx,dx mov cx,1024 Next1: mov ax,es:[si] cmp ax,0 jnz check_P inc di jmp next2 check_p: shl ax,1 jnc ADD_P inc dx jmp next2 ADD_P: inc bx next2: inc si inc si loop Next1

pop si pop ax pop cx ret TEST7 endp

分别call convert1, 并保存到不同的地方即可;

题3.38 设从地址F000:0000H开始的内存区域是缓冲区,存放了一组单字节的正数或负数,以0结尾。请编写一个程序确定其中最大的正数和最小的负数。

答:;从 F000:0000H开始以0结尾的单字节正数负数统计

;output bh=最大的正数

;bl=最小的负数

TEST8 proc xor bx,bx xor si,si mov ax,0F000h mov es,ax next9: mov al,es:[si] cmp al,0 jz exit9 test al,80h jnz Neg_1 cmp al,bh jb next7 xchg al,bh next7: inc si jmp next9 Neg_1: cmp al,bl jg next8 xchg al,bl next8: inc si jmp next9 exit9: ret TEST8 endp 题3.39 设从地址F000:0000H开始的1K字节内存区域是缓冲区。请写一个可收集该区域内

所有子串“OK”开始地址的程序

答:;从 F000:0000H开始1K字节内存区域,统计子串“OK”开始地址

;output 开始地址=ADDRESS TEST9 proc xor bx,bx xor si,si mov ax,0F000h mov es,ax mov cx,1024 next5: mov ax,es:[si] cmp ax,'OK' jnz next6 mov ADDRESS[BX],si inc bx inc bx next6: inc si inc si loop next5 ret TEST8 endp 题3.40 请优化3.6.2节例7所示排序程序。答:自己优化下;

第五篇:C语言程序设计教程_杨路明__课后习题答案

C语言程序设计教程 杨路明 课后习题答案 北京邮电大学出

版社

第一章

1、算法描述主要是用两种基本方法:第一是自然语言描述,第二是使用专用工具进行算法描述

2、c语言程序的结构如下:

①c语言程序由函数组成,每个程序必须具有一个main函数作为程序的主控函数。②“/*”与“*/”之间的内容构成c语言程序的注释部分。③用预处理命令#include可以包含有关文件的信息。④大小写字母在c语言中是有区别的。

⑤除main函数和标准库函数以外,用户可以自己编写函数,程序一般由多个函数组成,这些函数制定实际所需要做的工作。例如: void main()int a,b,c,s;a=8;b=12;c=6;s=a b*c;printf(“s=%d”,s);

3、c语言的特点:

①c语言具有结构语言的特点,程序之间很容易实现段的共享;

②c语言的主要结构成分为函数,函数可以在程序中被定义完成独立的任务,独立地编译成代码,以实现程序的模块化。

③c语言运算符丰富,运算包含的范围很广; ④c语言数据类型丰富。

⑤c语言允许直接访问物理地址,即可直接对硬件进行操作,实现汇编语言的大部分功能; ⑥c语言语法限制不太严格,程序设计自由度大,这样是c语言能够减少对程序员的束缚; ⑦用c语言编程,生成的目标代码质量高,程序执行效率高,可移植性好;

4、合法标识符:AB12、leed_

3、EF3_

3、_762、PAS、XYZ43K2 不合法标识符:a*b2、8stu、D.K.Jon、if、ave#xy、#_DT5、C.D

5、F2:将当前编辑器中文件存盘 F10:调用主菜单

F4:程序运行到光标所在行

Ctrl F9:当前编辑环境下,进行编译、连接且运行程序; Alt F5:将窗口切换到DOS下,查看程序运行结果

6、(1): ******************** welcome you very good ********************(2): please input three number;5,7,8 max number is:8

7、main

8、User screen、Alt F5

9、标识符必须是字母或下划线开头,大小写字母含义不同。由数字、字母和下划线组成; 关键字是一种语言中规定具有特定含义的标识符。关键字不能作为变量或函数名来使用,用户只能根据系统的规定使用它们。

10、选择主菜单File项下拉子菜单中Save项或直接按F2键存盘。

第二章

1、符合C语法规定的常数为:0x1e、“ab”、1.e5

2、(1): 错误如下:int x,y=5,z=5,aver;x=7;aver =(x y x)/3;结果如下:AVER=5(2): 错误如下:char c1='a',c2='b',c3='c';printf(“a=?=__end”,a,b);结果如下:a=3b='A'“end” aabcc abc3、4、(1):9,11,9,10(2):3,1,0,0(3):11,19,31,1

5、(1):0(2):0(3):9.500000(4):90(5):10(6):10(7):65(8):4(9):4.500000(10):1(11):0(12):20(13):0

6、(5)

7、求x的绝对值

8、c>(max=a>b?a:b)?c:max;

9、B

10、D

第三章

1、输入函数scanf的参数错误,应该为:scanf(“%f”,&k);

2、|1234 1234 |

3、ff10 4、1,3,1

5、原字符串

左边加空格再加字符串本省,字符个数总和为5个

6、scanf(“%d,%d,%c,%c”,&a1,&a2,&c1,&c2);

7、printf(“a b=%d”,a b);printf(“a-b=%d”,a-b);printf(“a*b=%d”,a*b);printf(“a/b=%d”,a/b);printf(“(float)a/b=%f”,(float)a/b);printf(“a%b=%d”,a%b);

8、void main()float r;float s,c;printf(“please input the number:”);scanf(“%f”,&r);if(r>=0)s = 3.14*r*r;c = 2*3.14*r;printf(“s = %f, c = %f”,s,c);else printf(“you input number is error!”);

9、void main()int n;printf(“please input the number:”);scanf(“%d”,&n);if(n>=100 && n printf(“%d%d%d”,n_,(n/10)_,n/100);else printf(“you input number is error!”);

10、void main()int i,j,k;scanf(“%d,%d,%d”,&i,&j,&k);((i%2!= 0?1:0)(j%2!= 0?1:0)(k%2!= 0?1:0))== 2?printf(“YES”):printf(“NO”);

11、void main()char a;scanf(“%c”,&a);printf(“%c,%c,%c”,a-1,a,a 1);printf(“%d,%d,%d”,a-1,a,a 1);

12、void main()float a,b,c,s,Area;scanf(“%f,%f,%f”,&a,&b,&c);if(a b > c || a c > b || b c >a)s =(a b c)/2;Area = sqrt(s*(s-a)*(s-b)*(s-c));printf(“%f”,Area);else printf(“you input the number is error!”);

第四章

1: 0 2: 20 3:(x20)||(x 4: ***a=25,b=14,c=16*** 5: 37 6: if(a else printf(“2”);

7、#include void main()char a,b,t1,t2;scanf(“%c,%c”,&a,&b);t1=a>b?a:b;t2=a if((t1-t2)%2==0)printf(“%c,%c”,a 1,b 1);else printf(“%c,%c”,a-1,b-1);getch();

8、#include void main()int temp1=0,temp2=0,x,y,i=1;printf(“Please input(x,y): ”);scanf(“%d,%d”,&x,&y);while((i*y)if(x==(i*y))temp1=1;break;temp2=i;i;if(temp1)printf(“%d / %d = %d”,x,y,i);else printf(“%d / %d---> shang=%d,yushu=%d”,x,y,temp2,x-y*temp2);getch();

9、#include void main()float x,y,m=0,n=0;scanf(“%f,%f”,&x,&y);n=(x-2)*(x-2);m=(y-2)*(y-2);if((m n)printf(“(%.3f,%.3f)In the yuan”,x,y);else printf(“(%.3f,%.3f)out of the yuan”,x,y);getch();

10、#include void main()int temp=0,month,year;printf(“Please input(year,month): ”);scanf(“%d,%d”,&year,&month);

if((year@0==0)||(year%4==0&&year_0!=0))temp=1;if(month==2)if(temp)printf(“%d year %d month have 29 ”,year,month);else printf(“%d year %d month have 28 ”,year,month);else if(month%2==0)printf(“%d year %d month have 30 ”,year,month);else printf(“%d year %d month have 31 ”,year,month);getch();

11、switch(a/10)case 5:m=4;break;case 4:m=3;break;case 3:m=2;break;case 2:m=1;break;default:m=5;

12、方法一: #include void main()int x,y;scanf(“%d”,&x);if(x-5)y=x-1;else if(x==0)y=x;else if(x>0&&x y=x 1;printf(“%d”,y);getch();方法二: #include void main()int x,y;scanf(“%d”,&x);if(x-5)if(x==0)y=x;else if(x>0&&x else y=x-1;printf(“%d”,y);else printf(“Input error!!”);getch();方法三: #include void main()int x,y,i;scanf(“%d”,&x);if(x-5)if(x==0)i=1;else if(x>0&&x else i=3;else i=4;switch(i)case 1:y=x;printf(“%d”,y);break;case 2:y=x 1;printf(“%d”,y);break;case 3:y=x-1;printf(“%d”,y);break;case 4:printf(“Input error!”);break;getch();

第五章

1、void main()int n,value;int i,count=0;float average = 0;long int sum = 0;scanf(“%d”,&n);for(i = 0;i scanf(“%d”,&value);if(value%2 == 0)sum =value;count;average = sum /(float)count;printf(“the average is %f”,average);

2、#include “stdio.h” void main()char ch;int zm = 0, sz = 0;ch = getchar();while(ch!= '*')if((ch >= 'A' && ch = 'a' && ch zm;if(ch >= '0' && ch sz;ch = getchar();printf(“zm = %d;sz = %d”,zm,sz);

3、void main()long i_value;int sum = 0;int temp = 0;scanf(“%ld”,&i_value);if(i_value for(;;)temp = i_value_;i_value = i_value/10;sum =temp;printf(“%d ”,temp);if(i_value == 0)break;printf(“=%d”,sum);

4、#include “stdio.h” void main()char ch;ch = getchar();while(ch!= '.')if((ch >= 'A' && ch ch = ch 32;putchar(ch);else if((ch >= 'a' && ch ch = ch1;printf(“Total steps: %d”, steps);return 0;

8、main()int i,j,k,n;printf(“the narcissus number is:”);for(n=100;n i=n/100;j=n/10-i*10;k=n_;if(i*i*i j*j*j k*k*k==n)printf(“%d”,n);

9、main()float i,j,temp,n,sum;int t;i=2;j=1;sum=0;scanf(“%d”,&t);for(n=1;n sum=sum i/j;temp=i;i=i j;j=temp;printf(“2/1 3/2 5/3 8/5 13/8...=%f”,sum);

10、void main()int nWidth,a,b;scanf(“%d”,&nWidth);for(a=(nWidth%2);a for(b=0;b char chOut =' ';int nleft =(nWidth-a)/2;int nright =(nWidth a)/2;if(b>=nleft&&b chOut ='*';printf(“%c”,chOut);printf(“");r

11、void main()int i=1,j=1;for(i=1;i for(j=1;j printf(”%d*%d=%d“,i,j,i*j);printf(”“)

12、#include ”stdio.h“ void main()char c;//count1是正数的个数 //count2是负数的个数 int count1=0,count2=0;//sum1是正数之和 //sum2是负数之和 int sum1=0,sum2=0;int flage = 0;c=getchar();while(c!= '*')if(c == '-')flage = 1;if(flage == 0)sum1 =(c-48);count1;else if(c!= '-')sum2-=(c-48);flage=0;count2;c = getchar();printf(”%d,%d“,count1,count2);printf(”%f,%f“,sum1/count1,sum2/count2);

13、void main()int i,j;int s = 0;for(i = 100;i s = 0;for(j=1;j if(i%j == 0)s = s j;if(s == i)printf(”]“,i);

14、#include #include void main()int n;long k = 1;float e = 1;n = 1;clrscr();while(fabs(1.0/k)>= 0.000001)n;e = e 1.0/k;k = k * n;printf(”%f“,e);

15、#include ”math.h“ main()float x0,x1,x2,f0,f1,f2;x1=-10;f1=2*x1*x1*x1-4*x1*x1 3*x1;x2=10;f2=2*x2*x2*x2-4*x2*x2 3*x2;do x0=(x1 x2)/2;f0=2*x0*x0*x0-4*x0*x0 3*x0;if((f0*f1)x2=x0;f2=f0;else x1=x0;f1=f0;while(fabs(f0)>1e-6);printf(”______2*x*x*x-4*x*x 3*x=0______:n“);printf(”the root is %f“,x0);

第六章

1、#include int divisor(int a,int b)int r;while((r=a%b)!=0)a=b;b=r;return b;int multiple(int a,int b)int d;d=divisor(a,b);return a*b/d;void main()int a,b,c,d;printf(”intput(a,b): “);scanf(”%d,%d“,&a,&b);c=divisor(a,b);d=multiple(a,b);printf(”=%d=%d“,c,d);

2、#include void tongji(char a[])int b[3]=0,0,0,i=0;while(a[i]!='')if((a[i]=65)||(a[i]=97))b[0];else if(a[i]=48)b[1];else b[2];i;printf(”zimu have: %d;shuzi have: %d;qita have: %d“,b[0],b[1],b[2]);getch();void main()char a[100];printf(”Please input a string: “);gets(a);tongji(a);

3、#include int flower(int n)int x=0,i,j,k;i=(n_);j=(n/10_);k=(n/100);x=i*i*i j*j*j k*k*k;if(x==n)return 1;else return 0;void main()int i,n;printf(”Please intput n: “);scanf(”%d“,&n);if(n>999||n else for(i=100;i if(flower(i))printf(”%d “,i);getch();

4、#include #define SWAP(a,b)t=b;b=a;a=t;main()float x,y,t;printf(”Enter two number(x,y): “);scanf(”%f,%f“,&x,&y);SWAP(x,y);printf(”:x=%f,y=%f“,x,y);getch();

5、#include int fib(int n)int p;if(n==0)p=0;else if(n==1)p=1;else p=fib(n-1)fib(n-2);return p;void main()int n;printf(”Please input fib: “);scanf(”%d“,&n);printf(”=%d“,fib(n));

6、#include long fac(int n)long f;if(n==0)f=1;else f=n*fac(n-1);return f;void main()int m,n;long f;printf(”Please input(m,n): “);scanf(”%ld,%ld“,&m,&n);f=fac(n m)fac(n);printf(”=%ld“,f);

7、#include void list()int i,j;for(i=1;i for(j=1;j printf(”%d*%d=%d “,i,j,i*j);printf(”“);void main()list();

8、#include int he(int n)int i,s=0;for(i=1;i if(n%i==0)s =i;return s;void main()int i,j;for(i=1;i for(j=1;j if((he(i)==j)&&(he(j)==i)&&(i!=j))printf(”%d%d “,i,j);

9、#include #define max 100 struct work long sid;char name[15];worker[max];int size=0;struct work *set_list()do printf(”input(sid,name): “);scanf(”%ld,%s“,&worker[size].sid,worker[size].name);size;while(worker[size-1].sid!=0);return worker;void paixu(struct work a[])int i,j,k;long t;char v[15];for(i=0;i k=i;for(j=i;j if(a[i].sid>a[j].sid)k=j;if(k!=i)t=a[i].sid;a[i].sid=a[j].sid;a[j].sid=t;strcpy(v,a[i].name);strcpy(a[i].name,a[j].name);strcpy(a[j].name,v);for(i=0;i printf(”sid: %ld:%s“,a[i].sid,a[i].name);getch();void select(struct work a[])int i=0,found=1;long num;printf(”Input select sid: “);scanf(”%ld“,&num);for(i=0;i if(a[i].sid==num)found=0;printf(”%ld: %s“,num,a[i].name);break;if(found)printf(”this sid!!“);getch();void main()struct work *p;p=set_list();paixu(p);select(p);

10、#include float jiecheng(int n)long s=1;int i;for(i=1;i s=s*i;return s;float chengfang(float x,int n)float s=1;int i;for(i=1;i s=s*x;return s;float f(float x,int n)float s=1,t=0;int i=1,j=-1;for(i=1;i t=j*chengfang(x,2*i)/jiecheng(2*i);s =t;j=j*j;return s;main()float s1=0,s2=0,s3=0,s4=0,x=5.6;int n=7;s1=f(x,n);s2=f(x 2.3,n);s3=f(x-3.2,n 3);s4=s1/(s2 s3);printf(”%f“,s4);getch();

第七章

1:(1)D(2)A(3)D(4)B(5)D 2:(1)1 5 4 4 6 7 8 2 3 4(2)6333 3:(1)a[8]=data;k>=0 a[k]=temp break k(2)”%s“ str[i]

4、/*题目:求一组成绩的平均分数以及高于平均分的成绩。*/ #include #define max 100 void main()float a[max],s=0,average=0;int i,n;printf(”Please input N: “);/*输入要处理元素的个数*/ scanf(”%d“,&n);printf(”input %d ge shu: “,n);/*输入90,85,92,77,80,62*/ for(i=0;i scanf(”%f“,&a[i]);s =a[i];average = s / n;printf(”= %.2f“,average);/*输出81.00*/ for(i=0;i if(a[i]>average)printf(”%.2f “,a[i]);/*输出90.00,85.00,92.00*/

5、/*题目:编写程序,输入一组整数,将他们排序后由小到大输出。*/ #include #define max 100 void main()int a[max],j,i,k=0,t=0,n=0;printf(”Please input N: “);/*输入要处理元素的个数*/ scanf(”%d“,&n);for(i=0;i scanf(”%d“,&a[i]);for(i=0;i k=i;for(j=i 1;j if(a[k]>a[j])k=j;if(k!=i)/*元素排序前下标与排序后下标不符,则交换其值*/ t=a[i];a[i]=a[k];a[k]=t;printf(”“);for(i=0;i printf(”%d “,a[i]);

6、/*题目:从键盘输入一个4x4的整数矩阵,以主对角线(┪猿浦?/ /*将左下角元素中较大者替换右上角元素,并将右上角含对称轴输出。*/ #include #include void main()int d[4][4]=0,0,0,0,i,j;clrscr();printf(”input 16 num: “);for(i=0;i for(j=0;j scanf(”%d“,&d[i][j]);for(i=0;i for(j=0;j if(d[i][j]>d[j][i])/*左下角元素大于右上角元素则交换*/ d[j][i]=d[i][j];for(i=0;i printf(”“);/*为了保持每行的间隔与每列的相同*/ for(j=0;j if(j>=i)printf(”%d“,d[i][j]);/*为了使位数不同的数输出依然保持三角型* else printf(”“);

7、*题目:输入一个3x4的二维数组,然后分别按行和按列输出。*/ #include #include void main()int d[3][4]=0,0,0,0,i,j;printf(”Please input 12 num: “);for(i=0;i for(j=0;j scanf(”%d“,&d[i][j]);printf(”hang: “);for(i=0;i for(j=0;j printf(”%d “,d[i][j]);

/ printf(” lie: “);for(i=0;i for(j=0;j printf(”%d “,d[j][i]);

8、/*题目:编写程序,将两个字符串连接起来,不用strcat函数。*/ #include #include void main()char s1[50],s2[50];int i=0,j=0,t=0;printf(”Input one: “);gets(s1);while(s1[i]!='')i;/*统计s1中字符个数*/ printf(”second: “);gets(s2);while(s2[j]!='')j;/*统计s2中字符个数*/ for(t=0;t s1[i]=s2[t];i;printf(” second: “);puts(s1);

9、/*输入一行字符串,统计字符对ab的个数。*/ #include #include #define MAX 100 void main()char str[MAX];int i=0,flage=0;int count=0;printf(”input a string: “);gets(str);while(str[i])if(str[i]=='a')flage=1;else if(str[i]=='b')if(flage==1)count;flage=0;else flage=0;i;printf(”the double char ab count is %d“,count);

10、#include /*相对于第一种方法,这种方法能把同为最大的字符串全部打印出来。*/#include int paixu(int a[],int n)/*构造对长度为n的数组排序的函数*/ int i,j,t,k,temp;for(i=0;i k=i;for(j=i 1;j if(a[k]>a[j])k=j;if(k!=i)t=a[i];a[i]=a[k];a[k]=t;temp=a[n-1];return temp;/*返回最大字符串的长度的值*/ void main()char str1[50],str2[50],str3[50],str4[50],str5[50],str6[50];char str7[50],str8[50],str9[50],str10[50];int count[10]=0,temp[10]=0,i,j;int paixu(int a[],int n);for(i=1;i printf(”input %d string: “,i);if(i==1)gets(str1);while(str1[count[0]])count[0];temp[0];if(i==2)gets(str2);while(str2[count[1]])count[1];temp[1];if(i==3)gets(str3);while(str3[count[2]])count[2];temp[2];if(i==4)gets(str4);while(str4[count[3]])count[3];temp[3];if(i==5)gets(str5);while(str5[count[4]])count[4];temp[4];if(i==6)gets(str6);while(str6[count[5]])count[5];temp[5];if(i==7)gets(str7);while(str7[count[6]])count[6];temp[6];if(i==8)gets(str8);while(str8[count[7]])count[7];temp[7];if(i==9)gets(str9);while(str9[count[8]])count[8];temp[8];if(i==10)gets(str10);while(str10[count[9]])count[9];temp[9];j=paixu(temp,10);for(i=1;i if(count[i-1]==j)/*只要字符串长度与最大长度相等就打印出来*/ switch(i)case 1:puts(str1);printf(”“);break;case 2:puts(str2);printf(”“);break;case 3:puts(str3);printf(”“);break;case 4:puts(str4);printf(”“);break;case 5:puts(str5);printf(”“);break;case 6:puts(str6);printf(”“);break;case 7:puts(str7);printf(”“);break;case 8:puts(str8);printf(”“);break;case 9:puts(str9);printf(”“);break;case 10:puts(str10);printf(”“);break;

11、/*给数组a输入m个按升序排列的数,给数组b输入n个按降序排列的数*/ /*将a与b中的元素按降序排列存在数组c中。*/ #include void main()int a[100],b[100],c[100],i,m,n,j,k,temp=0,s;printf(”= “);scanf(”%d“,&m);/*确定M的个数*/ printf(”= “);scanf(”%d“,&n);/*确定N的个数*/ printf(”input m ge shu: “);for(s=0;s scanf(”%d“,&a[s]);printf(”input n ge shu: “);for(s=0;s scanf(”%d“,&b[s]);i=m-1;j=0;k=0;/*i,j,分别标记a[]与b[]且都是从最大元素开始做标记*/ for(;;)if(i==0)/*a[]中只有一个数或者a[]处理到了最后一个元素*/ if(a[i] else c[k]=a[i];k;for(;;)/*把b[]数组接到c[]后面*/ c[k]=b[j];j;k;if(j==n)/*如果b[]处理完,结束。并做标记temp=1*/ temp=1;break;if(temp==1)break;/*标记temp=1,全部处理结束*/ if((a[i] c[k]=b[j];j;k;if((a[i]>b[j])&&(i!=0)&&(j!=n))c[k]=a[i];i--;k;if(j==n)/*b[]处理到完*/ for(;;)/*把b[]数组接到c[]后面*/ if(i==0)

/*如果a[]处理完,结束c[k]=a[i];temp=1;break;c[k]=a[i];i--;k;if(temp==1)break;/*标记temp=1,全部处理结束*/ for(s=0;s printf(”%d ",c[s]);getch();

并做标记temp=1*/。

下载c++语言程序设计教程(第二版)习题解答 沈显军 杨进才 张勇word格式文档
下载c++语言程序设计教程(第二版)习题解答 沈显军 杨进才 张勇.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    C语言程序设计教程(第2版)课后习题答案杨路明

    第一章 C语言程序设计概述 -习题答案1 算法的描述有哪些基本方法? 答 1、自然语言 2、专用工具 2 C语言程序的基本结构是怎样的?举一个例子说明。答 1、C语言程序由函数构成;......