谭浩强版C语言期末考试

2024-04-28

谭浩强版C语言期末考试(精选5篇)

篇1:谭浩强版C语言期末考试

C语言设计 学习笔记

早晨: 06:40

起床

07:20——08:20 上午: 08:30——10:30 10:50——11:30 中午: 12:00——02:00

下午: 02:30——04:30

晚上: 05:30——08:00 08:00——09:00 09:00——11:00

11:30

英语 1小时

新概念英语(单词、语法、听读背)大学英语(单词、语法、听读背)

计算机基础 2小时 计算机科学技术导论 计算机组成原理 微机原理及接口技术

Intel微处理器结构编程与接口 深入理解计算机系统 80x86汇编语言程序设计

8086-8088宏汇编语言程序设计教程 BIOS研发技术剖析 自己动手写操作系统 操作系统原理

Windows操作系统原理 Windows内部原理系列 Windows程序内部运行原理 计算机网络第五版

午休

计算机应用及编程

Windows用户管理指南、AD配置指南、网络专业指南、Windows即学即会教程

Windows下32位汇编语言程序设计、C#编程 锻炼、晚餐 辅导

专业基础 2小时

大学数学、大学物理、电机及拖动、电力电子技术、通信技术 休息

目 录

第一章 C语言概述.................................................................................................................................1.1 C程序结构特点16................................................................................................................1.2 C程序上机步骤17...................................................................................................................第二章 程序的灵魂——算法23............................................................................................................2.1 算法24.....................................................................................................................................2.2 算法的三种基本结构...............................................................................................................2.3 结构化程序设计方法42..........................................................................................................第三章 数据类型 运算符与表达式48..................................................................................................3.1 C语言的基本元素48...............................................................................................................3.2 C的数据类型48.......................................................................................................................3.3 常量与变量48..........................................................................................................................3.4 基本类型...................................................................................................................................3.5 变量63.....................................................................................................................................3.6 不同类型数据间的混合运算...................................................................................................3.7 函数的调用过程(补充).......................................................................................................第四章 最简单的C程序设计——顺序程序设计77...........................................................................4.1 字符数据的输入输出...............................................................................................................第五章 选择结构的程序设计97............................................................................................................第六章 循环结构程序设计.....................................................................................................................6.1 语句标号...................................................................................................................................6.2 break语句和continue语句......................................................................................................第七章 数组132......................................................................................................................................7.1 构造类型...................................................................................................................................7.2 数组133...................................................................................................................................7.3 二维数组...................................................................................................................................7.4 字符串——字符数组...............................................................................................................7.5 字符串处理函数 #include ......................................................................................第八章 函数153......................................................................................................................................8.1 c程序的结构154......................................................................................................................8.2 函数调用参数传递...................................................................................................................8.3 函数变量的作用范围...............................................................................................................8.4 变量的存储类别.......................................................................................................................第九章 预处理命令197........................................................................................................................9.1 预编译命令作用.....................................................................................................................第十章 指针211....................................................................................................................................10.1 变量的访问方式...................................................................................................................10.2 指针变量...............................................................................................................................第十一章 结构体270............................................................................................................................11.1 结构体270............................................................................................................................11.2 声明结构体类型变量的方法271........................................................................................11.3 结构体变量引用273............................................................................................................11.4 结构体变量初始化...............................................................................................................11.5 结构体数组275....................................................................................................................11.6 结构体类型指针...................................................................................................................11.7 链表283................................................................................................................................11.8 共用体 297...........................................................................................................................11.9 枚举类型301........................................................................................................................11.10 用typedef定义的类型304................................................................................................第十二章 位运算308............................................................................................................................12.1 位段 315...............................................................................................................................第十三章 文件319................................................................................................................................13.1 文件319................................................................................................................................13.2 文件的分类319....................................................................................................................13.3 C语言对文件的处理方法319.............................................................................................13.4 文件结构体类型321............................................................................................................13.5 文件结构体数组和指针321................................................................................................13.6 文件的操作321....................................................................................................................13.7 文件的定位333....................................................................................................................13.8 出错检测335........................................................................................................................13.9 小结336................................................................................................................................第十四章 C++对C的扩充 338...........................................................................................................14.1 C++的特点338.....................................................................................................................14.2 C++的输入输出 339.............................................................................................................14.3 C++的输出cout.....................................................................................................................14.4 C++的输入 cin 341...............................................................................................................14.4 函数的重载342....................................................................................................................14.5 带缺省参数的函数344........................................................................................................14.6 变量的引用类型345............................................................................................................14.7 内置函数 348.......................................................................................................................14.8 作用域运算符349................................................................................................................第一章 C语言概述

1.1 C程序结构特点16

1、C程序的基本构件——函数。

2、一个函数由函数首部和函数体两部分构成。

 函数首部一般包括函数类型、函数名、函数参数等。

 函数体一般包括声明部分和执行部分。其中:在声明部分中定义所用到的变量;执行部分则由若干个语句组成。

3、C程序只有一个main函数,且总是从main函数开始执行。

4、C语言语句必须以“;”结束。

5、用/*

*/作为注释。

6、C编译器一般自顶向下顺序编译C源程序,如果被调函数定义在主调函数之后位置时,要在主调函数前,给出被调函数的原型说明。以便编译器在编译被调函数的调用语句时,对调用语句进行参数检查。

如果不进行原型说明,则无法通过编译检查。

原型说明:类型说明 函数名(参数类型,参数类型,„„)

7、头文件——头文件包含了C语言的标准函数库的原型说明。

C语言通过使用#include <>预处理命令,将库函数的原型说明插入到源文件中。

1.2 C程序上机步骤17

1、编辑源文件.c;

2、编译成目标文件.obj;

3、连接——将目标程序和库函数及其他目标程序连接起来,生产可执行文件,文件扩展名为.exe;

4、执行。

结构体、共用体、枚举型。

3、指针类型:用于存储地址的一类数据类型。

4、空类型:

编译器根据变量的数据类型,给变量分配存储单元。

3.3 常量与变量48

1、符号常量——符号常量在其作用域内不能改变,也不能被赋值。#define 符号常量(大写)常量

2、变量——变量由变量名和变量值标识。数据类型 变量;

 变量名实际上是一个符号地址,编译连接程序时给每个变量名分配一个内存地址,当程序访问变量值时,实际上是通过变量名找到相应的内存地址,从其存储单元中读取数据。

3.4 基本类型

1、整形数据在内存中的存放,是以补码形式存放的。

2、实型数据:单精度 双精度。 在内存中以指数形势存放。

 若数据超过有效位,则超过C语言规定有效位的数据将被舍去,故产生误差。

3、字符型数据:用一个字节存储单元存储。即将字符的ASCII码存储到内存单元中。

 用单引号括起来的一个字符。

 转义字符——特殊字符常量或者控制字符常量,它们都以“”开头。 Char、unsigned char区别:char用7位数表示,最大表示编码为127的字符;unsigned char用8位数表示,最大表示编码为255的字符。 字符数据与整型数据可以相互赋值。

 字符数据可以以字符数据输出,也可以以整型数据形式输出。

4、字符串常量:C语言中,必须是用字符数组来保存字符串常量。在内存中顺序存储。

 用一对双引号括起来的字符序列。

(2)一般把建立存储空间的声明称为变量定义,把不需要建立存储空间的声明成为变量声明。

3.6 不同类型数据间的混合运算

 不同类型数据进行混合运算时,不同类型的数据要先转换成同一类型,按照类型级别由低到高(char,short—int——unsigned—long—double;float—double)的顺序进行转换。

 强制类型转换——(类型名)表达式。强制类型转换也就是将存储数据的内存单元强制转换为另一种数据类型的单元大小。即强制将存放数据的内存单元改变。

 赋值时进行类型转换:将数据复制给变量时,将会将数据强制转换为要赋值变量的类型。一般短类型转换为长类型时,进行符号扩展;长类型转换为短类型时,仅赋值低位,难以保证数据的正确性。

3.7 函数的调用过程(补充)

 C函数其实就是一个程序模块。

 C函数在编译时,单独编译成一个指令模块,在函数模块开始处定义保护现场指令,将用到的CPU寄存器压入堆栈。在返回时定义了恢复现场指令,将堆栈数据恢复到CPU寄存器。

 在调用函数时,一般利用堆栈传递输入参数;利用EAX传递输出参数,注意在函数调用完成后,要维持堆栈平衡,且函数返回输出参数在EAX中,在使用输出参数前,不要改变EAX的值。

第四章 最简单的C程序设计——顺序程序设计77 4.1 字符数据的输入输出

1、C语言没有输入输出语句,IO操作通过调用系统函数实现。

2、在程序的开头,要有:#include “stdio.h”或 #include ,预定义语句,用来引用头文件,在编译时将头文件中的函数原型声明添加到源文件中。

stdio.h 输入输出语句

2、数组——数组必须先定义后引用。静态数组变量定义时编译器自动初始化数据元素为0,动态数组变量在程序执行时分配存储空间,在未被赋值初始化之前其值随机。

3、C语言只能逐个引用数组元素,不能一次引用整个数组。

4、数组引用是“数组名+下标”引用,数组下标均为整数。如a[2]。

7.3 二维数组

1、数组元素为数组。

2、在内存中,C语言的二维数组中数组元素的存放顺序是按行存放的。

3、二维数组引用是“数组名+下标+下标”。如a[1][2]。

7.4 字符串——字符数组

1、一般用来标识字符串结尾。占用一个字符变量空间。

2、用字符串赋值字符数组时,C编译器在字符串后自动加赋给字符数字。

3、字符数组可以一次引用整个字符串数组。如整个字符串(数组)的输入输出,用%s格式,且在输入字符数组时,用数组名代表数组的首地址,对于二维数组,仅仅写行下标不写列下标,也可以代表给行数组的首地址。

在用%s输入输出字符串数组时,遇到结束。

7.5 字符串处理函数 #include

1、gets(字符数组名)

从键盘输入一个字符串(以回车结束),并返回字符数组的起始地址。如get(str)。

2、puts(字符数组名/字符串)

将数组中的字符串(结尾的字符序列)输出到终端上,输完换行。如puts(str),puts(“ok”)。

3、strcpy(目的字符数组1名,源字符串/字符数组2名)拷贝时,将“”一起拷贝过去。

4、strcat(字符数组1名,字符串/字符数组2名)将字符串/字符数组2连接到字符数组1中。

 在某个复合语句中定义的变量。

2、全局变量——在函数之外定义的变量。有效范围是从定义变量的位置开始到源文件结束。

8.4 变量的存储类别

变量的存储类别,即生存期。内存中供用户使用的存储空间包括:程序区、静态存储区、动态存储区。

1、静态存储区——在编译时分配空间,在程序运行完后才释放存储空间。存储静态局部变量和全局变量。

 局部静态变量在编译时赋初值,在执行时可改变该值,但该存储空间一直保存到程序结束。

 定义局部静态变量,如果没有赋初值,编译时会自动赋默认初值。 局部静态变量只能在定义它的函数中使用。 全局变量都是静态的。

 利用extern 外部变量方式表示变量的定义在别的文件中,提示编译器遇到此变量时,在其他模块中寻找其定义。而函数则是利用函数原型来声明。 用static 关键字说明一个不能在其他源文件中引用的全局变量。即静态全局变量在声明它的整个文件都是可见的,但是在文件之外是不可见的。

2、动态存储区——仅在在执行时分配空间,用完后释放存储空间。存放自动变量和形式参数。

 寄存器变量——用register关键字说明。寄存器变量对寄存器的占用是动态的。

第九章 预处理命令197 9.1 预编译命令作用

预编译命令主要完成宏定义、文件包含、条件编译三种功能。

1、宏定义——指用一个指定的标识符(名字)来代表一个字符串。在预编译时,将宏名替代成字符串的过程称为宏展开。如:

 # define PI 3.1415926 定义宏, # undef PI

终止宏定义的作用域。

 #define V(a,b,c)a*b*c 定义带参数的宏。当宏展开时,将引用宏名语句中的实参字符串代替宏定义的形参字符串。int v =V(2,3,4)则宏展开后为:int v= 2*3*4;

2、文件包含——指一个源文件可以将另一个源文件的全部内容包含进来。如:  #include “文件名”或

#include <文件名>  编译预处理时,将包含文件的全部内容复制到源文件中。在编译时作为一个源程序来编译。

3、条件编译——在预编译处理时,确定编译时要编译的部分。如:

0

而数组名的值不可以改变。

6、函数的指针专门用来存放函数的入口地址,当把函数的地址赋值给它时,它就指向该函数的入口地址。

声明格式:数据类型(*指针变量名)()如:int(*P)();

赋值格式:p=max; 注max为定义的函数名;函数名代表该函数的入口地址。引用格式:c=(*p)(a,b);等价——c=max(a,b);

7、只能将变量已分配的地址赋值给指针变量,不能直接将整数赋值给指针变量。

8、指针变量可以有null值,防止指针误作用。

第十一章 结构体270 11.1 结构体270

1、作用——将不同类型的数据组合成一个有机的整体。

2、结构体的定义——结构体是一种数据结构,按照某种规则定义,将若干个不同数据类型(也可相同)的数据项的组合成的一个有机整体。

3、声明结构体类型的形式:struct 结构体类型名字 {成员列表};  成员列表形式:类型符 成员名

如:int num;

11.2 声明结构体类型变量的方法271

1、先定义结构体类型:struct 结构体类型名字 {成员列表};再定义结构体变量:struct结构体类型名字 结构体变量名。

2、可在定义结构体类型时,定义结构体类型变量。struct 结构体类型名字 {成员列表}结构体类型变量1,结构体类型变量2,„„;

11.3 结构体变量引用273

1、不能将一个结构体变量作为一个整体进行输入输出,只能对结构体变量成员分别赋值。

2、结构体变量成员引用方式:结构体变量名.成员名

3、如果结构体变量成员是另一个结构体变量,则要用若干个成员运算符,一级一级找到最低一级的成员。

11.8 共用体 297

1、共用体指将几种不同类型的变量存储在同一段内存单元中。

2、共用体变量的存储单元大小等于最长成员变量所占内存的长度

3、共用体变量中起作用的是最后一次存放成员。

4、共用体类型声明方式:union 公用体类型名称 {成员变量列表};

5、共用体变量声明方式:(1)union 公用体类型名称 {成员列表}共用体变量;(2)先声明共用体类型,然后声明共用体变量,union 公用体类型名称 共用体变量。

11.9 枚举类型301

1、枚举类型——指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内的一个。

2、声明枚举类型:enum 枚举类型名称 {枚举常量列表};

3、声明枚举变量:enum 枚举类型名称 枚举类型变量;

 普通文件——指磁盘文件。

2、从操作系统的角度看:每一个与主机相关联的输入输出设备都可看作一个文件。

(1)根据文件的组织形式分为:顺序存取文件 和 随机存取文件。(2)根据文件的存储形式分为:ASCII文件 和 二进制文件。

13.3 C语言对文件的处理方法319 C语言中对文件的存取是以字符(字节)为单位的,一个输入输出流就是一个字节流或二进制流。

文件的存储方式分为缓冲文件系统和非缓冲文件系统。区别是缓冲文件系统是系统自动开辟缓冲区,非缓冲文件系统是由程序为每个文件设定缓冲区。

ANSI C标准只采用 缓冲文件系统 来处理文件。

13.4 文件结构体类型321 缓冲文件系统中,每个被使用的文件都在内存中开辟一个FILE结构体类型的区,用来存放文件的有关信息(文件名字、文件状态、当前位置、缓冲区等有关信息),FILE结构体类型原型:  typedef struct{

short level;

/*缓冲区“满”或“空”的程度*/

unsigned flags;/*文件状态标志*/

char fd;

/*文件描述符*/

unsigned char hold;/*如无缓冲区不读取字符*/

short bsize;

/*缓冲区的大小*/

unsigned char *buffer;/ *数据缓冲区的位置*/

unsigned char *curp;/*指针,当前的指向*/

unsigned istemp;/*临时文件,指示器*/

short token;/*用于有效性检查*/}FILE;

13.5 文件结构体数组和指针321 FILE *fp——声明了一个指向FILE类型结构体的指针变量。

buffer:是一个指针。对fread 来说,它是读入数据的存放地址。对fwrite来说,是要输出数据的地址(均指起始地址)。

size:

要读写的字节数。

count: 要进行读写多少个size字节的数据项。fp:

文件型指针。

6、格式化读写函数:

 fprintf(文件指针,格式字符串,输出表列);  fscanf(文件指针,格式字符串,输入表列);

注意:

用fprintf和fscanf函数对磁盘文件读写,使用方便,容易理解,但由于在输入时要将ASCII码转换为二进制形式,在输出时又要将二进制形式转换成字符,花费时间比较多。因此,在内存与磁盘频繁交换数据的情况下,最好不用fprintf和fscanf函数,而用fread和fwrite函数。

7、以“字”或者整数为单位读写函数:  putw(int i,FILE * fp);  int i = getw(FILE * fp);

8、以“字符串”为单位读写文件的函数:

 fgets(str,n,fp);从fp指向的文件读出n-1个字符,在最后加一个’’。返回值:str的首地址。如果遇到EOF则读入结束。

 fputs(“china”,fp);把字符串写入到fp指向的文件。第一个参数可以是字符串常量、字符数组名或字符型指针。字符串末尾的′\0′不输出。

13.7 文件的定位333

1、将文件当前的位置指针重新返回到文件的开头位置:无返回值。 rewind(fp);执行后,将文件的位置指针重新定位到文件的开头。

2、随机读写:改变文件的位置指针,一般用于二进制文件。 fseek(文件类型指针,位移量,起始点);无返回值。起始点:文件开头

SEEK_SET

0

文件当前位置

SEEK_CUR

文件末尾

SEEK_END

putw()把一个字输出到指定文件

fread()从指定文件中读取数据项

fwrite()把数据项写到指定文件中

fscanf()从指定文件按格式输入数据

fprintf()按指定格式将数据写到指定文件中

第十四章 C++对C的扩充 338 14.1 C++的特点338

1、C++保留了C语言原有的所有优点,增加了面向对象的机制。

2、C++源文件以.cpp为后缀。

3、除了可以用 /*……*/ 形式的注释行外,还允许使用以// 开头的单行注释。

4、除了可以用printf函数输出信息外,还可以用cout进行输出。cout的作用是将<<运算符右侧的内容送到输出设备中输出。使用cout需要用到头文件iostream.h,在程序的第一行用#include命令将该头文件“包含”进来。

 cout <<“ This is a c++ program.n” ;

14.2 C++的输入输出 339 C++为了方便使用,除了可以利用printf和scanf函数进行输出和输入外,还增加了标准输入输出流cout和cin。cout是由c和out两个单词组成的,代表C++的输出流,cin是由c和in两个单词组成的,代表C++的输入流。它们是在头文件iostream.h中定义的。在键盘和显示器上的输入输出称为标准输入输出,标准流是不需要打开和关闭文件即可直接操作的流式文件。

14.3 C++的输出cout

1、cout必须和输出运算符<<一起使用。<< 在这里不作为位运算的左移运算符,而是起插入的作用,例如:cout<<“Hello!n”;的作用是将字符串“Hello!n” 插入到输出流cout中,也就是输出在标准输出设备上。

2、也可以不用n控制换行,在头文件iostream.h中定义了控制符endl代表回车换行操作,作用与n相同。endl的含义是end of line,表示结束一行。

0

存。在C++中,这种输入操作称为“提取”(extracting)或“得到”(getting)。>> 常称为“提取运算符”。

2、cin要与 >> 配合使用。例如:

3、C++为流输入输出提供了格式控制,如:dec(用十进制形式),hex(用十六进制形式),oct(用八进制形式),还可以控制实数的输出精度等。

14.5 函数的重载342

1、C++允许在同一作用域中用同一函数名定义多个函数,这些函数的参数个数和参数类型不同,而且函数类型也可不同,这就是函数的重载,即一个函数名多用。

2、系统会根据参数的类型和个数找到与之匹配的函数,并调用不同的函数。

14.6 带缺省参数的函数344 C++允许实参个数与形参个数不同。办法是在形参表列中对一个或几个形参指定缺省值(或称默认值)。

例如某一函数的首部可用如下形式:

void fun(int a,int b,int c=100)在调用此函数时如写成fun(2,4,6),则形参a,b,c的值分别为2,4,6(这是与过去一样的)。如果写成fun(2,4),即少写了最后一个参数,由于在函数定义时已指定了c的缺省值为100,因此a,b,c的值分别为2,4,100。请注意:赋予缺省值的参数必须放在形参表列中的最右端。例如:

void f1(float a,int b,int c=0,char d=′a′)(正确)void f2(float a,int c=0,char d=′a′,int b)

(不正确)注意:不要同时使用重载函数和缺省参数的函数,因为当调用函数时少写一个参数,系统无法判定是利用重载函数还是利用缺省参数的函数,会发生错误。

14.7 变量的引用类型345

1、“引用”(reference)是C++的一种新的变量类型,是对C的一个重要扩充。它的作用是为一个变量起一个别名。

2、假如有一个变量a,想给它起一个别名b,可以这样写:

int a;

实参把变量名传给形参。i的名字传给引用变量a,这样a就成了i的别名。同理,b成为j的别名。a和i代表同一个变量,b和j代表同一个变量。在swap函数中使a和b的值对换,显然,i和j的值同时改变了。

当读者看到&a这样的形式时,怎样区别是声明引用变量还是取地址的操作呢?请记住,当&a的前面有类型符时(如int &a),它必然是对引用的声明;如果前面无类型符(如&a),则是取变量的地址。

14.8 内置函数 348 调用函数时需要一定的时间,如果有的函数需要频繁使用,则所用时间会很长,从而降低程序的执行效率。C++提供一种提高效率的方法,即在编译时将所调用函数的代码嵌入到主调函数中。这种嵌入到主调函数中的函数称为内置函数(inline function),又称内嵌函数。

例如:

#include inline int max(int a,int b,int c)//这是一个内置函数,求3个整数中的最大者

{ if(b>a)a=b;if(c>a)a=c;return a;} void main(){int i=7,j=10,k=25,m;m=max(i,j,k);cout<<“max=”<

14.9 作用域运算符349

1、作用域运算符∷,∷aa表示全局作用域中的变量。

2、不能用∷ 访问函数中的局部变量。

425-

篇2:谭浩强版C语言期末考试

endl 换行并刷新输出流

setw(n)设置字段位数为n hex,oct,dec 十六进制,八进制,十进制表示 setfill 定义填充字符

setprecision 定义浮点数的精度 left,right 左对齐,右对齐

showpoint 强制显示小数点以及全部尾部0 C++通过给常量命名的方式定义常量:

const<数据类型名><常量名>=<表达式> 用const定义的标识符常量时,一定要对其初始化。在说明时进行初始化是对这种常量置值的唯一方法,不能用赋值运算符对这种常量进行赋值。函数声明的一般形式为

函数类型 函数名(参数表)函数模板的定义

template

函数定义

例子:template T max(T a,T b){ return(a>b)? a:b;} 定义函数模板时可以使用多个类型参数,每个类型参数前面只需加上关键字typename或class,用逗号分隔:

template 例子:template T1 max(T1 a,T2 b){ return(a>b)? a :(T1)b;} 有默认参数的函数:实参与形参的结合是从左至右进行的,因此指定默认值的参数必须放在形参列表中的最右端 引用

定义

对变量起另外一个名字(别名alias),这个名字称为该变量的引用。<类型>&<引用变量名> = <原变量名>;

其中原变量名必须是一个已定义过的变量。如:

int

max;

int &refmax=max;refmax并没有重新在内存中开辟单元,只是引用max的单元。max与refmax在内存中占用同一地址,即同一地址两个名字。对引用类型的变量,说明以下几点:

1、引用在定义的时候要初始化

2、对引用的操作就是对被引用的变量的操作。

3、引用类型变量的初始化值不能是一个常数。

4、一旦引用被声明,它就不能再指向其它的变量。

5、对引用的初始化,可以用一个变量名,也可以用另一个引用。

6、引用同变量一样有地址,可以对其地址进行操作,即将其地址赋给一指针。当&m的前面有类型符时(如int &m),它必然是对引用的声明;如果前面无类型符(如cout<<&m),则是取变量的地址。

7、对常量(用const声明)的引用使用如下方式: int i=5;const int &a=i;内联函数定义的一般格式为:

inline <函数值类型><函数名>(<参数表>){ <函数体> } 作用域运算符

::a表示全局作用域中的变量a。注意:不能用::访问函数中的局部变量

new运算从堆中分配一块与<类型>相适应的大小为<元素个数>的数组存储空间,若分配成功,将这块存储空间的起始地址存入<指针变量名>,否则置<指针变量名>的值为NULL(空指针值,即0)。new的使用格式为:

<指针变量名>=new <类型>[<元素个数>];delete运算符用来释放<指针变量名>指向的动态存储空间。使用格式如下:

delete <指针变量名> 或

delete[] <指针变量名>

第2章 面向对象基本概念

面向过程编程与面向对象编程的区别:

面向过程编程先确定算法,再确定数据结构; 面向对象编程先确定数据结构,再确定运算。类定义:

class <类名> { <访问控制符>: <成员函数的声明> <访问控制符>: <数据成员的声明> };<成员函数的实现> 若在类体外实现,则需要使用作用域运算符“::”,用它来标识某个成员函数是属于哪个类的,其定义格式如下:

<函数值类型><类名>::<成员函数名>(<参数表>){ <函数体> } 类外访问对象中的成员可以有3种方法: 通过对象名和成员运算符访问对象中的成员。<对象名>.<公有成员> 通过指向对象的指针变量访问对象中的成员。<对象指针名>-><公有成员> 通过对象的引用访问对象中的成员。析构函数其定义格式如下: <类名>::~<类名>(){

<函数体> } 在一般情况下,调用构造函数与声明对象的顺序相同,而调用析构函数的次序正好与创建对象的顺序相反。三种构造函数

Box();

//无参构造函数 Box(int h,int w ,int len):height(h),width(w),length(len){}

//带参构造函数 复制构造函数定义

<类名>(<参数表>);

<类名>(const <类名>&<对象名>)Box(const Box& b);//复制构造函数

复制构造函数只有一个参数,并且是对同类对象的引用。

静态成员是类的所有对象共享的成员,而不是某个对象的成员,它在对象中不占存储空间,是属于整个类的成员。静态成员定义格式如下: static <静态成员的定义>;不能用参数初始化表对静态数据成员初始化,也不能在构造函数体内初始化,静态数据成员只能在类体外进行初始化。静态数据成员初始化格式如下:

<数据类型><类名>::<静态数据成员名>=<值>;在类的成员函数中可以直接访问该类的静态数据成员,而不必使用成员访问运算符或类名限定修饰符。

在类外必须使用成员访问运算符或类名限定修饰符访问公共静态数据成员。<对象名>.<静态成员> <类名>::<静态成员> 静态成员函数就是使用static关键字声明的成员函数。

静态成员函数可以直接访问该类的静态成员,但不能直接访问类中的非静态成员。

第3章 详解对象

对象指针就是用于存放对象数据起始地址的变量。声明对象指针的一般格式为: <类名> *<对象指针名>;对象指针的初始化一般格式为: <数据类型> *<对象指针名>=&<对象名>;<对象指针名>=&<对象名>;通过指针访问对象成员一般格式如下: <对象指针名>-><公有成员>

boxp->volumn();(*<对象指针名>).<公有成员>

(*boxp).volumn();this指针是一个特殊的隐含指针,它隐含于每一个成员函数(静态成员函数除外)中,也就是说,每个成员函数都有一个this指针参数。

this指针指向调用该函数的对象,即this指针的值是当前被调用的成员函数所在的对象的起始地址。

复制构造函数中隐含使用this指针: TAdd(const TAdd& p){

this->x=p.x;this->y=p.y;

cout<<“copy constructor.”<

x

this->x

(*this).x this指针是一个const指针,成员函数不能对其进行赋值。

静态成员中不能访问this指针,因为静态成员函数不从属于任何对象。指向非静态数据成员的指针一般形式为:

数据类型名

*指针变量名;

定义指向公有成员函数的指针变量的一般形式为: 数据类型名(类名:: *指针变量名)(参数列表);

使指针变量指向一个公有成员函数的一般形式为:

指针变量名=&类名::成员函数名 常量定义格式如下: const <数据类型名><常量名>=<表达式>;常对象是其数据成员值在对象的整个生存期间内不能被改变的对象。const <类名> <对象名>(<初始化值>);<类名> const <对象名>(<初始化值>);常成员函数

通过常成员函数来引用本类中的常数据成员。<数据类型><函数名>(<参数表>)const;

声明一维对象数组的一般格式为: <类名><数组名>[<下标表达式>] 6 第4章 运算符重载

重载为类的成员函数格式如下: <类名> operator <运算符>(<参数表>){ 函数体 } A operator +(A &);++为前置运算符时,它的运算符重载函数的一般格式为: operator ++()++为后置运算符时,它的运算符重载函数的一般格式为: operator ++(int)

运算符重载函数不能定义为静态的成员函数,因为静态的成员函数中没有this指针。

友元声明以关键字friend开始,只能出现在被访问类的定义中。具体格式如下:

friend <函数值类型><函数名>(<参数表>);friend class <类名>;

友元函数可以访问该类中的所有成员(公有的、私有的和保护的)

通常使用友元函数来取对象中的数据成员值,而不修改对象中的成员值,保证数据安全。

重载为类的友元函数语法形式

friend <函数值类型> operator <运算符>(<参数表>){<函数体>;} ++为前置运算符时,它的运算符重载函数的一般格式为: A operator ++(A &a)++为后置运算符时,它的运算符重载函数的一般格式为: A operator ++(A &a, int)

重载提取运算符的一般格式为:

friend istream & operater >>(istream &, ClassName &);istream & operater >>(istream &is, ClassName &f){„} 重载输出(插入)运算符的一般格式为:

friend ostream & operater >>(ostream &, ClassName &);ostream & operater >>(ostream &is, ClassName &f){„} 重载类型转换运算符函数格式: operator〈返回基本类型名〉(){

„„

return 〈基本类型值〉 } 类类型转换函数只能是成员函数,不能是友元函数。转换函数的操作数是对象。8 第5章 继承与派生

派生是指由基类创建新类的过程。class A { int i;//基类成员};class B:public A //A派生了B,B继承了A,//B自动拥有A的成员 {int j;//定义派生类的新成员};派生类的定义格式如下:

class <派生类名>:<继承方式><基类名> { <派生类新定义成员>};派生类继承了基类的全部数据成员和除了构造、析构函数之外的全部成员函数,它们在派生类中的访问属性由继承方式控制。三种继承方式下派生类中基类成员的访问控制权限

无论是哪种继承方式,基类的私有成员在派生类中都是不可被访问的。只能通过基类的成员函数访问基类的私有数据成员。

解决的办法是通过成员初始化表来完成,在成员初始化表中可以显式调用基类构造函数。

<派生类名>(<总参数表>):<基类名>(<参数表1>),<对象成员名>(<参数表2>){ <派生类数据成员的初始化> };构造函数调用顺序为:基类的构造函数→对象成员构造函数→派生类的构造函数。

析构函数调用顺序刚好相反。当基类中没有显式定义构造函数,或定义了无参构造函数时,派生类构造函数的初始化表可以省略对基类构造函数的调用,而采用隐含调用。当基类的构造函数使用一个或多个参数时,派生类必须定义构造函数,提供将参数传递给基类构造函数的途径。这时,派生类构造函数的函数体可能为空,仅起到参数传递作用。

如果在基类中既定义了无参构造函数,又定义了带参构造函数,则在定义派生类构造函数时,既可以包含基类构造函数和参数,也可以不包含基类构造函数。如果在一个派生类中要访问基类中的私有成员,可以将这个派生类声明为基类的友元。

友元关系是不能继承的。B类是A类的友元,C类是B类的派生类,则C类和A类之间没有任何友元关系,除非C类声明A类是友元。多继承派生类的定义

class <派生类名>:<继承方式><基类名1>,„,<继承方式><基类名n> {<派生类新定义成员>};多继承派生类的构造函数

<派生类名>(<总参数表>):<基类名1>(<参数表1>),„,< 基类名n>(<参数表n>){ <派生类数据成员的初始化> };<总参数表>必须包含完成所有基类初始化所需的参数 构造函数调用顺序是:先调用所有基类的构造函数,再调用对象成员类构造函数,最后调用派生类的构造函数。

处于同一层次的各基类构造函数的调用顺序取决于定义派生类时所指定的基类顺序,与派生类构造函数中所定义的成员初始化列表顺序无关。如果有多个成员类对象,则构造函数的调用顺序是对象在类中被声明的顺序,而不是它们出现在成员初始化表中的顺序。

析构函数的调用顺序与构造函数的调用顺序相反。虚基类

虚基类的定义格式为:

class <派生类名>:virtual <继承方式><共同基类名>;【说明】引进虚基类后,派生类对象中只存在一个虚基类成员的副本。虚基类的初始化与一般多继承的初始化在语法上相同,但构造函数的调用顺序有所不同,规则如下:

先调用虚基类的构造函数,再调用非虚基类的构造函数。若同一层次中包含多个虚基类,其调用顺序为定义时的顺序。若虚基类由非虚基类派生而来,则仍按先调用基类构造函数,再调用派生类构造函数的顺序。

如果在虚基类中定义了带参数的构造函数,则要在其所有派生类(包括直接派生类或间接派生类)中,通过构造函数的初始化表对虚基类进行初始化。

第6章 多态性与虚函数

类型兼容规则

类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。

类型兼容规则中所指的替代包括以下情况: 派生类的对象可以赋值给基类的对象。派生类的对象可以初始化基类的引用。

派生类的对象的地址可以赋值给基类的指针变量。在替代之后,派生类对象就可以作为基类的对象使用,但只能访问从基类继承的成员。

只能用派生类对象对其基类对象赋值,而不能用基类对象对其派生类对象赋值。同一基类的不同派生类对象之间也不能赋值。虚函数

虚函数就是在基类中被关键字virtual说明、并在一个或多个派生类中被重新定义的成员函数。

声明虚函数的格式如下:

virtual <函数值类型><函数名>(<参数表>);在派生类中重新定义虚函数时,其函数原型包括返回类型、函数名、参数个数、类型和顺序,都必须与基类中的原型相同。一个函数一旦被声明为虚函数,则无论声明它的类被继承了多少层,在每一层派生类中该函数都保持虚函数特性。因此,在派生类中重新定义该函数时,可以省略关键字virtual。实现动态的多态性时,必须使用基类类型的指针变量或对象引用,并使其指向不同的派生类对象,并通过调用指针或引用所指向的虚函数才能实现动态的多态性。可将类簇中具有共性的成员函数声明为虚函数,而具有个性的函数没有必要声明为虚函数。但是下面的情况例外: 静态成员函数不能声明为虚函数。构造函数不能是虚函数。

内联成员函数不能声明为虚函数。析构函数可以是虚函数。虚析构函数

虚析构函数的声明格式如下:

virtual ~<类名>();如果一个类的析构函数是虚函数,那么,由它派生的所有子类的析构函数也是虚函数。

纯虚函数用virtual声明,没有任何实现、必须由派生类覆盖该函数提供实现 纯虚函数的声明格式为:

virtual <函数值类型><函数名>(<参数表>)=0;包含一个或多个纯虚函数的类称为抽象类。

如果派生类没有实现基类中的所有纯虚函数,派生类也是抽象类。抽象类无法实例化,即不能创建抽象类的对象。第7章 输入输出

iostream:I/O流类库的最主要的头文件,包含了对输入输出流进行操作所需的基本信息,还包括cin、cout、cerr和clog共4个流对象。fstream:用于用户管理的文件的I/O操作。strstream:用于字符串流I/O。

stdiostream:用于混合使用C和C++的I/O操作。iomanip:使用格式化I/O时应包含此头文件。

用setf函数设置状态标志,其一般格式如下:

long ios::setf(long flags)清除状态标志

用unsetf函数清除状态标志,其一般格式如下: long ios::unsetf(long flags)用函数flags取状态标志有两种形式,其格式分别如下: long ios::flags()

//返回与流相关的当前状态标志值 long ios::flags(long flag)//将流的状态标志值设置为flag,并返回设置前的状态标志值。以上三组函数必须用流类对象(cin或cout)来调用,其格式如下: <流对象名>.<函数名>(ios::<状态标志>)cout.setf(ios::showpos);cout.setf(ios::scientific);cout.setf(ios::showpos| ios::scientific);设置输出宽度函数有两种形式,其格式分别如下:

int ios::width(int len)

int ios::width()第一种形式是设置输出宽度,并返回原来的输出宽度;

第二种形式是返回当前输出宽度,默认输出宽度为0。只对其后的第一个输出项有效。

填充字符的作用是当输出值不满输出宽度时用填充字符来填充,默认填充字符为空格。它与width()函数配合使用,否则没有意义。设置填充字符函数有两种形式,其格式分别如下:

char ios::fill(char ch)

char ios::fill()第一种形式是重新设置填充字符,并返回设置前的填充字符; 第二种形式是返回当前的填充字符。

设置浮点数输出精度有两种形式,其格式分别如下:

int ios::precision(int p)

int ios::precision()第一种形式是重新设置输出精度,并返回设置前的输出精度; 第二种形式是返回当前的输出精度。默认输出精度为6 用get函数读入一个字符(1)不带参数的get函数

cin.get()用来从指定的输入流中提取一个字符(包括空白字符),函数的返回值就是读入的字符。

若遇到输入流中的文件结束符,则函数返回文件结束标志EOF。(2)有一个参数的get函数

cin.get(ch)用来从输入流中读取一个字符,赋给字符变量ch。读取成功返回非0值(真),如失败(遇文件结束符)则函数返回0值(假)。3)有三个参数的get函数

cin.get(字符数组/字符指针,字符个数n,终止字符)从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组)。如果在读取n-1个字符之前遇到指定的终止字符,则提前读取结束。如果读取成功返回非0值(真),如失败(遇文件结束符)则函数返回0值(假)。用getline函数读入一行字符

cin.getline(字符数组(或字符指针),字符个数n,终止字符)从输入流中读取一行字符,其用法与带3个参数的get函数类似。eof函数

无参函数,表示文件结束。

从输入流读取数据,如果到达文件末尾(遇文件结束符),返回非零值(真),否则为0(假)。

while(!cin.eof())peek函数

无参函数,表示“观察”,观测下一个字符。

返回值是当前指针指向的当前字符,但只是观测,指针仍停留在当前位置,并不后移。

如果要访问的字符是文件结束符,则函数值是EOF。

c=cin.peek(); putback函数

将前面用get或getline函数从输入流中读取的字符ch返回到输入流,插入到当前指针位置,以供后面读取。

控制符不属于任何类成员,定义在iomanip头文件中 设置输入/输出宽度setw(int)用整型参数来制定输入/输出域的宽度。使用时只对其后一项输入/输出有效。当用于输出时,若实际宽度小于设置宽度时,数据向右对齐,反之则按数据的实际宽度输出。

当用于输入时,若输入的数据宽度超过设置宽度时,超出的数据部分被截断而被作为下一项输入内容。

设置输出填充字符setfill(char)与ios::fill相同,常与setw(int)联合使用,从而向不满设置输出宽度的空间填入指定的字符,不设置则填空格。设置后直至下一次设置前一直有效。参数可以是字符常量或字符变量。

设置输出精度setprecision(int)指明输出实数的有效位数。

参数为0时,按默认有效位数6输出。

在以fixed形式和scientific形式输出时参数为小数位数。

setiosflags(ios::fixed)用定点方式表示实数。

setiosflags(ios::scientific)用科学记数法方式表示实数。

如果setprecision(n)与setiosflags(ios::fixed)合用,可以控制小数点右边的数字个数。

如果setprecision(n)与setiosflags(ios::scientific)合用,可以控制科学记数法中尾数的小数位数。

setiosflags(ios::left)输出数据左对齐 setiosflags(ios::right)输出数据右对齐

设置输入/输出整型数数制dec、hex和oct。控制换行的控制符endl

代表输出单字符“”的控制符ends open()函数的原型在fstream中定义。其原型为:

void open(char *filename,int mod,int access);其中第一个参数是用来传递文件名;第二个参数的值决定文件的使用方式;第三个参数的值决定文件的访问方式。

篇3:谈C语言上机考试的自动评分

若采用系统自动评分,不但将考生作弊的可能大幅减小,并且智能化的给学生的程序进行评分,以取代教师的低效率的、机械的阅卷模式,改变了院校人工批阅上机考试的现状,更加直观地反应学生的学习水平和教师的教学成果。因此,自动评分技术的研究与实现,在高等教育领域和计算机考试中具有十分重要的实际意义。本文以C语言程序设计为例,给出一种利用LD算法实现自动评分的方法。

1 填空改错题的评分

C语言上机考试系统的题型一般情况下,不外乎有填空题、改错题和编程题,其中填空题和改错题的评分完全可以将比较来判定成绩,即通过比较原题和学生答题找到最长不同字符串,然后将该字符串同标准答案比较即可。其实现方法在VB6.0中可以用以下源代码实现:函数名为CompStrFun,形参indata、dindata表示学生答题结果、试题标准答案,均为字符串类型。该函数返回两个参数最长不同字符串的长度。

2 编程题的评分

对C语言考试系统中的编程题,因为不同学生考虑问题的角度和解决问题的思路与方法存在差异,于是同样的问题学生给出的争取答案多种多样,从而造成系统无法给出标准的答案。

目前,多数程序设计类课程的上机考试系统对于编程题的评判,多是采用比较程序运行所输出结果的文件,而不考虑学生所编写程序。虽然这样能够确保编程完全正确的学生获得该题满分,但是这样造成了以下两种不合理的情况存在。第一种情况,完全不编程而直接通过编辑输出文件来获取满分的情况;第二种情况:编写的程序大部分正确,但程序无法运行得零分的情况。

对于第一种情况,在学生提交考试结果时的时候通过重新生成结果文件来避免。即先删除学生答题所产生的结果文件,再调用编译系统重新编译连接学生编写的程序,生成可执行的exe文件并运行产生最新的结果文件,然后和标准结果进行比较。这样即使学生直接编辑结果文件正确,但没有编写程序,也无法获取成绩。此情况在VB6.0中可以编写如下函数代码来实现。

‘函数名:AgainExe()

‘参数:形参FileName表示学生所编写的源程序文件(包含路径)。

‘返回值:True表示成功重新生成exe文件,Flase表示生成exe文件失败。

Public Function AgainExe(ByVal FileName As String)As Integer

Shell"VCVARS32.BAT"'设置运行环境参数

AgainExe=Shell("Cl.exe"&App.Path&FileName,vbNormalFocus)

End Function

对于第二种情况,因学生的主观因素造成学生的答题结果存在着差异,而编程题的答案并不是唯一的。这样造成该类型的题目并不能采用上述填空改错题的方式来评分。本文通过文本相似性来实现编程题的评分,即借助距离编辑(LD)算法,将学生答案和标准答案进行比较获得答案相似度作为得分比例,然后乘以该题总分作为学生该题的得分。

3 距离编辑算法实现

距离编辑算法(简称LD算法)是以一个字符串A转换成另一个字符串B的过程中,所进行的插入、删除、替换等操作的次数表示两个字符串的相似度。在上机考试系统中,从学生答案读取程序行作为字符串A,而标准答案读取程序行作为字符串B,然后即可按行执行LD算法。

例如学生程序行“x=a[j]”如何变成标准程序行“x=b[++i]”呢?第1步,a替换成b,x=a[j]→x=b[j];第2步,j替换成i,x=b[j]→x=b[i];第3步,在i前插入++,x=b[i]→x=b[++i]。故x=a[j]和x=b[++i]的编辑距离为3。

在VB6.0中实现该算法的函数源代码如下:其中函数名为LD,形参StrA、StrB表示学生答题结果、试题标准答案,均为字符串类型。该函数返回两个参数的编辑距离。

4 结论

本文提出的计算机自动评分方法,已经应用于程序课上机考试系统中。不但可以将该系统作为《C语言程序设计》课程的期末上机考试系统,另一方面还可以让学生熟悉二级语言考试环境,从而提高计算机等级考试通过率。

摘要:在程序设计课的上机考试系统中,如何实现自动评分是最为关键的部分。该文对不同题型给出了不同的评分方法,其中编程题的评分,采用学生答案和标准答案之间的编辑距离作为评分依据,将LD算法用于考试系统的自动评分,并给出用VB6.0实现的函数代码。

关键词:自动评分,考试系统,VB6.0,LD算法

参考文献

[1]吴宗东,李兵元.浅谈SHELL函数使用新法[J].新疆石油科技,2000,21(2):76-80.

[2]王振明,李俊龙.一种简易的文本内容比较算法及在VB中的实现[J].计算机应用与软件,2007,24(8):199-221.

篇4:谭浩强版C语言期末考试

摘 要: 文章通过对大学C语言程序设计考试过程的实践,对传统C语言程序设计教学考试的弊端进行了客观分析,阐述了进行无纸化考试的优势,并根据所在学校的考试改革实践情况,介绍了C语言程序设计无纸化考试的改革。

关键词: C语言程序设计 无纸化 B/S C/S 数据库

1.引言

C语言程序设计是大学理工科学生的一门公共基础课,旨在帮助学生了解一门计算机语言,以及通过语言进行程序设计,形成编程解决问题的能力,动手能力又是培养理工科学生的重点。大学教师应该紧紧围绕如何提高学生的动手能力。想办法实现C语言程序设计由传统的笔试到无纸化考试的转换,可以达到提高学生动手能力、检验学生动手能力的目的,从而有必要对C语言程序设计课程考试进行改革。

2.普通高校C语言程序设计课程考试现状分析

目前普通高校C语言程序设计考核方式大部分采用的是笔试,因此,老师每次出题时,总是在出考试题目上花费很多时间和精力,并且要充分考虑到试题能否完全考查C语言程序设计课程知识点,而且要考虑题目的难易度,考虑是否与以往试题雷同,考虑能否考查广大学生的综合能力等,选好试题后,还要相应地进行排版、制卷等工作,在考试完成后,又需要评分。这个过程要花费很多时间才能够完成。而且即使是只有这一门课程,因为每次考试都要求更新,这样又要重新出题。

C语言程序设计传统笔试考试的不足:(1)传统笔试试题均是由手工设置的,在公平上很难达到高标准,当然就很难高效地反映学生水平,所以不便于教师客观公正地考评学生。(2)传统考试的试卷通常只有一到二套,所以学生试卷基本相同,容易出现作弊现象。(3)传统考试需要制作纸质的试卷,从而需要进行排版、印刷,而且纸张需求量很大。

3.无纸化C语言程序设计课程考试系统的优势

无纸化C语言程序设计课程考试系统可以有效避免出题时主观性太强,并且不再是追求片面的理论,有效地降低命题老师的工作量,同时也使考试内容、难度更公平和客观,真正全面科学地反映学生水平,从而使考试的考核质量大大提高。

C语言程序设计无纸化考试的优点:(1)试卷的生成、阅卷迅速。C语言程序设计无纸化考试的试卷由系统自动生成,其数据是可来源于数据库,数据库的内容往往是海量存储,阅卷评分系统是自动进行的,相对于传统的考试,无纸化考试具有更加准确和迅速的优点,完全无人为因素,从而使得整个考核过程更公平、公正。(2)试卷客观性强。C语言程序设计无纸化考试系统的抽题方式通常是B/S模式或C/S模式,它们的共同特点是试卷抽题面广、试卷覆盖面大,同时又可生成许多套试卷,全面地反映出每一位考生的真正实力,更客观地保证考试的准确性和公平性。(3)试卷的安全性、保密性强。C语言程序设计相对于传统的考试,其题目是采用题库抽题,考试前没有任何试卷,而且试题库都作了加密处理,除原始出题老师知道导入的题目外,其他人很难知道题库的海量内容,所有试卷都是考试开始时由计算机考试系统随机生成的,而且每一位考生的试卷都不一样,试卷安全性很高,保密性非常强。

4.C语言程序设计无纸化考试研究

(1)无纸化考试系统的指导思想。无纸化考试系统是采取自动组卷、阅卷和具有考试系统管理等功能的考试系统,并且这种无纸化考试系统可以根据用户的不同需求,管理不同类型试卷的题目编制、审阅试卷及评分等。

(2)无纸化考试的科学性和公平性。C语言程序设计课程无纸化考试时,随机生成学生试卷,所以每位学生的考试试卷都不会相同,这当然就会增加考试系统软件开发的难度,在出题时老师应为各种试题设置不同难度系数,每套试卷的难易程度要相当,以保证学生考核的公平、公正。

(3)无纸化考试系统试题库的建设。此环节中有许多基本要素,如题型要求多样化、内容要求全面化、题量要求海量化等,这样才能全面考查学生对C语言程序设计知识的掌握情况,这是考试系统建题库所要考虑的。

(4)程序考试试题答案的多样性。在计算机无纸化考试中,绝大多数题目的答案是客观固定的,但对于程序设计题,会出现一题多解的情况,因此,在设计计算机自动阅卷程序时应充分考虑此类问题,必要时可增加人工活动,力保阅卷准确。

5.C语言程序设计无纸化考试系统设计目标

C语言程序设计无纸化考试系统的目标是:建立一套功能设置齐全、操作简单方便、管理灵活规范、界面友好、运行稳定的考试系统。所以要做好以下几个方面:

(1)数据处理的完整性。考试系统能方便录入试题、编辑试题、生成试卷、登记成绩、试卷分析、网络在线考试等功能。

(2)实用性。考试系统要能同时支持在局域网或互联网中使用,并且同一试题在考试当中准许不同用户同时进行操作,即分配少数相同的试卷,从考试文件中导入试题,而且可以在局域网中使用,加快试题操作速度。为考试试题生成相应的文件,便于考试系统及时进行修改、保存。

(3)安全性。对于任何一个学校来说,考试都是非常严肃和认真的,所以考试系统需要有很强的安全保证机制,不但要保证考试系统中考试数据的机密性、认证性、完整性,而且要保证整个考试系统一定是可控的。

(4)操作界面友好。需要采用目前普遍的简易操作方法,使系统界面力求友好、易用,系统安装要求方便,维护简单。

6.C语言无纸化考试系统实现流程

(1)建设高标准的考试环境:例如组建局域网、连接互联网、安装考试系统。

(2)组建考试系统题库、导入考生信息:例如教师出题组建题库,导入全体考生信息到考生信息库。

(3)组织课程考试:考生均凭自己的准考证号登录到考试系统当中,并加以信息验证;在系统随机生成考试试题后,然后系统自动开始进行倒计时考试。

(4)考试系统交卷:在考生答题交卷结束时或时间结束时,考试系统会自动进行相应交卷处理,从而保证考试的公平、公正。

(5)试卷答题提交:学生交卷后,考生考试试题会全部自动提交到考试服务器。

(6)阅卷评分:考试系统最后完成对试卷的阅卷。

(7)系统维护等。

7.结语

篇5:谭浩强版C语言期末考试

目前的很多自动化评分系统仍采用的是按结果评分的策略。所谓按结果评分方法, 就是只对结果进行评判。程序运行结果与正确结果一模一样, 就按对来算分, 运行结果与正确结果不一模一样, 就按错来算分。但是学过C语言的人都知道, 这样来判分是有失公平的。经过大量的调查和深入的研究, 我们提出了修复编译评分、结果对比评分和关键代码对比评分相结合的C语言程序设计自动评分策略。

程序设计题的自动评分的整个过程包括:生成考生源程序文件、使用Turbo C (简称TC) 编译链接程序、程序运行及控制 (包括死循环处理) 、程序运行结果对比、修复编译评分、关键代码对比评分。

(1) 对考生的源程序进行编译、连接, 如果能正常运行并能产生结果文件, 则将其运行结果与标准答案进行对比。与标准答案文件内容完全相同, 则说明结果正确, 得满分。如果运行结果有一部分对比正确, 则按比例给分, 如果得分为极端分 (0) 分或分数太低, 则转入静态评阅, 进行代码对比评分。若程序不能编译通过, 无法运行产生结果文件, 则转入修复编译评分。

(2) 考生程序不能通过编译产生结果, 说明考生程序存在语法错误, 则转入修复编译过程继续处理。对考生源程序进行词法分析。扫描源程序, 对代码中的单词进行分析, 识别各个单词的类型, (常量、变量、关键字) 等, 并保存到一个Token链表;根据词法分析的结果, 再对考生程序进行语法分析, 找出其中的语法错误并进行修正。如果修改次数过多, 得分已经太低则转入静态评阅。如果修改后程序能正常运行并生成结果文件, 则进行结果对比评分, 并根据修改次数给予适当扣分。如果仍不能编译通过, 则转入静态评阅。

(3) 静态评阅。静态评阅就是读取考生源程序文件的关键字 (词、表达式或语句) 对考生程序进行检测, 根据检测出的关键字的条数判断程序的逻辑合理性, 给出相应的分值。

2 C语言程序设计题自动评阅的实现

2.1 生成源文件

根据用户需要及对需求分析的深入分析研究, 本系统的程序设计题考试方式采用与全国等级考试相同的方式。即由考生完成部分程序代码 (通常是一个关键性函数) 对于这种形式, 需要从数据库中读取程序的非考生填写部分的代码, 将其和考生答案拼合成一个完整的程序文件才能正确执行。

2.2 编译连接程序

2.2.1 编译环境的构建

将一个程序源文件编译成一个可执行文件, 除了正确组成源程序外, 还需构建编译的环境, 本系统的处理方法是通过MS Sql Server的扩展存储过程Xp_Cmd Shell调用Tc命令实现。

2.2.2 判断编译是否成功的方法

编译是否成功可通过判断是否生成了可执行文件名来确定, 跟据C程序的编译原理, 名为XX.c的源文件编译成功后会生成XX.obj文件和XX.exe的目标文件, 可通过判断编译之后是否有XX.exe文件来确定编译是否成功, 而判断文件是否存在可用Asp的Fso.File Exists方法。

2.3 程序的运行

运行程序必需要在考生源程序文件编译成功生成了可执行文件的前提下进行, 程序的运行所涉及到的问题也很多, 它包括程序的执行、死循环处理等。

2.3.1 执行程序

执行待评程序也是通过Ms SQL Server的扩展存储过程Xm_Cmd Shell调用程序实现, 同时, 通过>>重定向符将屏幕输出的内容重定向到输出文件中去。

2.3.2 死循环的处理

对于考生程序出现死循环的问题, 系统采用的双线程的方法来处理。一个线程执行考生程序, 别一个线程执行计时程序, 任何一个线程执行完毕就立刻退出程序, 对于计时线程的编写使用的是API函数Wait For Single Object

2.4 程序运行结果对比

将学生程序运行的结果与标准答案进行对比的方法是将考生答案从输出文件中读取出来存放到一个字符串中, 再从数据库中读出标准答案, 通过对比它们的相似度来获得得分结果。如果只是简单的将两个字符串逐个比较, 那么得出来比较结果是不科学的。例如标准答案是“1 2 3”而学生答案是“212 3”其第一个关键字错误但后两个是正确的, 但逐个比较的结果相似度却是0。对于这种情况, 系统处理的方法是用ASP的Split函数把学生答案拆开成多个关键词, 同时也把标准答案用同样的方法拆开, 这样再逐个进行比较就不会出现刚才的问题。同时, 考虑到学生程序自由度比较大, 如果学生输出答案不规范, 比如说标准答案仍是“1 2 3”而学生答案输出出现友好提示等附加内容, 例如“The answer is 1 2 3”虽然学生答案原则上是对的但却因为友好提示而得0分。

2.5 修复编译评分

一个考生的程序不能通过编译, 并不一定表示该考生的程序存在很大的错误, 其原因可能仅仅是漏掉了一个分号或者无意输错了一个字母。修复编译的目的, 不是试图纠正考生程序中的所有语法错误, 而是修复考生常出现的一些导致程序不能编译的小错误, 使之能编译运行, 然后给出一个合理分数。修复编译程序是一个专门设计的C语言编译器, 这个编译器编译的部分是标准C语言编译器的一个字集, 但是它具有一定修复考生程序常见错误并能生成一个新的较为正确的程序代码的能力。

2.6 关键代码对比评分

首先, 由编题的教师在题库数据库中实现存放好适量的正确关键代码 (语句、单词等) 评分时, 系统通过查找考生程序中这些关键代码的数量, 给出一个比较合理的分数。

C语言程序书写格式多种多样, 同一段程序可以用不同的风格书写, 程序中定义的变量名也随考生个人喜好有所不同, 而且书写时会出现有无空格之类的区别, 同样功能的程序编写方法千变万化, 直接使用字符匹配方法显然存在很大的不合理性。经过对C程序语法等特性的研究, 在自动评阅方法中采用正则表达式来表示一程序中的关键算法。例如实现1-10的整数求和程序段的通用句式可表示为:

int@VAR@;for (int@VAR@=1;@VAR@<=10;@VAR@++) @VAR@=@VAR@+@VAR@;这种形式可以表示上述程序的核心算法而且具有通用性。

3 结束语

基于上述C语言程序设计题自动评阅方法的C语言考试系统正在试用阶段, 现在我院已应用于实际教学和教学辅助网站。经过大量测试和使用, 程序设计题的自动评分可全部实现。对于正确的考生程序, 能100%的准确评分, 对于存在错误的考生程序, 评分结果接近人工评分标准, 准确率在90%左右, 避免了不合理极端分数的出现, 完全可以在实际考试中使用。此C语言程序设计题自动评阅方法, 也可应用各种将C语言列入考试科目的各类计算机考试, 如全国计算机等级考试二级、三级C语言上机, 省二级C语言考试和国家程序员考试等, 具有很好的应用和推广价值。

摘要:本文提出C语言在线自动评分考试系统的研究, 这样不仅在分类统计准确性和阅卷稳定性方面有很大的提高, 具有很好的实用价值和应用前景。

上一篇:十大网络用语下一篇:《太上感应篇》原文及讲解