C程序设计语言(第二版)

C程序设计语言(第二版)
C程序设计语言(第二版)

第一章基本概念

第二章类型、运算符与表达式

一个对象的类型决定着该对象可取值的集合以及可以对该对象施行的运算。

2.2 数据类型与大小

1. 在C语言中只有如下几个基本数据类型:

char 单字节,可以存放字符集中一个字符。

int 整数,一般反映了宿主机上整数的自然大小。

Float 单精度浮点数。

Double 双精度浮点数。

此外,还有一些可用于限定这些基本类型的限定符。

2.3 常量

1.诸如1234一类的整数常量是int常量。Long常量要以字母l或L结尾。无符号常量以字母u或U结尾,后缀ul或UL用于表示unsigned long常量。(这里的常量其实就是指直接指定的一般数字或是字符字符串什么的)

浮点常量必须包含一个小数点或指数(如1e-1)或两者都包含,在没有后缀时类型为double。后缀f与F用于指定float常量,而后缀l或L则用于指定

字符常量是一个整数,写成用单引号括住单个字符的形式,如‘x’。字符常量的值是该字符在机器字符集中的数值。

常量表达式时其中只涉及到常量的表达式。这种表达式可以在编译时计算而不必推迟到运算时,因而可以用在常量可以出现的任何位置,例如由define定义的宏。

字符串常量也叫字符串字面值,是用双引号括住的由0个或多个字符组成的字符序列。从技术绝度看,字符串常量就是字符数组。在内部表示字符串时要用一个空字符’\0’来结尾,故用于存储字符串的物理存储单元数比括在双引号中的字符数多一个。这种表示发意味着,C语言对字符串的长度没有限制,但是程序必须扫描完整个字符串才能决定这个字符串的长度。

枚举常量。枚举是常量整数值的列表。不同的枚举中的名字必须各不相同,同一枚举中各个名字的值不要求不同。枚举是使常量值与名字相关联的又一种方便的方法,其相对于#define语句的优势是常量值可以由自己控制。

2.4 说明

其实就是声明。如果所涉及的变量不是自动变量(就是局部变量),那么只初始化一次,而且从概念上讲应该在程序开始执行之前进行,此时要求初始化符必须为常量表达式。显示初始化的自动变量每当进入其所在的函数或分程序时就进行一次初始化,其初始化符可以是任何表达式。外部变量与静态变量的缺省值为0。未经显式初始化的自动变量的值为未定义值(即垃圾)。

2.5 算术运算符

2.6 关系运算符与逻辑运算符

2.7 类型转换

1. 当一个运算符的几个运算分量的类型不同时,要根据一些规则把它们转换成某个共同的类型。一般而言,只能把“比较窄的”运算分量自动转换成“比较宽的”运算分量,这样才能不丢失信息。

2. char类型就是小整数类型,在算术表达式中可以自由地使用char类型的变量或常量。这就使得在某些字符转换中有了很大的灵活性。但是在将字符转换成整数时有一点微妙。C 语言没有指定char类型变量时无符号还是有符号量。当把一个char类型的值转换成int类型的值时,其结果是不是负整数?结果视机器的不同而有所变化,反映了不同机器结构之间

的区别。在某些机器上,如果字符的最左一位为1,那么就被转换成负整数。在另一些机器上,采取的是提升的方法,通过在最左边加上0把字符提升为整数,这样的转换结果总是正的。C语言的定义保证了机器的标准可打印字符集中的字符不会是负的,故在表达式中这些字符总是正的。但是,字符变量存储的位模式在某些机器上可能是负的,而在另一些机器上却是正的。为了保证程序的可移植性,如果要在char变量中存储非字符数据,那么最好指定signed或unsigned限定符。

3. 当表达式中包含unsigned类型的运算分量时,转换规则要复杂一些。主要问题是,在有符号与无符号值之间的比较运算取决于机器,因为它们取决于各个整数类型的大小。例如,假定int对象占16位,long对象占32位,那么,-1L<1U,这是因为int类型的-1U被提升为signed long类型;但是-1L>1UL,这是因为-1L被提升为unsinged long类型,因此它是一个比较大的正数。

4. 在进行赋值时要进行类型转换,=右边的值要转换成左边变量的类型,后者即赋值表达式结果的类型。不管是否要进行符号扩展,字符值都要转换成整数值。当把较长的整型数转换成较短的整型数或字符时,要把超出的高位部分截掉。

5. 由于函数调用的变元是表达式,当把变元传递给函数时也可能引起类型转换。在没有函数原型的情况下,char与short类型转换为int类型,float转换为double型,这就是即使在函数使用char与float类型的变元表达式调用时仍把参数说明成int与float的原因。

2.8 加一与减一运算符

2.9 按位运算符

2.10 赋值运算符与赋值表达式

2.11 条件表达式

2.12 运算符优先级与表达式求值次序

同一行的各个运算符具有相同的优先级,纵向看越往下优先级越低。

第三章控制流

第四章函数与程序结构

4.1 函数的基本知识

1. 程序是变量定义和函数定义的结合。函数之间的通信可以通过变元、函数返回值以及外部变量进行。函数可以以任意次序出现在原文件中。源程序可以分成多个文件,只要不把一个函数分在几个文件中就行。

4.3 外部变量

1.C程序由一组外部对象(外部变量或函数)组成。外部变量在函数外面定义,故可以在很多函数中使用。由于C语言不允许在一个函数中定义其他函数,因此函数本身是外部的。在缺省情况下,外部变量与函数具有如下性质:所有通过名字对外部变量与函数的引用都是引用的同一对象。

4.4 作用域规则

4.5 头文件

4.6 静态变量

1. static说明适用于外部变量与函数,用于把这些对象的作用域限定为被编译源文件的剩余部分。

2. 外部static说明最常用于说明变量,当然它也可以用于说明函数。通常情况下,函数名字是全局的,在整个程序的各个部分都可见。然而,如果把一个函数说明称静态的,那么该函数名字就不能用在除该函数说明所在的文件之外的其他文件中。Static说明也可用于说明内部变量。内部静态变量就像自动变量一样局部于某一特定函数,只能在该函数中使用,但与自动变量不同的是,不管其所在函数是否被调用,它都一直是存在的,而不像自动变量那样,随着所在函数的调用与退出而存在与消失。

4.7 寄存器变量

Register说明用于提醒编译程序所说明的变量在程序中使用频率较高。其思想是,将寄存器变量放在机器的寄存器中,这样可以是程序更小、执行速度更快。但编译器可以忽略此选项。寄存器说明只适用于自动变量以及函数的形式参数。所有寄存器变量的地址都是不能访问的。

4.9 初始化

1.在没有显示初始化的情况下,外部变量与静态变量都被初始化为0,而自动变量与寄存器变量的初值则没有定义(即,其初值是“垃圾”)。

4.10 递归

4.11 C预处理程序

第五章指针与数组

5.1 指针与地址

1.取地址运算符&只能应用于内存中的对象(即变量与数组元素),它不能对表达式、常量或寄存器变量进行操作。

5.3 指针与数组

1.数组下标所能完成的任何运算都可以用指针来实现。一般而言,指针运算比数组下标运算的速度快。在对数组进行下标运算,即求a[i]的值时,C语言实际上是先将其转化成*(a+i)的形式然后再进行求值,因而在程序中这两种形式等价。

2.必须注意到,数组名字和指针之间仍然存在着一点区别。指针是变量,因而在C语言中,语句pa=a和pa++都是合法的。但是数组名字不是变量,因而诸如a=pa(这个是指对整个数组从一个到另一个的整体赋值)和a++(这是指对数组名执行自加运算,其实可以运用a+i的形式,不知为啥a++不行)这样的语句是非法的。

3.当把一个数组名字传递给一个函数时,实际上传递的是该数组第一个元素的位置。也可以通过传递指向子数组的指针的方法把数组的一部分作为参数传递给函数。例如f(&a[2])。

5.4 地址算术运算

1.有效的指针运算包括:相同类型指针之间的赋值运算;指针值加或减一个整数值的运算;指向相同数组中的元素的指针之间的减或比较运算;将指针赋0或指针与0之间的比较运算。所有其他形式的指针运算均非法,诸如下列形式的运算就是非法的指针运算:指针间的加法、乘法、除法或屏蔽运算;指针值加单双精度浮点数的运算;除两者之一是void*类型指针外,不经强制类型转换就将指向一种类型对象的指针赋给指向另一种类型对象的指针的运算。

5.5 字符指针与函数

char amessage[] = “now is the time”; /*定义一个数组*/

char *pmessage = “now is the time”; /*定义一个指针*/

上述说明中,amessage是一个不可改变的常量,它总指向同一片存储区。另一方面,pmessage是一个指针,其初值指向一个字符串常量,之后它可以被修改指向其他地址,但是如果试图修改字符串的内容,结果将不确定。

5.6 指针数组与指向指针的指针

1. 例如定义char *line[20],那么请注意,这时首先根据运算符优先级规则,line是一个数组,又由于有*的修饰,所以他是一个指针数组,即数组里面存储的全部是指针。

5.7 多维数组

1.数组在内存中按行存储。如果要将二维数组作为变元传递给函数,那么函数的参数说明中应该指明相应数组的列数,数组的行数不必指定。

5.9 指针与多维数组

注意

int a[10][20];

int *b[10];

这两个的区别,对于b来说,每一维的长度可以不一致。

5.10 命令行变元

5.11 指向函数的指针

1.在C语言中,函数本身不是变量,但可以定义指向函数的指针,这种指针可以被赋值、存放于数组中、传递给函数及作为函数返回值等等。

2.定义指向函数的指针:return_type (*fun_name) (参数列表);

调用则为(*fun_name)(实参);

5.12 复杂说明

1. 见定义:

char **argv; argv:指向字符指针的指针

int (*daytab) [13]; daytab:指向由13个整形类型元素组成的一维数组的指针(这就是数组指针,指向数组的指针。就是一指针)。

(这里这么用,int nArray[3] = {1, 2, 3};int (*pArray)[3] = &nArray;)

int *daytab[13]; daytab:由13个指向整数类型对象的指针组成的一维数组(存储的是13个指针)。

void *comp(); comp:返回值为指向通用类型的指针的函数。

void (*comp)(); comp:指向返回值为通用类型的函数的指针。

char (*(*X())[])(); X:返回值为指向一维数组的指针的函数,该一维数组由指向返回字符类型的函数指针组成。

char (*(*X[3])()) [5]; X:由3个指向函数的指针组成的一维数组,该函数返回指向由5个字符组成的一维数组的指针。

对于这种复杂的声明,可以采用基于说明符的方式进行解读:

说明符:可选的*序列直接说明符

直接说明符:名字

(说明符)

直接说明符()

直接说明符[可选的大小]

简而言之,说明符即前面也许带有符号*的直接说明符。直接说明符可以是名字、由一对圆括号括住的说明符、后面跟有一对圆括号的直接说明符或后面跟有由方括号括住可选大小的直接说明符。

例如:(*pfa[])(),pfa首先是一个直接说明符,于是pfa[]也是一个直接说明符。接着*pfa[]被识别出是一个说明符,因而(*pfa[])是一个直接说明符。

于是,按照此规则,对于char (*(*X[3])()) [5]作分析:X是一个直接说明符,那么*X[3]是一个说明符,这就定义了一个指针数组,类型待定。接着(*X[3])是一个直接说明符,那么(*X[3])()也是,它表示这是一个函数指针数组,接着*(*X[3])()表示这个函数返回的是一个指针,(*(*X[3])())表示这是一个直接说明符,char (*(*X[3])()) [5]到这里表示这个函数返回由5个字符组成的一维数组的指针。

2. 对于这种复杂的定义,有著名的右左法则:首先从最里面的圆括号看起,然后往右看,在往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

这里,应该对这个法则作一个小小的修正,应该从未定义的标识符开始阅读,即不是C 语言的关键字开始。

仍旧对上例说明:首先X是个未定义的标识符,往右看是个[],说明这是个数组,再往右,遇到括号则往左,有*说明这是个指针数组。在往左,遇到括号,此时括号里面的东西解析完毕。接着括号外面往由,直接遇到括号,说明这是个函数,即指针数组里的指针式函数指针。跳转往左,遇到*说明函数返回值为指针,跳转往右,括号则整个跳出,再往右,[],说明这是一个指向数组的指针。

第六章结构

6.2 结构与函数

1. 对结构的合法操作只有拷贝、作为一个单元对其赋值、通过&取其地址及访问结构成员这几种。

6.5 自引用结构

即在结构内部定义指向自己的指针。

6.9 位字段

1.当存储空间很宝贵时,有必要将几个对象打包到一个单一机器中去。一个常用的方法是使用类似编译程序中符号表的单个位标志集合。外部使用的数据格式(如硬件接口设备)也常需要能从字的部分位中读取数据。

2. 有关字段对齐的规则请查资料。

C专家编程

第四章数组和指针并不相同

4.2 我的代码为什么无法运行

1.对于以下定义:

文件1:int mango[100];

文件2:extern int *mango;

这种情况是不行的。虽说对数组的引用总是可以写成对指针的引用,而且确实存在一种指针和数组的定义完全相同的上下文环境。但是并不是总是这样。

4.3 什么是声明,什么是定义

1.C语言中的对象必须有且只有一个定义,但他可以有多个extern声明。定义是一种特殊的声明,它创建了一个对象;声明简单的说明了在其他地方创建的对象的名字,它允许你使用这个名字。extern对象声明告诉编译器对象的类型和名字,对象的内存分配则在别处进行。

2.C语言引入了“可修改的左值”这个术语。它表示左值允许出现在赋值语句的左边。这个奇怪的术语是为与数组名区分,数组名也用于确定对象在内存中的位置,也是左值,但它不能作为赋值的对象。因此,数组名是个左值但不是可修改的左值。标准规定赋值符必须用可修改的左值作为他左侧的操作数。通俗的说,只能给可以修改的东西赋值。

3.出现在赋值符左边的符号有时被称为左值,出现在赋值符右边的符号有时则被称为右值。编译器为每个变量分配一个地址(左值)。这个地址在编译时可知,而且该变量在运行时一直保存于这个地址。相反,存储于变量中的值(它的右值)(对于这个地方解释,例如x=y,这时y便称为“它的右值”)只有在运行时才可知。如果需要用到变量中存储的值,编译器就发出指令从指定地址读入变量值并将它存于寄存器中。

4.这里强调一点,对于所有的变量,在编译时都会分配一个地址,而且在编译时可知。那么我们引用这个变量,就是相当于直接对应了这个地址。对于一般的变量,我们引用定义的名字就引用了编译时分配的对应地址里的内容;对于指针变量,由于变量对应的是一个表示地址的地址,所以我们要解引用。请特别注意理解这里!!!

5.extern char a[]与extern char a[100]等价的原因:这两个声明都提示a是一个数组,也就是一个内存地址,数组内的字符可以从这个地址找到。编译器并不需要知道数组总共有多长,因为它只产生偏离起始地址的偏移地址。

6.当你“定义为指针,但以数组方式引用”时会发生什么:

其实,无论对于你定义为指针却以数组的方式引用,还是定义为数字却以指针的方式引用,都会出现错误(作为函数参数可以)。因为当另外去声明这个变量的时候,接下来就会以你声明的这种方式去引用这个变量。但是二者引用的原理却不一样:定义为指针声明为数组,引用的时候会直接根据这个地址去算偏移量,而不是先解引用,所以会出错。定义为数组声明为指针则会先去解引用,这样对一个不是地址的变量去解引用必然会出错。

4.5 数组和指针的其他区别

1.指针和数组都可以在它们的定义中用字符串常量进行初始化。尽管看上去一样,底层的机理却不相同。定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义时同时赋给指针一个字符串常量进行初始化。

2.在ANSI C 中,初始化指针时所创建的字符串常量被定义为只读。与指针相反,由字符串常量初始化的数组是可以修改的。

第五章对链接的思考

5.1 函数库、链接和载入

1. 链接器基础知识:编译器创建一个输出文件,这个文件包含了可重定位的对象。这

些对象就是与源程序对应的数据和机器指令。绝大多数编译器并不是一个单一的庞大程序。他们通常由多大六七个稍小的程序所组成,这些程序由一个叫做“编译器驱动器”的控制程序来调用。这些可以方便地从编译器中分离出来的单独程序包括:预处理器、语法和语义检查器、代码生成器、汇编程序、优化器、链接器,还包括一个调用所有这些程序并向各个程序传递正确选项的驱动器程序。

2. Gcc的编译流程:

(1)预处理阶段:将必要的文件包含进来gcc -E hello.c -o hello.i

(2)编译阶段:这个对应的是语法和语义检查器、代码生成器。在这个阶段中,Gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,Gcc把代码翻译成汇编语言gcc -s hello.i -o hello.s

(3)汇编阶段:汇编阶段是把编译阶段生成的”.s”文件转成目标文件,读者在此可使用选项”-c”就可看到汇编代码已转化为”.o”的二进制目标代码了gcc -c hello.s -o hello.o (4)链接阶段:

3. 目标文件(这里只编译进行到汇编(把汇编语言代码翻译成目标机器指令的过程)之后的文件,等链接完后就成了可执行文件)不能直接执行,它首先需要载入到链接器中。链接器确认main函数为初始进入点,把符号引用绑定到内存地址,把所有的目标文件集中在一起,在加上库文件,从而产生可执行文件。

4. 如果函数库(这个函数库是指已经编译好的二进制文件)的一份拷贝是可执行文件的物理组成部分,那么我们称之为静态链接;如果可执行文件只是包含了文件名,让载入器在运行时能够寻找程序所需要的函数库,那么我们称之为动态链接。收集模块准备执行的三个阶段的规范名称是链接-编辑、载入和运行时链接。静态链接的模块被链接编辑并载入以便运行。动态链接的模块被链接编辑后载入,并在运行时进行链接以便运行。程序执行时,在main()函数被调用前,运行时载入器把共享的数据对象载入到进程的地址空间。外部函数被真正调用之前,运行时载入器并不解析它们。所以即使链接了函数库,如果并没有实际调用,也不会带来额外开销。

5.2 动态链接的优点

1. 可执行文件的体积非常小。虽然运行速度稍微慢一些,但动态链接能够更加有效的利用磁盘空间,而且链接-编辑阶段的时间也会缩短(因为链接器的有些共组被推迟到载入时)。

2. 尽管单个可执行文件的启动速度稍受影响,但动态链接可以从两个方面提高性能:

(1)动态链接可执行文件比功能相同的静态链接可执行文件的体积小。它能够节省磁盘空间和虚拟内存,因为函数库只有在需要时才被映射到进程中。以前,避免把函数库的拷贝绑定到每个可执行文件的唯一方法就是把服务至于内核中而不是函数库中,这就带来了可怕的“内核膨胀”问题。

(2)所有动态链接到某个特定函数库的可执行文件在运行时共享改函数库的一个单独拷贝。操作系统内核保证映射到内存中的函数库可以被所有使用他们的进程共享。这就提供了更好的I/O和交换空间利用率,节省了物理内存,从而提高了系统的整体性能。如果可执行文件时静态链接的,每个文件都拥有一份函数库的拷贝,显然极其浪费。

3. 编译时地址问题:在编译阶段,所有非局部变量地址已经确定。这些这里有与位置无关的代码和与位置有关的代码。与位置无关的代码表示这种代码保证对于任何全局数据的访问都是通过间接地方法完成的。而与位置无关的代码,其代码会被对应到固定的地址。对于这个问题,有待接下来的研究,还有进程间的共享,以及与位置无关以及与位置有关的代码,这个位置指的是直接对应内存还是相对于程序本身,都有待研究。

第六章运动的诗章:运行时数据结构

编程语言理论的经典对立之一就是代码和数据的区别。有些把二者视为一体。C语言通常维持二者的区别。代码和数据的区别也可以认为是编译时和运行时的分界线。编译器的绝大部分工作都跟翻译代码有关,必要的数据存储管理的绝大部分都在运行时进行。

6.2 段

1. 在UNIX中,段表示一个二进制文件相关的内容块。在Inter x86的内存模型中,段表示一种设计的结果。在这种设计中(基于兼容性的原因),地址空间并非一个整体,而是分成一些64K大小的区域,称之为段。

2. 对于unix中的可执行文件,是以段形式组织的。一般有文本段,数据段和bss段。

3. 段可以方便地映射到链接器在运行时可以直接载入的对象中。载入器只是去文件中每个段的映像,并直接将他们放入内存中。从本质上说,段在正在执行的程序中是一块内存区域,每个区域都有特定的目的。

4. 每个段的作用:

(1)文本段包含程序的指令。链接器把指令直接从文件拷贝到内存中,以后便再也不用管它。

(2)数据段包含经过初始化的全局和静态变量以及它们的值。

(3)bss段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段之后。当这个内存区进入程序的地址空间后全部清零。

包括数据段和bss段的整个区段此时通常称为数据区。这是因为在操作系统的内存管理术语中,段就是一片连续的虚拟地址,所以相邻的段被结合。

6.4 C语言运行时系统在a.out里干了什么

运行时数据结构有好几种:堆栈、活动记录、数据、堆等。

1.堆栈段主要有三个用途:

(1)堆栈为函数内部声明的局部变量提供存储空间。

(2)进行函数调用时,堆栈存储与此有关的一些维护性信息。

(3)堆栈也可以被用作暂时存储区。有时候程序需要一些临时存储,比如计算一个很长的算术表达式时,它可以把部分计算结果压到堆栈中,当需要时再把它从

堆栈中取出。

除了递归调用之外,堆栈并非必须。因为在编译时可以知道局部变量、参数和返回地址所需空间的固定大小,并可以将它们分配于BSS段。

6.5 当函数被调用时发生了什么;过程活动记录

1. C语言自动提供的服务之一就是跟踪调用链——哪些函数调用了哪些函数,当下一个“return”语句执行后,控制将返回何处等。解决这个问题的经典机制是堆栈中的过程活动记录。当每个函数被调用时,都会产生一个过程活动记录(或类似的结构)。过程活动记录是一种数据结构,用于支持过程调用,并记录调用结束以后返回调用点所需要的全部信息。(如下图):

2. 绝大多数的现代算法语言允许函数和数据一样在函数内部定义。C语言不允许以这种语法进行函数的嵌套。C语言中的所有函数在词法层次中都是位于最顶层。

在允许嵌套过程的语言中,活动记录一般

要包含一个指向它的外层函数的活动记录的指针。这个指针被称为静态链接,它允许内层过

程访问外层过程的活动记录,因此也可以访问外层过程的局部数据。记住在同一时刻一个外层过程可能有好几个处于活动状态的调用。内层过程活动记录的静态链接将指向合适的活动记录,允许访问局部数据的正确实例。

这种类型的访问(一个指向词法上外层范围的数据项的引用)被称作上层引用。静态链接(指向从词法上讲属于外层过程的活动记录,由编译时决定)之所以如此命名是因为它与动态链接相对照,后者是一个活动记录指针链(在运行时指向最靠近自己的前一个过程调用的活动记录)。

6.6 auto和static关键字

1. 对于在函数内部定义的自动变量,函数调用结束就被回收。如果要返回指针,此时指针不是有malloc或静态变量,那么当函数调用结束时,返回了改变量地址的副本,但是该地址(此时为副本代表的地址)所指向的内存块实际上已经被回收。所以当你再去调用这个返回的指针时,其指向的内容其实是未知的。这个指针也叫悬垂指针。

2. 存储类型说明符auto关键字在实际中从来用不着。它通常由编译器设计者使用,用于标记符号表的条目——它表示“在进入该块后,自动分配存储”。

3. 过程活动记录并不一定要存在于堆栈中。事实上,尽可能地把过程活动记录的内容放到寄存器中会使函数调用速度更快。SPARC架构引入了一个概念,称为“寄存器窗口”,CPU拥有一组寄存器,它们只用于保存过程活动记录中的参数。每当函数调用时,空的活动记录依然到堆栈中。当函数调用链非常深而寄存器窗口不够用时,寄存器的内容就会被保存到堆栈中保留的活动记录空间中,以便重新利用这些寄存器。

第七章对内存的思考

7.2 Inter 80x86内存模型以及它的工作原理

1. 在Inter 80x86内存模型中,段是内存模型设计的结果,在80x86的内存模型中,个各处理器的地址空间并不一致(因为要保持兼容性),但他们都被分割成以64KB为单位的区域,每个这样的区域便称为段。

2. 作为80x86内存模型最基本的形式,8086中的段是一块64KB的内存区域,由一个段寄存器所指向。内存地址的形成过程是:取得段寄存器的值,左移4位,然后加上16位的偏移地址(表示段内的地址),就是最终的地址。

3. 8086有20位地址总线,总共是1MB的内存。但是只有640KB可供应用程序使用。因为其他的要预留给系统使用。

7.3 虚拟内存

1. 虚拟内存:为了去除安装在机器上的物理内存数量的限制,提出虚拟内存这个概念。基本思路是用廉价但缓慢的磁盘来扩充快速却昂贵的内存。在任一给定时刻,程序实际需要使用的虚拟内存区段的内容就被载入物理内存中。当物理内存中的数据有一段时间未被使用,他们就可能被转移到硬盘中,节省下来的物理内存空间用于载入需要使用的其它数据。

2. 以SunOS为例说明:

SunOS中的进程执行于32位地址空间。操作系统负责具体细节,使每个进程都以为自己拥有整个地址空间的独家访问权。这个幻觉是通过“虚拟内存”实现的。所有进程共享机器的物理内存,当内存用完时就用磁盘保存数据。在进程运行时,数据在磁盘和内存之间来回移动。内存管理硬件负责把虚拟地址翻译为物理地址,并让一个进程始终运行于系统的真正内存中。应用程序员只看到虚拟地址,并不知道自己的进程在磁盘和内存之间来回切换。

虚拟内存通过“页”的形式组织。页就是操作系统在磁盘和内存之间移来移去或进行保护的单位,一般为几K字节。

从潜在的可能性上说,与进程有关的所有内存都将被系统所使用。如果该进程可能不会

马上运行,操作系统可以暂时取回所有分配的给他的物理内存资源,将该进程的所有相关信息都备份到磁盘上。这样这个进程就被“换出”。在磁盘中有一个特殊的“交换区”,用于保存从内存中换出的进程。

进程只能操作位于物理内存中的页面。当进程引用一个不在物理内存中的页面时,MMU (内存管理单元)就会产生一个页错误。内核对此事件做出响应,并判断该引用是否有效。如果无效,内核像进程发出一个“段违规”的信号。如果有效,内核从磁盘取回该页,换入到内存中。一旦页面进入内存,进程便被解锁,可以重新运行——进程本身并不知道它曾经因为页面换入事件等待了一会。

7.4 Cache存储器

1. 位于CPU和内存之间,所有对内存的读取和写入操作都要经过Cache。

7.5 数据段和堆

1. 就像堆栈段能够根据需要自动增长一样,数据段也包含了一个对象,用于完成这项工作,这就是堆。堆区域用于动态分配的存储。

2. 被分配的内存总是经过对齐,以适合机器上最大尺寸的原子访问。

第八章

第九章再论数组

9.1 什么时候数组与指针相同

1. 表达式中的数组名(与声明不同)被编译器当作一个指向该数组第一个元素的指针。对数组的引用如a[i]在编译时总是被编译器改写成*(a+i)的形式。

2. C语言把数组下标作为指针的偏移量。C语言把数组下标改写成指针偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。

3. “作为函数参数的数组名”等同于指针。在函数形参定义这个特殊情况下,编译器必须把数组形式改写成指向数组第一个元素的指针形式。

9.3 为什么C语言把数组形参当作指针

1. 这个主要是为了避免值传递时发生的大数据量的拷贝。

2. 必须注意的是对于数组和指针,数组定义了之后是不能修改它的值的(可以修改它里面的元素,这个修改它的值指的是不能修改这个变量名所代表的数组,例如int a[]; int b[]; a=b;这样是不允许的)。

9.4 C语言的多维数组

第十章再论指针

10.4 向函数传递一个一维数组

1. 当像一个函数传递一个二维数组作为参数时,传递给他的是指向该数组第一行的指针。

2. C语言中,对于函数参数的二维数组,一般是使用指针形式(因为要记录每一维的大小以防止越界)。C语言无法向函数传递一个普通的多维数组的。

10.6 使用指针从函数返回一个数组

1. 严格的说,无法直接从函数返回一个数组。但是,可以让函数返回一个指向任何数据结构的指针,当然也可以是指向数组的指针。

这个地方比较麻烦,例子:

int (*paf()) [20]; //paf是一个函数,返回一个指向包含20个int元素的数组的指针

定义可能为:

int (*paf())[20]{

int (*pear)[20];

pear = calloc(20, sizeof(int));

if(!pear) longjemp(error, 1);

return pear;

}

这种用法平时并不多见。需要注意的是千万不能从函数中返回一个指向函数的局部变量的指针。

《C程序设计语言》样卷

韩山师范学院2011年专升本插班生考试样卷 计算机科学与技术专业高级语言程序设计试卷(A卷) 一、填空题(每空1分,共10分) 1.C程序的基本单位是________。 2.C语言源程序文件的后缀是________。 3.C语言中的标识符由________、________和字母组成。 4.设y为float型变量,执行表达式y=6/5之后,y的值是________。 5.在C语言中,要求运算量必须是整型的运算符是___________。 6.如果函数值的类型与返回值的类型不一致时,应该以___________为准。7.已知int a=8,*p=&a;,则*p的值是___________。 8.把一些不同类型的数据作为一个整体来处理时,常用___________。9.若x=2,y=3,则x|y<<2的结果是___________。 二、单项选择题(每小题1.5分,共30分) A.顺序结构、选择结构、循环结构B.递归结构、循环结构、转移结构C.嵌套结构、递归结构、顺序结构D.循环结构、转移结构、顺序结构2.在一个C语言的源程序中,以下叙述正确的是()。

A.必须有除主函数外其他函数B.可以有多个主函数 C.必须有一个主函数D.可以没有主函数 3.以下叙述正确的选项是()。 A.C语言的源程序不必通过编译就可直接执行 B.C语言中的每条语句最终都将被转换成二进制的机器指令 C.C语言程序经编译形成的二进制代码可以直接执行 D.C语言中的函数不可以单独进行编译 4.算法是指为解决某个特定问题而采取的正确且有限的步骤,下面不属于算法的5个特性的是( )。 A.有零个输入或多个输入B.高效性C.有穷性D.确定性5.以下能正确定义且赋初值的语句是( )。 A.int n1=n2=10; B.char c=32; C.float f=f+1.1; D.double x=12.3E2.5 6.有以下程序: main() { char a='a',b; printf("%c",++a); printf("%c\n",b=a++); } 程序运行后的输出结果是( )。 A.bb B.bc C.ab D.ac 7.以下程序段的输出结果是( )。 int a=1234; printf("%2d ",a); A.12 B.34 C.1234 D.提示出错 8.有以下程序:

C语言程序设计(第二版)课后答案 丁亚涛

习题二 一、选择题 二、填空题 1.18 2.int float double 3.10 11 4.8 16 10 5.% 三、阅读题 1. 10,10,9,10 2. j=1, i=2 k=3,i=3 i=3,i=2 k=1,i=1 习题三 一、选择题 二、填空题 1. 从键盘上读入一个字符在屏幕上输出一个字符 #include 2. 按十进制整数形式输出,有符号 按16进制整数形式输出,没有符号 按十进制小数形式输出,输出的数据长度为7位,有2位小数 按字符形式输出一个字符 3. 按十进制整数形式输入数据 按十进制整数形式输入三位数据 跳过3位十进制数据 按字符形式输入一个字符 4. 分程序;; 5. 大写字母L 6. -1 三、阅读题 1. 6 6 6.00 6.00

2. x=127,x= 127,x=177,x=7f y=123.4567,y= 123.46,y=123,45670 3. 2,1 4. 1234 5. 4,3 6. -6,-6 习题四一、选择题 二、填空题 1. 非0 0 、 2. k==0 3. n%7==0&&n%==0 else 三、阅读题 1. a=1,b=0 2. c=1 习题五一、选择题 二、填空题 1. for语句 do-while 语句 while 语句 2. a=14,y=26 3. k=14,n=-1 4. 39 5. s=19 6. 22222 7. 10 8. 7 9. 8 10. 5,5 三、改错题

1. for( i=0;i<5;i++);for控制部分用分号分隔 2. int j=0;while(j<10){j++;i=j} 分号是多余的,否则会造成死循环 3. int s=1,i=1; while(i<5) {s*=i; i++; } 两条语句需要加上花括号 4. while(j<10);(分号不能少) 5. continue改为break 习题六 一、选择题 二、填空题 1. 20 0 19 2. 数组名 3. 越界 4. 6 5. j==k a[j][k]=1; a[j][k]=0; 三、阅读题 1. 6 5 4 3 2 1 2. aaa bbb ccc ddd 3. 2,2,1 习题七 一、选择题 二、填空题 1. 整个函数体内局部 2. 整型 3. k<=b return y;

C程序设计语言 (第二版) 课后答案第一章

Chapter 1 Exercise 1-1 Run the “hello world” program on your system. Experiment with leaving out parts of the program, to see what error message you get. #include int main() { printf("hello, "); printf("world"); printf("\n"); return 0; } Exercise 1-2 Experiment to find out what happens when printf’s argument string contains \c, where c is some character not list above. Exercise 1-3 Modify the temperature conversion program to print a heading above the table. #include int main() { float fahr, celsius; float lower, upper, step; lower = 0; upper = 300; step = 20; fahr = lower; printf("Fahrenheit temperatures and their centigrade or Celsius equivalents\n"); while (fahr <= upper) { celsius = (5.0/9.0) * (fahr-32.0); printf("%3.0f %6.1f\n", fahr, celsius); fahr = fahr + step; } return 0; }

第5章-C语言程序设计(第2版)教材习题答案

【教材】《C语言程序设计(第2版)》清华大学出版社,黄保和,江弋编著。2011年10月第二版。ISBN:978-7-302-26972-4。售价:35元。 【答案版本】本习题答案为2012年2月修订版本。 一、选择题 1. 设有程序段”int k=10; while(k=0) k=k-1;”,则下面叙述正确的是D)循环体语句一次也不执行。 A. while循环执行10次 B. 循环是无限循环 C. 循环体语句执行一次 D. 循环体语句一次也不执行 2. 设有程序段”int x=0,s=0;while(!x!=0) s+=++x; printf(“%d”,s);”则A)运行程序段后输出1。 A. 运行程序段后输出1 B. 程序段执行无限次 C. 运行程序段后输出0 D. 程序段中的控制表达式是非法的 3. 下面循环语句中,错误的是D) int a=1,b=2;do b-- while(b= =0);。 A. int a=1,b=2; while(b--); B. int a=1,b=2; do a++; while(a==b); C. int a=1,b=2; while(a=3); D. int a=1,b=2; do b-- while(b==0); 4. 已知”int i=5;”,下列do…while循环语句的循环次数为C) 5。 do{ printf(“%d\n”,i--); } while(i!=0); A. 0 B. 1 C. 5 D. 无限 5. 循环语句”for(int i=0,j=10; i==j; i++,j--)”的循环次数是A) 0。 A. 0 B. 5 C. 10 D. 无限 6. 下述有关break语句的描述中,不正确的是C) break语句用于if语句的内嵌语句内,它结束该if语句。 A. break语句用于循环体内,它将结束该循环 B. break语句用于开关语句,它结束该开关语句 C. break语句用于if语句的内嵌语句内,它结束该if语句 D. break语句在一个循环体内可使用多次 7. 下面关于循环语句的描述中,错误的是B)循环体内必须同时出现break语句和continue 语句。 A. 循环体内可以包含有循环语句 B. 循环体内必须同时出现break语句和continue语句 C. 循环体内可以出现选择语句 D. 循环体可以是空语句 8. 以下不是死循环的是D)for(;(c=getchar()!=’\n’);)printf(“%c”,c);。 A. for(; ; x+=i); B. while(1) { x++; } C. for( i=10; ; i--) sum+=i; D. for( ; (c=getchar() )!=’\n’ ; ) printf( “%c”,c); 9. 执行语句”for(i=0;i++<3;);”后,变量i的值为C) 4。 A.2 B. 3 C. 4 D. 5 10.语句”for(x=0,y=0;y!=1&&x<4;x++);”是C)循环4次。 A. 无限循环 B. 循环次数不定 C. 循环4次 D. 循环3次

(完整版)C程序设计语言复习题(试题及答案版)

一.填空题 26.C#源程序的后缀名为______.cs________。 26.C#中每个int 类型的变量占用____4___个字节的内存。 26.C#的每行语句以________分号_______结尾。 26.布尔型的变量可以赋值为关键字_____true__________或_____false_________。 26.如果int x的初始值为5,则执行表达式x - =3之后,x的值为_____2_________。 26.do...while语句在执行循环体_____之后________测试语句是否满足循环条件。 26.关键字_______class________表示一个类的定义。 26.如果一个类包含一个或多个抽象方法,它是一个_________抽象_____________类。 26.try块运行后,总是会执行_________finally_____________块中的代码。 26.一个数组如果有两个索引值,那么它是__________二维__________数组。 二.单项选择题 1.在对SQL Server 数据库操作时应选用()。 A、SQL Server .NET Framework 数据提供程序; B、OLE DB .NET Framework 数据提供程序; C、ODBC .NET Framework 数据提供程序; D、Oracle .NET Framework数据提供程序; 2.下列选项中,()是引用类型。 A、enum类型 B、struct类型 C、string类型 D、int类型 3.C#的数据类型有() A、值和调用类型; B、值和引用类型; C、引用和关系类型; D、关系和调用类型 4.下列描述错误的是() A、类不可以多重继承而接口可以; B、抽象类自身可以定义成员而接口不可以; C、抽象类和接口都不能被实例化; D、一个类可以有多个基类和多个基接口; 5.下列关于构造函数的描述正确的是() A、构造函数可以声明返回类型。 B、构造函数不可以用private修饰 C、构造函数必须与类名相同 D、构造函数不能带参数 6.int[][] myArray3=new int[3][]{new int[3]{5,6,2},new int[5]{6,9,7,8,3},new int[2]{3,2}}; 那么myArray3[2][2]的值是( )。 A、9 B、2 C、6 D、越界 7.接口是一种引用类型,在接口中可以声明(),但不可以声明公有的域或私有的成员变量。 A、方法、属性、索引器和事件; B、方法、属性信息、属性; C、索引器和字段; D、事件和字段; 8.在https://www.360docs.net/doc/d22747455.html,中,对于Command对象的ExecuteNonQuery()方法和ExecuteReader()方法,下面叙述错误 的是()。 A、insert、update、delete等操作的Sql语句主要用ExecuteNonQuery()方法来执行; B、ExecuteNonQuery()方法返回执行Sql语句所影响的行数。 C、Select操作的Sql语句只能由ExecuteReader()方法来执行; D、ExecuteReader()方法返回一个DataReder对象; 9.Winform中,关于ToolBar控件的属性和事件的描述不正确的是( )。 A、Buttons属性表示ToolBar控件的所有工具栏按钮 B、ButtonSize属性表示ToolBar控件上的工具栏按钮的大小,如高度和宽度 C、DropDownArrows属性表明工具栏按钮(该按钮有一列值需要以下拉方式显示)旁边是否显示下箭 头键 D、ButtonClick事件在用户单击工具栏任何地方时都会触发

程序设计基础——基于C语言(第2版) 课后习题参考答案汇总

习题1参考答案 1.1解释以下术语 (1)计算机软件:计算机软件是一系列按照特定结构组织的程序、数据(Data)和文档(Document)的集合。 (2)计算机程序:用计算机语言所编写的一系列指令的集合。 (3)数据:数据是程序加工和处理的对象。 (4)算法:算法是一组有穷的规则,它们规定了为解决某一特定问题而采取的一系列运算步骤。 (5)数据结构:数据结构是存在一种或多种特定关系的数据元素的集合,其外在表现为数据的组织形式。 (6)数据类型:数据类型是一个值的集合和定义在这个值集上的操作的总称。 (7)程序设计:程序设计是给出解决特定问题程序的方法和过程,是软件构造活动中的重要组成部分。 1.2 简答题 (1)简述内存的组织结构形式? 计算机系统把内存看作是由若干个连续的存储单元(Storage Location)组成的,每个存储单元的大小为一个字节(Byte)。为了能唯一标志每个存储单元,在计算机系统中给每个存储单元指定一个唯一的编号,该编号被称为存储单元的地址(Address),计算机在读写内存时就是按照存储单元的地址进行的。 (2)为什么计算机系统是一个通用的计算系统? 在计算机硬件相对固定不变的前提下,计算机的通用性主要表现在通过运行不同的程序来完成不同的计算任务。 (3)简述结构化程序设计的基本思想? 在程序设计过程中,如果仅仅使用顺序、选择和循环这三种基本控制结构,并且使每个代码块只有一个入口和一个出口,则这样的程序设计方法被称为结构化程序设计(Structured Programming)。 (4)简述计算机语言的发展史? 程序设计语言经历了从机器语言、汇编语言、高级语言到超高级语言的发展历程。(5)简述利用计算机进行问题求解的过程? 1、理解问题特征 2、设想解决方案 3、优化解决方案 4、描述解决方案 5、执行并分析解决方案 (6)简述各个程序质量要素的含义? 1、正确性(Correctness):正确性是指一个计算机程序的正确程度,即程序在预定的

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

2 第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\n"); 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\n",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 1 2 3 5 8 13 21 3 4 55 89 144 233 377 610 987 1597 2584 4181 6765

C语言程序的设计习题参考答案(第二版_杜友福)

C 语言程序设计习题答案 习题一 C 语言程序设计概述 一、名词解释 (1)程序P1 (2)程序设计P1 (3)机器语言P1 (4)汇编程序P2 (5)高级语言P2 (6)编译程序P3 (7)解释程序P3 (8)算法P4 (9)结构化的程序设计P9 二、简述题 1. 设计程序时应遵循哪些基本原则?P4 答:正确性、可靠性、简明性、有效性、可维护性、可移植性。 2. 算法的要素是什么?算法具有哪些特点? 答:算法的要素是:操作与控制结构;算法的特点有:有穷性、确定性、有效性、有零个或多个输入、有一个或多个输出。 3. 算法的表示形式有哪几种? 答:算法的表示形式有:自然语言、传统流程图、伪代码、结构化的流程图(N_S 流程图,盒图)。 4. 有哪三种基本结构? 答:三种基本结构是:顺序结构、选择结构和循环结构。 5. 传统流程图与N-S 流程图最大的区别是什么? 答:N-S 流程图去掉了在传统流程图中常用的流程线,使得程序的结构显得更加清晰、简单。 三、用传统流程图、N-S 图分别表示求解以下问题的算法。 1. 有3个数a ,b ,c ,要求按由大到小的顺序把它们输出。 2. 依次将10个数输入,求出其中最大的数 和最小的数并输出。 3. 求1+2+3+…+100的值。 4. 求1×2×3×…×10的值。

5. 求下列分段函数的值。 6. 求100~200之间的所有素数。 7. 求一元二次方程ax 2+bx+c=0的根。分别考虑d=b 2-4ac 大于0、等于0和小于0三种情况。 四、注释下面C 程序的各个组成部分。 main() /*主函数 */ { /*程序开始 */ int a,k,m; /*定义三个用来存放整数的变量 */ a=10; /*将整数10赋值给变量a */ k=2; /*将整数2赋值给变量k */ m=1; /*将整数1赋值给变量1 */ a=(k+m)*k/(k-m); /*先求出算术表达式的值,并将其赋值给变量a */ printf("%d\n",a); /*在屏幕上打印出变量a 的值 */ } /*程序结束 */ 习题二 数据类型、运算符与表达式 一、选择题 1~10:BCDCB DDBCA 11~20: ADDAA DBADC 21~28: DABAD CDD Y= 3X (X<1) 4X-1 (X=1) 5(X-1)+6 (1

《C程序设计语言》模拟试卷二

一、单项选择题 1.以下并非C语言的特点的是____________。 A.C语言简洁紧凑 B.能够编写出功能复杂的程序 C.C语言可以直接对硬件进行操作 D.C语言移植性好 2.在C程序中,main()的位置___ ______。 A.必须作为第一个函数 B.必须作为最后一个函数 C.可以任意 D.必须放在它所调用的函数之后 3.一个C程序是由____ ________。 A.一个主程序和若干个子程序构成 B.一个或多个函数构成 C.若干过程组成 D.若干子程序组成 4.以下字符串为标识符的是___ _________。 A._MY B.2_2222 C.short D.LINE 5 5.下列符号可以作为变量名的是___ ________。 A.+a B.*p C._DAY D.next day 6.设c是字符变量,则以下表达式正确的是___ _______。 A.c=666 B.c='c' C.c="c" D.c="abcd" 7.以下说法正确的是_____ _______。 A.输入项可以为一个实型常量,如scanf("%f", 3.5) B.只有格式控制没有输入项也能进行正确输入,如scanf("%d") C.当输入一个实型数据时,格式控制部分应规定小数点后的位数,如 D.当输入数据时,必须指定变量的地址,如scanf("%f", &f) 8.若a, b, c均定义为整型,要给它们输入数据,正确的输入语句是____ ________。 A.read(a, b, c); B.scanf("%d%d%d", a, b, c); C.scanf("%D%D%D", a, b, c); D.scanf(%d%d%d", &a, &b, &c); 9.若a是float变量,b是unsigned型变量,以下输入语句中合法的是____ ___。 A.scanf("%6.2f%d", &a, &b); B.scanf("%f%n", &a, &b); C.scanf("%f%3o", &a, &b); D.scanf("%f%f", &a, &b); 10.if后面的表达式之值__________。 A.只能是0或1 B.只能是正整数或负整数 C.只能是整数或字符型数据 D.可以是任何类型的数据 11.为了避免嵌套的if-else语句的二义性,C语言规定else总是与__ ___组成配对 关系。 A.缩排位置相同的if B.在其之前未配对的if C.在其直接最近的未配对的if D.同一行上的if 12.选择出合法的if语句(设int x, a, b, c;)____ _____。 A.if(a = b0 x++; B.if (a =< b) x++; C.if(a <> b) x++; D.if (a=>b) x++; 13.语句while(!e); 中的条件!e等价于____ _______。 A. e == 0 B.e!=1 C.e!=0 D.~e 14.C语言中while和do-while循环的主要区别是____ _______。 A.do-while的循环体至少无条件执行一次 B.while的循环控制条件比do-while的循环控制条件严格

课后题答案-C语言程序设计(第2版)

《C语言程序设计能力教程(第二版)》课后作业及实训题 参考答案 第1章进入C语言程序世界 二、 1. I love China! printf("we are students.\n") 2. 6 项目实训题参考答案 1.编写一个C程序,输出以下信息: * * * * * * * * * * * * * * * * * * * * I am a student! * * * * * * * * * * * * * * * * * * * * main() { printf("********************\n"); printf(" I am a student!\n "); printf("********************\n"); } 2.已知立方体的长、宽、高分别是10cm、20cm、15cm,编写程序,求立方体体积。 解: main() { int a,b,c,v; a=10; b=20; c=15; v=a*b*c; printf("v=%d",v); } 本程序运行结果为: v=3000 第2章编制C程序的基础知识 一选择题 C B A B A C C 二操作题

,2,-8,2 3.000000,2.500000,-8.000000 2. ABC DE FGH why is 21+35 equal 52 3. 3 1 4 3 2 3 1 2 4. aa bb cc abc A N 项目实训题 1.定义一个符号常量M为5和一个变量n值为2,把它们的乘积输出。 #define M 5 main() { int n,c; n=2; c=M*n; printf("%d\n",c); } 2.编程求下面算术表达式的值。 (1)x+a%3*(int)(x+y)%2/4,设x=2.5,a=7,y=4.7; (2)(float)(a+b)/2+(int)x%(int)y,设a=2,b=3,x=3.5,y=2.5。 (1)main() { int a=7; float x=2.5,y=4.7; printf("%f\n",x+a%3*(int)(x+y)%2/4); } (2)main() { int a=2,b=3; float x=3.5,y=2.5; printf("%f\n",(float)(a+b)/2+(int)x%(int)y); } 第三章顺序结构程序设计 一选择题 A C D C C 二操作题 1. x=3,a=2,b=3 2. z=12.700000

C程序设计语言资料

第3次作业 一、填空题(本大题共20分,共5小题,每小题4分) 1?假定一个二维数组为a[M][N],则a[i]的地址值(以字节为单位)为 2. 类型兼容原则指的是:任何在需要________ 对象的地方,都可以用_______________________________________ 的对象 去替代。 3. 重新抛出异常的表达式为:__________ 4. 以下程序的执行结果是______________________ #i nclude using n amespace std; class Base{ public: Base(){cout<< ” T ;} ~Base(){cout<< ” 2” ;} }; class Derived : public Base{ public: Derived(){cout<< ” 3” ;} ~Derived(){cout<< ” 4” ;} }; void mai n(){ Derived d;

5. 以下程序的执行结果是______________________ #i nclude using n amespace std; class A{ int x; public: A(int x){this->x=x;} A &operator--(){x--;return *this;} A operator— nt){A a(x-=2);retur n a;} void show(){ cout? x;} }; void mai n(){ A a(3),b(3); (a--).show(); (--b).show(); } 二、程序阅读题(本大题共40分,共5小题,每小题8分) 1.写出下面程序运行结果。 #i nclude void rev(i nt a[],i nt n) { int t; for(int i=0,j=n-1;i

C程序设计语言第次

第1次作业 一、单项选择题(本大题共60分,共 20 小题,每小题 3 分) 1. C++程序中,用于实现数据输出的是()。 A. 输出流对象cin和提取运算符>> B. 输出流对象cin和插入运算符<< C. 输出流对象cout和提取运算符>> D. 输出流对象cout和插入运算符<< 2. C++程序中,定义内联函数时需要函数的返回值类型前加上关键字()。 A. outline B. inline C. in D. inport

3. 下面所列选项中,合法的用户标识符是()。 A. if B. switch C. finename D. int 4. C++程序中,定义引用变量时,()。 A. 使用的运算符是* B. 使用的运算符是() C. 使用的运算符是& D. 使用的运算符是[] 5. C++程序中要使用标准输入/输出流对象,必要包含()。 A.

string头文件 B. cmath头文件 C. iostream头文件 D. cctype头文件 6. C++程序中,为了导入标准命名空间,使用的语句是()。 A. inporting namespace std; B. using namespace std; C. using namespace standard; D. inporting namespace standard; 7. 下列关于函数的说法中,不正确的是()。 A. 在不同函数中可以使用相同的名字命名变量 B. 形式参数是局部变量 C. 在函数内部定义变量的作用域在本函数中 D. 在一个函数内的复合语句中定义变量的作用域也是整个函数 8. C++程序的函数调用中,使用数值参数传递时,()。

c语言程序设计(科学出版社)课后习题解答

第3章习题解答 第1章 1.C 语言程序主要由预处理命令、函数、注释等组成。 2.填空 (1)分号 (2)main (3)stdio.h 3. 源程序: #include main( ) { printf(“*************************\n”); printf(“Hello World!\n”); printf(“*************************”); } 4. 源程序: #include main( ) { int a, b, c; /* 定义变量*/ scanf(“%d”, &a); /* 输入第一个整数*/ scanf(“%d”, &b); /* 输入第二个整数*/ c=a-b; /* 计算差*/ printf(“%d-%d=%d”,a,b,c); /* 输出结果*/ } 5. (1) (2)x=10; (3)printf(“s=%d\n”,s); 第2章 1. (1) c (2) a (3) b g (4) a d e (5) d 2. a. 5 b. 295 c. 4 d. 29 e. 9 3. a.x=4,y=6

b. x=4,y=3 f.x=3,y=6 4. 16 5. #include main() { int a,b,c; scanf("%d%d",&a,&b); c=a*b; printf("%d*%d=%d",a,b,c); } 第3章 1. (1) b (2) b (3) d (4) a (5) b 2. (1)&a,&b (2)l,s 3. printf(“x=%.2f,y=%.2f\n”,x,y); 4. #include main() { int num1,num2,num3,sum; float average; scanf("%d%d%d",&num1,&num2,&num3); sum=num1+num2+num3; average=sum/3.0; printf("sum=%d,average=%.2f\n",sum,average); } 5. #include main() { int hour,minute,second,total; /* 定义变量代表时、分、秒和总秒数*/ scanf("%d",&total); hour=total/3600; minute=total%3600/60; second=total%3600%60;

《C程序设计语言》读书笔记及课后答案

通过一周多的学习,大体看完了《C程序设计语言》这本书,这是我的笔记。 (一)读这本书的目标是什么? (1)、读完后必须深入了解C的语法以及内涵,并且达到熟练应用。 (2)、通过练习习惯一种编程风格,深入理解指针,数组,结构体以及内存分配。 (3)、通过练习锻炼逻辑思维能力 (4)、学完后编程要上一个层次,自己能够编写出有用的C代码。 (二)这本书哪个部分是我要重点看的? (1)、指针、数组、结构体 (2)、内存分配 (3)、输入输出及接口问题 (三)读这本书我有什么收获? 3、1 对于本书的感受 这是一本经典的C语言书籍,与其他语法书不同的是所有语法都是用例题来讲的,通过例子理解并练习语法,另外这本书的习题比较难做,不是简单的考语法,而是一些有意义的习题。通过做练习发现还是有所收获的。本书中与Linux联系密切,用C重写了许多简化版的Shell命令如:grep,ls,cat,sort,tail,cp等等。 3、2 收获: 因为本来就有C语言的基础知识,所以对于语法问题基本没有多学新的知识,但是仍然对以下几点有了新的了解: 1)、位字段,不管是通过直接设置位字段还是用以前的位计算,都有新的了解与认识。 2)、指针。建立了“指针为大”的思想,对于应用指针进行类型转换以及运算 都有了新的认识。比如:int a=5,char* p, p=(char)&a,*p = ‘c’;建立这样的过 程对于更加复杂的指针转换就理解了。 3)、结构体。通过第六章对于二叉树以及哈希表的应用深入了解结构体, 并且通过调试程序观察递归过程,同时对递归有了一定的理解。 4)、内存分配malloc函数,通过第八章的学习对malloc函数的内部进行分析, 理解了动态内存管理机制。 3.3 学习的程度以及那些地方存在不足: 对于C的基本语法已经差不多了,但是否达到了当初的目标即在编程方面上一个层次,这我并不敢确定,因为到现在为止这本书上的习题有些我都没有搞定,又看了一下以前的有关C的东西是觉得已经好了许多了,最起码对于很麻烦的程序不再感到畏惧了。另外觉得自己对于某些问题还是没有理解透彻,比如说输入输出时的缓冲机制,比如说指针与结构体的灵活运用,比如说如何能够运用模块化的思想把一个大的问题逐步细分,通过一个一个的小模块(函数)逐步解决,这些有的是与逻辑思维有关,有些是与某方面的专业知识有关,有些是单纯与C有关,比如说有关缓冲与内存的知识要了解操作系统,另外编译原理也要知道,这些我以前都没有学过,以后会找机会补一补。当然随着进一步的学习与应用,会逐渐的熟练或理解某一些知识点。另外因为时间的原因,对于许多练习没有真正的从各个方面去思考,只是做出来就完了,也没有返回去再仔细考虑每一道习题的意义以及对于我的收获。 所以还有待以后有时间在对某些知识点进行学习。 习题是本书的重点,也用了不少时间,其中有些是通过对章节内容的学习后自己做出来的(S),有些是参考别人的,参考的原因主要有: (A)对题目不理解,不明白具体要做到什么程度。

C程序设计语言部分章节习题

第8章函数 一、选择题(在下列各题的A)、B)、C)、D)四个选项中,只有一个选项是正确的,请将正确选项填涂在答题卡相应位置上。) 8.1 若已定义的函数有返回值,则以下关于该函数调用的叙述中错误的是 A)函数调用可以作为独立的语句存在B)函数调用可以作为一个函数的实参 C)函数调用可以出现在表达式中D)函数调用可以作为一个函数的形参 考生答案: 正确答案: D 8.2 在调用函数时,如果实参是简单的变量,它与对应形参之间的数据传递方式是 A)地址传递B)单向值传递C)由实参传形参,再由形参传实参D)传递方式由用户指定 考生答案: 正确答案: B 8.3 以下正确的说法是 A)定义函数时,形参的类型说明可以放在函数体内B)return后边的值不能为表达式 C)如果函数值的类型与返回值类型不一致,以函数值类型为准D)如果形参与实参类型不一致,以实参类型为准 考生答案: 正确答案: C 8.4 以下正确的说法是 A)用户若需调用标准库函数,调用前必须重新定义 B)用户可以重新定义标准库函数,若如此,该函数将失去原有含义 C)系统根本不允许用户重新定义标准库函数 D)用户若需调用标准库函数,调用前不必使用预编译命令将该函数所在文件包括到用户源文件中,系统自动调用 考生答案: 正确答案: B 8.5 以下叙述正确的是 A)函数可以嵌套定义但不能嵌套调用B)函数既可以嵌套调用也可以嵌套定义 C)函数既不可以嵌套定义也不可以嵌套调用D)函数可以嵌套调用但不可以嵌套定义 考生答案: 正确答案: D 8.6 下面对C语言的描述中,正确的是 A)函数一定有返回值,否则无法使用函数B)C语言函数既可以嵌套定义又可以递归调用C)在C语言中,调用函数时,只能将实参的值传递给形参 D)C语言程序中有调用关系的所有函数都必须放在同一源程序文件中 考生答案: 正确答案: C 8.7 下列说法中错误的是 A)静态局部变量的初值是在编译时赋予的,在程序执行期间不再赋予初值 B)若全局变量和某一函数中的局部变量同名,则在该函数中,此全局变量被屏蔽 C)静态全局变量可以被其他的编辑单位所引用 D)所有自动类局部变量的存储单元都是在进入这些局部变量所在的函数体(或复合语 句)时生成,退出其所在的函数体(或复合语句)时消失 考生答案: 正确答案: C 8.8 以下程序有语法错误,有关错误原因的正确说法是 void main() { int G=5,k; void prt_char(); ... k=prt_char(G); ...

c语言(第二版朱鸣华)课后编程题答案

第五章 1 2、#include #include int main() { char a; scanf("%c",&a); if(a>'A'&&a<'Z') printf("%c,%c\n",a-1,a+1); else if(a=='A') printf("没有前面字母"); else if(a=='Z') printf("没有后面字母\n"); return 0; } 3、#include #include int main() { int a; scanf("%d",&a); if(a>=90&&a<=100) printf("A\n"); else if(a>=80&&a<=89) printf("B\n"); else if(a>=70&&a<=79) printf("C\n"); else if(a>=60&&a<=69) printf("D\n");

else printf("E\n"); return 0; } 4、#include int main() { int year,month,day; int maxdays[]={31,28,31,30,31,30,31,31,30,31,30,31}; printf("请输入年月日,中间用空格隔开!\n"); scanf("%d %d %d",&year,&month,&day); if(year%400==0 || (year%4==0 && year%100!=0)) maxdays[1]=29; if(month>12 || month<1) { printf("日期不合法!\n"); return 0; } if(day>maxdays[month-1]) { printf("日期不合法!\n"); return 0; } day++; if(day==maxdays[month-1]) { day=1; month++; if(month==12) { month=1; year++; } } printf("明天的日期是:%d-%d-%d\n",year,month,day); return 0; } 5、#include int main() { double a,b,c; scanf("%lf%lf%lf",&a,&b,&c); if((a+b)>c&&(a+c)>b&&(b+c)>a) if(a==b&&b==c&&c==a) printf("等边三角形\n"); else if((a==b)||(a==c)||(b==c))

《C语言程序设计》-谭浩强(第四版)教案

《C 语言程序设计》-谭浩强(第四版)教案

C语言程序设计》教案

C 语言是近年来国内外得到迅速推广使用 的一种计算机语言。 C 语言程序设计课程是计 算机专业和信息管理专业的核心专业基础课 , 它功能丰富,表达能力强,使用灵活方便,应 用面广,目标程序效率高,可移植性好,既具 有高级语言的优点,又具有低级语言的优点。 既适用于应用软件编写,又适用于系统软件的 编写。在现代的工业机器人的众多语言中,大 多编程风格以 C 语言非常类似,学生学好 C 语 言,对将来的工作中,从事工业机器人现场编 程是非常有帮助的。 课程的性质和任务 《语言程序设计》这门课是我校工业机器人、 分布式发电与微电网专业的专业必修课。作为 计算机系的数据结构、 c++、单片机编程等课 程的前导课程,也是一门实践性很强的课程, 既要掌握概念,又要动手编程,还要上机调试 运行。对工业机器人专业来说是一门必修的课 程。 同时,这门课程也是 “湖南省非计算机专业 学生计算机应用能力水平考试 ”二级考试的主 要语种之一。 课程的教学目标 本课程的教学目标是: 通过理论和实践教学, 使学生较好地掌握 C 语言各方面的知识, 掌握 一、程序设计和 C 语言 重点:计算机程序、计算机语言、 C 语言 编译软件的安装、最简单的 C 语言程序 教 学 基 本 目 的 和 要 求

二、算法:程序的灵魂重点:简单的算法举例、算法的特性、用流程图表示算法。 三、顺序结构程序设计 重点:C 语言的数据类型、C 语句的种类、赋值语句、数据的输入输出及输入输出中最常用的控制格式。 四、选择结构程序设计重点:关系运算符与逻辑运算符及其组成的具有逻辑值的表达式、二条分支语句的格式及基本应用、多分支的选择语句。 五、循环结构程序设计重点:C 构成循环的四种方法,尤其是后三种方法、break 与continue 语句的基本作用。 难点:while 语句;do-while 语句;for 语句;循环的嵌套;break 与continue 语句。 六、数组 重点:一维数组、二维数组的定义与引用; 字符数组的定义与引用、常用字符串处理函数 及字符处理函数;数组的应用 难点:二维数组的定义与引用;字符数组; 数组的应用

相关文档
最新文档