03二级C串讲Word文件下载.docx
《03二级C串讲Word文件下载.docx》由会员分享,可在线阅读,更多相关《03二级C串讲Word文件下载.docx(181页珍藏版)》请在冰豆网上搜索。
C语言程序设考试内容
一、C语言的结构
1.程序的构成,MAIN函数和其他函数。
2.头文件,数据说明,函数的开始和结束标志。
3.源程序的书写格式。
4.C语言的风格。
二、数据类型及其运算
1.C的数据类型(基本类型,构造类型,指针类型,空类型)及其定义方法。
2.C运算符的种类、运算优先级和结合性。
3.不同类型数据间的转换与运算。
4.C表达式类型(赋值表达式,算术表达式,关系表达式,逻辑表达式,条件表达式,逗号表达式)和求值规则。
三、基本语句
1.表达式语句,空语句,复合语句。
2.数据的输入与输出,输入输出函数的调用。
3.复合语句。
4.GOTO语句和语句标号的使用。
四、选择结构程序设计
1.用IF语句实现选择结构。
2.用SWITCH语句实现多分支选择结构。
3.选择结构的嵌套。
五、循环结构程序设计
1.FOR循环结构。
2.WHILE和DOWHILE循环结构。
3.CONTINUE语句和BREAK语句。
4.循环的嵌套。
六、数组的定义和引用
1.一维数组和多维数组的定义、初始化和引用
2.字符串与字符数组。
七、函数
1.库函数的正确调用。
2.函数的定义方法。
3.函数的类型和返回值。
4.形式参数与实在参数,参数值的传递。
5.函数的正确调用,嵌套调用,递归调用。
6.局部变量和全局变量。
7.变量的存储类别(自动,静态,寄存器,外部),变量的作用域和生存期。
8.内部函数与外部函数。
八、编译预处理
1.宏定义:
不带参数的宏定义;
带参数的宏定义。
2.“文件包含”处理。
九、指针
1.指针与指针变量的概念,指针与地址运算符。
2.变量、数组、字符串、函数、结构体的指针以及指向变量、数组、字符串、函数、结构体的指针变量。
通过指针引用以上各类型数据。
3.用指针作函数参数。
4.返回指针值的指针函数。
5.指针数组,指向指针的指针,MAIN函数的命令行参数。
十、结构体(即“结构”)与共用体(即“联合”)
1.结构体和共用体类型数据的定义方法和引用方法。
2.用指针和结构体构成链表,单向链表的建立、输出、删除与插入。
十一、位运算
1.位运算符的含义及使用。
2.简单的位运算。
十二、文件操作
只要求缓冲文件系统(即高级磁盘I/O系统),对非标准缓冲文件系统(即低级磁盘I/O系统)不要求。
1.文件类型指针(FILE类型指针)。
2.文件的打开与关闭(FOPEN,FCLOSE)。
3.文件的读写(FPUTC,FGETC,FPUTS,FGETS,FREAD,FWRITE,FPRINTF,FSCANF函数),文件的定位(REWIND,FSEEK函数)。
1.笔试:
120分钟,满分100分,其中含公共基础知识部分的30分。
2.上机:
60分钟,满分100分。
上机操作包括:
(1)填空;
(2)改错;
(3)编程。
第二部分公共基础知识和C语言基本知识的重点分析
重点难点知识讲解
C语言之指针、数组和函数
基本解释
1、指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址);
数组的本质则是一系列的变量。
2、数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。
3、当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
问题:
指针与数组
听说chara[]与char*a是一致的,是不是这样呢?
答案与分析:
指针和数组存在着一些本质的区别。
当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是一种比较特殊的情况而已,在本质上,两者是有区别的。
请看以下的例子:
chara[]="
Hi,pig!
"
;
char*p="
上述两个变量的内存布局分别如下:
数组a需要在内存中占用8个字节的空间,这段内存区通过名字a来标志。
指针p则需要4个字节的空间来存放地址,这4个字节用名字p来标志。
其中存放的地址几乎可以指向任何地方,也可以哪里都不指,即空指针。
目前这个p指向某地连续的8个字节,即字符串“Hi,pig!
”。
另外,例如:
对于a[2]和p[2],二者都返回字符‘i’,但是编译器产生的执行代码却不一样。
对于a[2],执行代码是从a的位置开始,向后移动2两个字节,然后取出其中的字符。
对于p[2],执行代码是从p的位置取出一个地址,在其上加2,然后取出对应内存中的字符。
数组指针
为什么在有些时候我们需要定义指向数组而不是指向数组元素的指针?
如何定义?
使用指针,目的是用来保存某个元素的地址,从而来利用指针独有的优点,那么在元素需要是数组的情况下,就理所当然要用到指向数组的指针,比如在高维需要动态生成情况下的多维数组。
定义例子如下:
int(*pElement)[2]。
下面是一个例子:
intarray[2][3]={{1,2,3},{4,5,6}};
int(*pa)[3];
//定义一个指向数组的指针
pa=&
array[0];
//'
&
'
符号能够体现pa的含义,表示是指向数组的指针
printf("
%d"
(*pa)[0]);
//将打印array[0][0],即1
pa++;
//猜一猜,它指向谁?
array[1]?
对了!
//将打印array[1][0],即4
上述这个例子充分说明了数组指针—一种指向整个数组的指针的定义和使用。
需要说明的是,按照我们在第四篇讨论过的,指针的步进是参照其所指对象的大小的,因此,pa++将整个向后移动一个数组的尺寸,而不是仅仅向后移动一个数组元素的尺寸。
指针数组
有如下定义:
structUT_TEST_STRUCT*pTo[2][MAX_NUM];
请分析这个定义的意义,并尝试说明这样的定义可能有哪些好处?
前面我们谈了数组指针,现在又提到了指针数组,两者形式很相似,那么,如何区分两者的定义呢?
分析如下:
数组指针是:
指向数组的指针,比如int(*pA)[5]。
指针数组是:
指针构成的数组,比如int*pA[5]。
至于上述指针数组的好处,大致有如下两个很普遍的原因:
a)、各个指针内容可以按需要动态生成,避免了空间浪费。
b)、各个指针呈数组形式排列,索引起来非常方便。
在实际编程中,选择使用指针数组大多都是想要获得如上两个好处。
问题:
指向指针的指针
在做一个文本处理程序的时候,有这样一个问题:
什么样的数据结构适合于按行存储文本?
首先,我们来分析文本的特点,文本的主要特征是具有很强的动态性,一行文本的字符个数或多或少不确定,整个文本所拥有的文本行数也是不确定的。
这样的特征决定了用固定的二维数组存放文本行必然限制多多,缺乏灵活性。
这种场合,使用指向指针的指针有很大的优越性。
现实中我们尝试用动态二维数组(本质就是指向指针的指针)来解决此问题:
图示是一个指针数组。
所谓动态性指横向(对应每行文本的字符个数)和纵向(对应整个文本的行数)两个方向都可以变化。
就横向而言,因为指针的灵活性,它可以指向随意大小的字符数组,实现了横向动态性。
就竖向而言,可以动态生成及扩展需要的指针数组的大小。
下面的代码演示了这种动态数组的用途:
//用于从文件中读取以'
\0'
结尾的字符串的函数
externchar*getline(FILE*pFile);
FILE*pFile;
char**ppText=NULL;
//二维动态数组指针
char*pCurrText=NULL;
//指向当前输入字符串的指针
ULONGulCurrLines=0;
ULONGulAllocedLines=0;
while(p=getline(pFile))
{
if(ulCurrLines>
=ulAllocedLines)
{
//*当前竖向空间已经不够了,通过realloc对其进行扩展。
ulAllocedLines+=50;
//每次扩展50行。
ppText=realloc(ppText,ulAllocedLines*(char*));
if(NULL==ppText)
{
return;
//内存分配失败,返回
}
}
ppText[ulCurrLines++]=p;
//横向“扩展”,指向不定长字符串
}
指针数组与数组指针与指向指针的指针
指针和数组分别有如下的特征:
指针:
动态分配,初始空间小
数组:
索引方便,初始空间大
下面使用高维数组来说明指针数组、数组指针、指向指针的指针各自的适合场合。
多维静态数组:
各维均确定,适用于整体空间需求不大的场合,此结构可方便索引,例a[10][40]。
数组指针:
低维确定,高维需要动态生成的场合,例a[x][40]。
指针数组:
高维确定,低维需要动态生成的场合,例a[10][y]。
指向指针的指针:
高、低维均需要动态生成的场合,例a[x][y]。
数组名相关问题
假设有一个整数数组a,a和&
a的区别是什么?
a==&
a==&
a[0],数组名a不占用存储空间。
需要引用数组(非字符串)首地址的地方,我一般使用&
a[0],使用a容易和指针混淆,使用&
a容易和非指针变量混淆。
区别在于二者的类型。
对数组a的直接引用将产生一个指向数组第一个元素的指针,而&
a的结果则产生一个指向全部数组的指针。
例如:
inta[2]={1,2};
int*p=0;
p=a;
/*p指向a[0]所在的地方*/
x=*p;
/*x=a[0]=1*/
p=&
a;
/*编译器会提示你错误,*/
/*显示整数指针与整数数组指针不一样*/
函数指针与指针函数
请问:
如下定义是什么意思:
int*pF1();
int(*pF2)();
首先清楚它们的定义:
指针函数,返回一个指针的函数。
函数指针,指向一个函数的指针。
可知:
pF1是一个指针函数,它返回一个指向int型数据的指针。
pF2是一个函数指针,它指向一个参数为空的函数,这个函数返回一个整数。
计算机二级C语言典型题解析
例题1
voidf(inta[],inti,intj)
{intt;
if(i<
j)
{t=a[i];
a[i]=a[j];
a[j]=t;
f(a,i+1,j-1);
main()
{inti,aa[5]={1,2,3,4,5};
f(aa,0,4);
for(i=0;
i<
5;
i++)printf("
%d,"
aa[i]);
printf("
\n"
);
执行后输出结果是
A)5,4,3,2,1,B)5,2,3,4,1,C)1,2,3,4,5,D)1,5,4,3,2,
答案:
A
解析:
f(aa,0,4)调用是地址双向传递.i=0,j=4,交换aa=[0]、aa[4]的值使
aa[5]={5,4,3,2,1};
接着递归调用f(a,i+1,j-1)即f(a,1,3),交换aa[1]、aa=[3]的值使aa[5]={5,4,3,2,1};
接着递归调用f(a,i+1,j-1)即f(a,2,2),由于i=j=2,退出函数调用,依次输出aa[5]的数组元素为"
5,4,3,2,1,"
例题2
structSTU
{charname[10];
intnum;
intScore;
};
{structSTUs[5]={{"
YangSan"
20041,703},{"
LiSiGuo"
20042,580},
{"
WangYin"
20043,680},{"
SunDan"
20044,550},
Penghua"
20045,537}},*p[5],*t;
inti,j;
i++)p[i]=&
s[i];
4;
i++)
for(j=i+1;
j<
j++)
if(p[i]->
Score>
p[j]->
Score)
{t=p[i];
p[i]=p[j];
p[j]=t;
%d%d\n"
s[1].Score,p[1]->
Score);
A)550550B)680680C)580550D)580680
C
本题算法类似于"
冒泡排序"
它是依次将p[0]、p[1]、p[2]、p[3]、p[4]分别指向s[5]中成员Score从低到高排列的数组单元,即537、550、580、680、703,而s[5]数组的值不变,因此,s[1].Score=580,p[1]->
Score=550.
有以下程序(提示:
程序中fseek(fp,-2L*sizeof(int),SEEK_END);
语句的作用是使位置指针从文件末尾向前移2*sizeof(int)字节)
#include<
stdio.h>
{FILE*fp;
inti,a[4]={1,2,3,4},b;
fp=fopen("
data.dat"
"
wb"
i<
i++)fwrite(&
a[i],sizeof(int),1,fp);
fclose(fp);
rb"
fseek(fp,-2L*sizeof(int),SEEK_END);
fread(&
b,sizeof(int),1,fp);
/*从文件中读取sizeof(int)字节的数据到变量b中*/
%d\n"
b);
A)2B)1C)4D)3
D
本程序先是建立一个二进制文件data.dat,并从数组a[4]中取出四个整型变量数据块写入该文件,从该文件中位置指针处开始取一个整型变量数据块给变量b即b=3.
第三部分典型和易错例题的分析
1)下面叙述正确的是________。
A)算法的执行效率与数据的存储结构无关
B)算法的空间复杂度是指算法程序中指令(或语句)的条数
C)算法的有穷性是指算法必须能在执行有限个步骤之后终止
D)算法的时间复杂度是指执行算法程序所需要的时间
(1)C
知识点:
算法的基本概念;
算法复杂度的概念和意义(时间复杂度与空间复杂度)
评析:
算法的设计可以避开具体的计算机程序设计语言,但算法的实现必须借助程序设计语言中提供的数据类型及其算法。
数据结构和算法是计算机科学的两个重要支柱。
它们是一个不可分割的整体。
算法在运行过程中需辅助存储空间的大小称为算法的空间复杂度。
算法的有穷性是指一个算法必须在执行有限的步骤以后结束。
算法的时间复杂度是指执行算法所需要的计算工作量,即算法执行过程中所需要的基本运算次数。
(2)以下数据结构属于非线性数据结构的是________。
A)队列B)线性表C)二叉树D)栈
(2)C
栈和队列的定义;
栈和队列的顺序存储结构及其基本运算
评析:
线性表、栈和队列等数据结构所表达和处理的数据以线性结构为组织形式。
栈是一种特殊的线性表,这种线性表只能在固定的一端进行插入和删除操作,允许插入和删除的一端称为栈顶,另一端称为栈底。
一个新元素只能从栈顶一端进入,删除时,只能删除栈顶的元素,即刚刚被插入的元素。
所以栈又称后进先出表(LastInFirstOut)。
队列可看作是插入在一端进行,删除在另一端进行的线性表,允许插入的一端称为队尾,允许删除的一端称为队头。
在队列中,只能删除队头元素,队列的最后一个元素一定是最新入队的元素。
因此队列又称先进先出表(FirstInFirstOut)。
二叉树的数据结构是树型结构,结构中数据元素之间存在着一对多的关系,因此它是一种非线性数据结构。
(3)在一棵二叉树上第8层的结点数最多是________。
A)8B)16C)128D)256
(3)C
知识点:
二叉树的定义及其存储结构
根据二叉树的性质:
二叉树第i(I>
1)层上至多有2i-1个结点。
得到第8层的结点数最多是128。
(4)下面描述中,不符合结构化程序设计风格的是________。
A)使用顺序、选择和重复(循环)三种基本控制结构表示程序的控制逻辑
B)自顶向下
C)注重提高程序的执行效率
D)限制使用goto语句
(4)C
结构化程序设计
结构化程序设计方法的四条原则是:
1.自顶向下:
2.逐步求精;
3.模块化;
4.限制使用goto语句。
“自顶向下”是说,程序设计时,应先考虑总体,后考虑细节,先考虑全局目标,后考虑局部目标;
“逐步求精’’是说,对复杂问题,应设计一些子目标作过渡,逐步细节化;
“模块化”是说,一个复杂问题肯定是由若干稍简单的问题构成,解决这个复杂问题的程序,也应对应若干稍简单的问题,分解成若干稍小的部分。
(5)下面概念中,不属于面向对象方法的是________。
A)对象、消息B)继承、多态C)类、封装D)过程调用
(5)D
面向对象的程序设计方法、对象、方法、属性及继承与多态性
面向对象方法是一种运用对象、类、封装、继承、多态和消息等概念来构造、测试、重构软件的方法。
面向对象方法从对象出发,发展出对象、类、消息、继承等概念。
(6)在结构化方法中,用数据流程图(DFD)作为描述工具的软件开发阶段是________。
A)可行性分析B)需求分析C)详细设计D)程序编码
(6)B
结构化设计方法
软件开发阶段包括需求分析、总体设计、详细设计、编码和测试五个阶段。
其中需求分析阶段常用的工具是数据流程图和数据字典。
(7)软件生命周期中所花费用最多的阶段是________。
A)详细设计B)软件编码C)软件测试D)软件维护
(7)D
软件工程基本概念,软件生命周期概念,软件工具与软件开发环境
软件生命周期分为软件定义、软件开发及软件运行维护3个阶段。
本题中详细设计、软件编码和软件测试都属于软件开发阶段;
维护是软件生命周期的最后一个阶段,也是持续时间最长,花费代价最大的一个阶段,软件工程学的一个目的就是提高软件的可维护性,降低维护的代价。
(8)数据库系统的核心是________。
A)数据模型B)DBMSC)软件工具D)数据库
(8)B
数据库的基本概念:
数据库,数据库管理系统,数据库系统
数据库管理系统DBMS是数据库系统的核心。
DBMS是负责数据库的建立、使用和维护的软件。
DBMS建立在操作系统之上,实施对数据库的统一管理和控制。
用户使用的各种数据库命令以及应用程序的执行,最终都必须通过DBMS。
另外,DBMS还承担着数据库的安全保护工作,按照DBA所规定的要求,保证数据库的完整性和安全性。
(9)下列叙述中正确的是________。
A)数据处理是将信息转化为数据的过程
B)数据库设计是指设计数据库管理系统
C)如果一个关系中的属性或属性组并非该关系的关键字,但它是另一个关系的关键
字,则称其为本关系的外关键字
D)关系中的每列称为元组,一个元组就是一个字段
(9)C
数据模型,实体联系模型及E-R图,从E-R图导出关系数据模型
数据处理是指将数据转换成信息的过程,故选项A叙述错误;
设计数据库的目的实质上是设计出满足实际应用需求的实际关系模型,故选项B叙述错误;
关系中的行称为元组,对应存储文件中的记录,关系中的列称为属性。
对应存储文件中的字段,故D选项叙述错误