一、操作题高频考点
(一) C程序设计基础
【考点1】 C程序结构特点
(1)一个C源程序有且仅有一个main函数,程序执行总是从main函数开始。
(2)函数体必须用花括号({})括起来。
(3)每个执行语句都必须以分号(;)结尾,预处理命令、函数头和花括号(})之后不加分号。
(4)区分大小写。
题型剖析:该知识常在修改题中考查,如句末缺少分号、括号不匹配、运算符或关键字书写错误等。做题前先运行程序,可以很快地找到语法错误。
【考点2】 常量与变量
1.整型数据
(1)整型常量:即整常数,包括十进制整数(如 123、-456、0)、八进制整数(以0开头,如0123,即(123)8)、十六进制整数(以0x开头,如0x123,即(123)16)。
(2)整型变量:可分为有符号基本整型([signed]int)、无符号基本整型(unsigned[int])、有符号短整型([signed] short[int])、无符号短整型(unsigned short[int])、有符号长整型([signed]long[int])、无符号长整型(unsigned long[int])。
2.实型数据
(1)实型常量:也称浮点型,有两种表示形式,十进制小数形式(如.123、123.、123.0)和指数形式(如123.456e3 表示123.456 × 103)。
(2)实型变量:可分为单精度型(float)、双精度型(doub-le)和长双精度型(long double)。
3.字符型数据
(1)字符常量:用单引号括起来的一个字符(如′a′、′+′、′\0′)。
(2)字符变量:用来存储单个字符。
(3)字符串常量:由一对双引号括起来的字符序列(如"hello"、"123456")。字符串常量占用的内存字节数等于字符串中字符数加1,最后一个字节存放字符“\0”(ASCII码值为0),即字符串结束标识。
4.变量的初始化
定义的变量在使用之前,需要赋给一个确定的初值,否则会出现冗余数据直接参与运算的情况。初始化有两种方法:(1)先定义后初始化(如int a;a=5;);(2)在定义时直接初始化(如int a=5;)。在遇到循环时,循环变量需要先定义,然后才能在循环结构中应用。
题型剖析:字符串和字符串结束标识(“\0”)是常考查的内容,在填空题和修改题中都时有出现,并且编程题中经常要对字符串进行操作,因此在编程题中出现的概率也很高。
常见的考查形式有两种。
(1)判断是否到达字符串的结尾,即判断当前字符是否为“\0”。
例如,要遍历字符串s,使用整型变量n存放下标,那么判断当前字符是否为“\0”,可表示为:while(s[n]!=′\0′){…}。
注:也可以使用指针实现,若指针p指向某一个字符,则为:while(*p!=′\0′){…}。
(2)对字符串操作结束后,添加“\0”。
例如,下标n为字符串中最后一个字符的下标,要添加结束标识,可以表示为:s[n++]=′\0′。
注:也可以用指针实现,若指针p指向最后一个字符,则为:*(p++)=′\0′。
【考点3】 运算符及表达式
(1)算术运算符:圆括号(())、求正(+)、求负(-)、乘(*)、除(/)、求余(%)、加(+)、减(-)。
(2)复合赋值运算符:+=、-=、*=、/ =和% =。
(3)自加自减运算符:i++表示i参加运算后再加1,++i表示i加1后参加运算,对于i--和--i同理。
(4)逻辑运算符:&& 逻辑与
‖ 逻辑或
! 逻辑非
优先级的大小是:!>&&>‖。
应用逻辑运算符可以组成复杂的逻辑关系表达式。判断一个量是否为真的依据是其值是否为0,若为0,则为假,否则为真。
题型剖析:这一部分知识常在编程题中考查。表达式的应用是否正确直接决定了一个算法是否有效。填空题和改错题中也经常要求根据上下文的算法来补全特定位置的一个表达式。
(1)应该强调的是部分运算符的优先级问题,如涉及逻辑关系表达式的语句,如果想表达两个或关系的与,应该严格地应用括号(exp1‖exp2)&&(exp3‖exp4),而 exp1‖exp2&&exp3‖exp4表示的是3个表达式的多元或关系。
(2)整数除法的问题,一个整数去除另外一个整数,那么得到的结果是一个整数,这个整数是结果的整数部分,小数部分会被忽略掉,而且不是按照四舍五入的规则。比如3/2结果是1.5,但是如果返回一个整数的时候,则结果是1。这类情况通常在比较长的综合计算表达式中会被忽视,造成整体运算的错误,所以在特定的时候需要注意整数除法。相应的解决方法是设置数据类型为浮点数。
(3)除法运算符(/)和求余运算符(%)的区别。典型题目是求得一个多位整数各个位上的数值。
例如,要得到三位数456的个位、十位和百位数值。
个位数:456% 10=6
十位数:456/10% 10=45% 10=5
百位数:456/100=4
(4)自加自减运算符的特点及区别。
f(i++):表示i在参与f运算之后自加1。
f(++i):表示i在参与f运算之前自加1。
(5)赋值号(=)与等号(==)的区别,容易在语句中由于疏忽而混淆。例如,if(a=5)是错误的,因为在条件语句中不可能出现赋值号。
【考点4】 强制类型转换
利用强制类型转换运算符,可以将一个表达式转换成所需类型,其一般形式如下:
(类型名)(表达式);
例如,(char)(x+y)表示将(x+y)的值强制转换为字符型。
题型剖析:该知识点常在填空题和修改题中出现,典型题目是求两个整数相除的值。
例如,“int i;double f;”,需要将整数i的倒数赋值给f,这里直接使用f=1/i是错误的,因为我们知道两个整数相除的结果也是一个整数,f中存放的是1 与i相除结果的整数部分。解决的方法有以下两种。
●强制类型转换,f=(double)1/i;
●在赋值运算中进行类型转换,将运算符左侧的整数变为浮点型数,f=1.0/i。
(二) C语言的基本结构
【考点5】 格式输入输出
1.printf()函数
printf()函数用于格式化输出数据,其语法格式如下:
printf(格式控制,输出列表);
其中,格式控制是用引号引起来的部分,它包括两种信息:格式转换说明和原样输出的字符。输出列表是需要输出的一些数据,可以是常量、变量或表达式。
printf("Hello World!!");
原样输出字符串Hello World!!
printf("% 5d",123);
输出□□123,即123前面还有两个空格,5表示格式输出长度。
printf("% 2d",123);
输出123,即如果格式长度不足,则按实际长度输出。
printf("% c",c);
输出字符型变量c,其中c一定被赋值过。
printf("% s","string");
输出字符串string。
printf("% f",a);
输出单精度数a。
printf("% 2.2",1.2);
输出□1.20,即前面有一个空格,小数点后有两位有效数字。
2.scanf()函数
scanf()函数用于格式化输入数据,其语法格式如下:
scanf(格式控制,地址列表);
其中,格式控制与printf()函数相同,只是没有位数的设置。
值得注意的是,格式化输入字符的时候,空格也会被当作一个字符输入,所以连续输入多个字符的时候,中间一定不能添加空格,例如:
#include<stdio.h>
void main(){
char a,b,c;
scanf("% c% c% c",&a,&b,&c);
/*容易忽略的地方是输入时的空格以及这里的取地址符*/
scanf("% c % c % c",&a,&b,&c);
}
可以看到,如果在格式控制中添加空格,那么连续输入字符的时候添加空格就是合法的。
3.putchar()函数
putchar()函数用于向终端输出一个字符,其语法格式如下:
putchar();
putchar('a');
/*将字符a输出在屏幕上*/
putchar(65);
/*将ASCII码值为65的字符输出在屏幕上*/
char a= 'c';putchar(a);
/*将字符型变量a的值输出在屏幕上*/
4.getchar()函数
getchar()函数用于从终端获得一个字符,其语法格式如下:
getchar();
题型剖析:输入输出是基本知识点,其他的功能往往通过输入输出来体现。考点主要有以下3个方面。
(1)格式控制,根据输出列表判断格式控制的形式。
(2)输出列表,根据题目要求输出不同的结果。
(3)地址列表,根据题目要求输入不同的数据。
该知识点通常会在填空题和修改题中出现。填空题中会要求根据格式控制、输出列表或地址列表的部分内容补充另外部分的内容,从而符合语法要求。而修改题则是要求判断格式控制、输出列表、地址列表之间的对应关系是否正确,如小数点后有效位数的保留情况,小数点之前整数位数预留情况,输入输出格式中空格的作用,等等。
另外,应用scanf()函数接收终端输入的时候,带入的待赋值变量参数一定要是加上取址符号&,以传值引用的方式调用,否则可能出现未初始化或者计算错误等问题。
【考点6】 条件与分支(if,switch)
1.if语句
if条件语句可以有两种形式:if(exp){}或者if(exp){}else{}。在嵌套结构中,else只与其前面最近的且未匹配的if匹配,或者,在嵌套结构中直接应用{}将if…else搭配关系表示清楚。
例如:
int a=0;
if(1)a=3;
if(0)a=4;
else a=5; 得到的答案是5。而下面的代码:
int a = 0;
if(1){
a=3;
if(0)a=4;
}
else a = 5; 得到的答案是3。
if语句的另外一种表达方法是三目运算符,即(exp1)?exp2:exp3;,等价于if(exp1)exp2;else exp3;,同样,三目表达式也可以嵌套。
2.switch语句
分支语句switch是支持多分支的选择语句,用来实现多分支选择结构。
格式:
switch(exp){
case constexp1:exp1;
case constexp2:exp2;
…
default:expn;
}
如果想在执行某条case语句后直接跳出分支判断,则在exp后面添加break语句即可。每个case的值应该不同,否则会出现冲突。
题型剖析:if语句作为条件判断必不可少的语句,考查广泛分布在填空题、修改题、编程题中,尤以编程题中居多。考查方式主要有如下几种。
(1)if语句的表达式。一般根据题目要求填入判断的条件,如if(______)。语句的表达式有很多种,可以是简单的算术表达式、逻辑表达式,也可以是带有指针、数组等变量的表达式。
(2)if语句体。根据题目要求填入判断后应执行的语句,如if(a == 0){______}。
(3)if的嵌套形式。应该注意if语句的配对,在填空题中可以考查根据嵌套形式写出结果,也可以在修改题中判断所应用的嵌套形式中某个条件是否正确,是否满足算法的判断要求。
switch语句的考查主要涉及填空题中语句的书写形式。一般根据题目要求填入表达式,如switch(______),或选择条件及执行语句,如case______:______;,或考查break语句。
【考点7】 循环
1.常用的循环语句
while(exp) {} /*当exp为真时,执行语句*/
do{}while(exp); /*先执行语句,然后判断 exp
是否为真,若为真,则继续执行*/
for(exp1;exp2;exp3){} /*应用exp1初始化,满足条件则执行exp2,变化为exp3*/
其中{}表示要执行的语句块。
循环是可以嵌套的,其实质是对应语句块的嵌套,也就是{}的配对。
考试中,循环的考查方式往往是给出一段程序,然后让考生填写循环表达式。循环表达式包括:循环变量的初始化,循环变量的取值范围及以循环的结束条件等。
2.跳出循环的语句(continue,break)
continue:表示跳过本次循环,而直接继续执行下一次循环。
break:表示跳出整个循环体,直接执行该循环的后继语句。
题型剖析:
1.while语句
(1)while语句中条件表达式的考查。一般根据题目要求填入循环条件,如while(______)。while与if语句的表达式一样有很多种,可以是简单的算术表达式、逻辑表达式,也可以是带有指针、数组等变量的表达式。
(2)while结构语句的考查,根据题目要求填入循环执行语句,如while(a>5&&a<10){______}。
2.do…while循环
(1)循环条件,即while语句表达式的考查,与while语句考查形式基本相同。
(2)循环体,根据题目要求填写,基本与while循环体语句的考查形式相同。但是要注意do…while循环是先执行循环体,再进行循环判断,而while循环是先进行循环判断,再执行循环体。
(3)与迭代算法一起考查,如求级数或者求阶乘。
3.for语句
(1)考查循环起始条件、继续条件、循环变量,如 for(______;______;______)。
(2)for语句执行语句部分的考查,根据题目要求写出循环执行语句,如for(i=0;i<100;i++){______;______}。
4.循环嵌套
(1)循环嵌套的形式:6种基本嵌套形式。
(2)for循环的嵌套、执行的过程,内循环的执行以及循环语句的结束条件。
(三) 函数
【考点8】 函数的定义、调用及参数传递
1.函数的定义
格式:类型标识符 函数名([形参列表]){
声明部分
语句部分
}
2.函数参数和返回值
函数的参数分为形式参数和实际参数。在定义函数时,函数名后面括号中的变量称为形式参数(简称形参);在主调函数中,函数名后面括号中的参数(可以是一个表达式)称为实际参数(简称实参)。形式参数与实际参数应该类型相同且个数相等。
函数的返回值是通过函数调用,使主调函数能得到一个确定的值。返回值的类型应与函数类型标识符相同。
3.函数的调用
格式:函数名(实参列表)
函数调用的方式有如下几种。
(1)函数语句,把函数调用作为一条语句,此时该函数不要求有返回值,只需要执行一定的操作。
(2)函数表达式,函数出现在一个表达式中,称为函数表达式。因为要参与表达式的计算,所以要求函数有对应数据类型的返回值。
(3)函数参数,函数调用作为一个函数的实参。
4.参数的传递
传递值:
函数名(实参列表)
传递引用:
函数名(& 参数,…)
它们的区别是:在值传递时,参数在函数执行过程中所产生的变化不被记录,即形式参数中值的变化不会影响实际参数的值,而在引用传递时则恰好相反。
题型剖析:
1.函数的定义
(1)函数类型的考查。要求根据主调函数的调用形式,写出被调用函数的类型标识符,例如:______fun(int a)。其类型可以是基本类型,也可以是用户自定义类型。要确定函数的类型,只需要确定函数应返回值的类型即可,如果函数不返回值,则为void型。
(2)参数类型的考查,要求根据实参类型填写被调用函数的形参类型,例如:int fun(int a,______c)。这里要记住,形参与实参一一对应。
2.函数的参数和返回值
(1)函数的形参和实参,该考点考查形式比较灵活,除了定义时的个数和类型要一一对应外,还要根据具体程序确定变量的名称。
(2)函数返回值,根据函数调用后要返回主调函数的值填写返回值变量名,例如:return 。
【考点9】 迭代算法和递归算法
迭代算法:使用计算机解决问题的一种基本方法,它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定的步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出一个新值。迭代算法常用来求方程的近似根。
递归算法:在调用一个函数的过程中直接或间接调用其函数本身的方法,称为函数的递归调用。最常用的递归调用有:求n!、遍历树等。
题型剖析:求n!、Fibonacci数列、递归输出回文等是递归算法的典型应用,在填空题、修改题、编程题中均有出现,具体考查形式不固定,多是对算法中关键步骤的考查。
例:求10!。
#include<stdio.h>
long fun(int n)
{ if(n>1) return(n*fun(n-1));
return 1;
}
main()
{printf("10!=% ld\n",fun(10));}
(四) 指针
【考点10】 指针变量的定义
一个变量的地址称为该变量的“指针”。如果有一个变量专门用来存放地址,那么这个变量就是指针变量,即存放变量地址的变量是指针变量。
指针的定义格式为:
基类型 * 指针变量名
例如:
float *a; /*a是指向float型变量的指针变量*/
char *b; /*b是指向char型变量的指针变量*/
变量的前面加上符号&(如&a),表示变量的地址,所以可以将&a赋值给一个指针。例如:
#include<stdio.h>void main(){
int a = 0;
int *i = &a;
}
注意:(1)虽然在定义时,用int *i定义了一个指向int类型变量的指针,但是该指针的变量名仍然是i;(2)定义指针时要在*前面声明指针的类型;(3)对指针赋值时,指针的类型应与其指向的值的类型一致;(4)对于*p=a来说,p和&a表示变量a的地址,*p和a表示变量a的值;(5)p++表示地址加1,(*p)++表示指针指向的数据加1。
题型剖析:指针是C语言的重要工具,也是考查的重点,其考查形式如下。
(1)指针变量的声明,特别要注意声明时的*号。
(2)指针变量的赋值,指针变量存储的是地址,因此在考试时要注意变量的值与地址的区别。
【考点11】 函数之间的地址传递
在函数一章已经讲述过,传递值不修改原参数的值,但是如果原参数是一个指针,就可以修改指针指向的内存地址中所存放的数据。例如:
#include<stdio.h>
void change(int *);
void main(){
int a = 0;
int *p = &a;
change(p);
printf("% d\n",a);
}
void change(int *p){
(*p)++;
}
输出结果为1。
题型剖析:函数之间的地址传递在填空题和修改题中均有出现,考查形式如下。
(1)根据函数的实参,确定指针形参的类型,例如:
int *p3,*p4;
swap(p3,p4);
void swap(int*p1,*p2)
/*实参与形参的类型要一致*/
(2)根据函数的形参,确定实参的变量名。
(五) 数组
【考点12】 一维数组
1.定义方法
格式:类型说明符 数组名[常量表达式];
其中,类型说明符是指数组元素的数据类型;常量表达式是一个整型值,指定数组元素的个数,即数组的长度,数组的长度必须用[]括起来;常量表达式可以是常量或符号常量,不能包含变量。
例如:int array[5];
/*定义了一个数组元素类型为整型、长度为5的数组*/
注意:数组的元素下标从0开始,即该数组元素分别为:a[0]、a[1]、a[2]、a[3]、a[4],这也是数组元素的访问方法。
2.一维数组的初始化
一般在定义的时候为数组赋值。
例如:int array[5]={0,1,2,3,4};
/*分别赋值0、1、2、3、4*/
int array[5]={0,1,2};
/*前面3个元素赋值0、1、2,后面两个元素默认为0*/
int array[5]={0};
/*给所有5个元素均赋值为0*/
int array[]={0,1,2,3,4};
/*定义并初始化了一个长度为5的整型数组*/
3.一维数组元素的输入输出
如果需要逐个输入或输出数组元素,可以使用循环语句实现,以int array[5]为例:
#include<stdio.h>
void main(){
int array[5],i;
for(i = 0;i < 5;i ++){ /*输入*/
scanf("% d",&array[i]);
}
for(i = 0;i < 5;i ++){ /*输出*/
printf("% d",array[i]);
}
}
输入:01234
输出:01234
注意:数组名a本身就是一个指向数组内存区域首地址的指针,其类型与数组元素类型相同,也就是说,数组元素a [i]可以写成*(a+i)。
题型剖析:一维数组的考查比较频繁,其考查形式如下。
(1)数组元素的引用,可以使用数组下标和指针两种形式实现,其中最常见的方法是使用数组下标。
例如,要引用整型数组a[5]的第3个元素,使用数组下标的方式为a[2],使用指针的方式为*(a+3)。
(2)数组的遍历,常使用循环语句实现,此时要注意数组的上下界。
例如,要遍历的数组a[5],则该数组的下界为0,上界为4,用程序实现为:
for(i=0;i<5;i++)
...
【考点13】 排序算法
1.冒泡排序算法
以升序为例,冒泡排序算法的基本思想是:将元素两两进行比较,把大数向后边移动,经过一轮比较,使最大的数移动到数组的最后一位;经过第二轮比较,使第二大的数移动到数组的倒数第二位;以此类推,最终得到一个升序序列。
排序过程如下。
(1)比较第一个数和第二个数,若为逆序a[0]>a[1],则交换;然后比较第二个数与第三个数;以此类推,直到第n-1个数和第n个数比较完成为止,完成第一轮冒泡排序,结果使最大的数放到了最后的位置。
(2)下面需要排序前n-1个元素,按照步骤(1),将这n-1个元素中最大的元素放到前面n-1 个元素的最后位置,也就是整体的倒数第二个位置。
(3)重复上述步骤,直到n-1轮排序过后,整体冒泡排序算法结束。
程序如下:
#include<stdio.h>
void main(){
int a[10],i,j,t;
printf("Input 10 numbers:\n");
for(i = 0;i < 10;i++){
/*由终端接收10个整数,一般情况下是无序的*/
scanf("% d",&a[i]);
}
printf("\n");
for(i= 0;i < 9;i++){
/*代表的是执行冒泡排序的次数,统一为从0开始*/
for(j = 0;j < 9-i;j++){
/*从0开始两两比较,不用比较已经确定位置的大数*/
if(a[j]>a[j+1]){
t = a[j];
a[j]= a[j+1];
a[j+1]= t;
}
}
}
for(i = 0;i < 10;i++){
printf("% d",a[i]);
}
}
2.选择排序算法
仍然以升序排序为例,选择排序算法的基本思想是:在第一轮进行排序时,从所有的元素中找到最小的元素,与第一个元素交换。在进行第二轮排序时,从剩下的n-1个元素中找到最小的元素,与第二个元素交换。以此类推,完成排序。
排序过程如下。
(1)首先通过n-1次比较,从n个数中找到最小的数,将它与第一个数交换,使最小的数被放到第一个元素的位置上。
(2)再通过n-2次比较,从剩余的n-1个数中找出次小的数,将它与第二个数交换,使次小的数被放到第二个元素的位置上。
(3)重复上述过程,经过n-1轮排序后,得到一个升序序列。
程序如下:
#include<stdio.h>void main(){
int a[10],i,j,k,x;
printf("Input 10 numbers:\n");
/*从终端接收10个整数*/
for(i = 0;i < 10;i++){
scanf("% d",&a[i]);
}
printf("\n");
for(i=0;i<9;i++){/*开始进行选择排序算法*/
k = i;
for(j = i+1;j < 10;j ++){
if(a[j]< a[k]){k=j;}
}
if(i!=k)
{ x = a[i];
a[i]= a[k];
a[k]= x;
}
}
printf("the sorted numbers:\n");
for(i=0;i<10;i++)
{printf("% d",a[i]);}
}
题型剖析:将这两个算法的完整代码写在这里,是为了强调这两个算法的基础性和重要性。排序是解决上机编程的重要工具,要学会灵活运用。应着重理解两重循环中内层循环和外层循环在算法中各自起到的作用,以及它们的联系和区别。
【考点14】 二维数组
1.定义方法
格式:类型说明符 数组名[常量表达式1][常量表达式2];
例如:int array[3][4]; /*定义了一个3*4 = 12个元素的数组,元素类型为整型*/
注意:(1)二维数组的定义不能写成 int array[3,4];(2)二维数组中元素的排列顺序是按行排列,即存放完第一行的元素之后接着存放第二行的元素,数组名array代表二维数组首地址,a[0]代表数组第0行的首地址,a[i]代表数组第i行的首地址;(3)允许定义多维数组。
2.二维数组的初始化
例如:int a[3][4]= {{0,1,2,3},{4,5,6,7},{8,9,10, 11}};
/*为3行数组元素分别赋值*/
int a[3][4]= {0,1,2,3,4,5,6,7,8,9,10,11};
/*为12个元素赋值*/
int a[3][4]= {{0},{4},{8}}
/*与一维数组一样,没有赋值的元素默认为0*/
int a[][4]= {0,1,2,3,4,5,6,7,8,9,10,11};
/*为全部元素赋值的时候可以省去第一个常量*/
3.二维数组的输入输出
如果需逐个输入或输出数组元素,则需要使用一个两层循环实现,以array[3][3]为例:
#include<stdio.h>void main(){
int array[3][3],i,j;
for(i=0;i<3;i++) /*输入*/
for(j=0;j<3;j++)
scanf("% d",&array[i][j]);
for(i=0;i<3;i++)/*输出*/
{for(j=0;j<3;j++)
printf("% d ",array[i][j]);
printf("\n");
}
}
输入:1 2 3 4 5 6 7 8 9
输出:1 2 3
4 5 6
7 8 9
题型剖析:
二维数组的考查形式如下。
(1)二维数组元素的引用多使用数组下标实现,常用于矩阵的运算。
例如,用二维数组a[3][3]存放三阶矩阵A,则该短阵的对角线元素为a[0][0]、a[1][1]、a[2][2]。
(2)二维数组的遍历,常使用嵌套循环语句实现,此时要注意内外两层循环分别表示的意义。
例如,要遍历二维数组a[3][3],用程序实现为:
for(i=0;i<3;i++) /*i表示行坐标*/
for(j=0;j<3;j++) /*j表示列坐标*/
(六) 字符串
【考点15】 字符串的表示
由于没有字符串变量,所以用一维字符数组表示字符串,其定义、初始化均与一般的数组相仿。
如果在声明字符数组的同时初始化数组,则可以不规定数组的长度,系统在存储字符串常量时,会在串尾自动加上一个结束标识“\0”。结束标识在字符数组中也要占用一个元素的存储空间,因此在声明字符数组的长度时,要预留出该字符的位置。
当然,还可以采用循环语句进行输入输出,程序如下:
#include<stdio.h>void main(){
char a[2];
scanf("% s",a);
/*或者用gets(a)进行输入操作*/
printf("% s\n",a);
/*或者用puts(a)进行输出操作*/
}
输入:ab
输出:ab
题型剖析:
字符串及其数组元素的引用在上机中的考查形式如下。
(1)字符与字符常量的表示形式及输出形式。字符常量用(‘’),输入输出时使用格式字符“%c”;字符串与字符串常量的表示形式及输出形式分别为(“”)和“%s”。
(2)字符串结束标识“\0”。根据“\0”来判断字符串是否结束,例如:
for(i =0;str[i]!=′\0′;i++)
【考点16】 指向字符串的指针
定义格式:
char * 指针变量
初始化方法:
char *p = "abc";
使用方法:
while(*p){}
注意:只有字符数组才可以应用数组名称直接将整个数组中的元素输出,其他类型的数组不具备这种特征。
题型剖析:
(1)填空题中,常常要求根据函数的调用,写出参数中字符串指针的正确形式,如:a、b是两个数组,对于函数void fun(char *a,char *b),其调用形式为fun(a,b)。
(2)使用指针对字符串进行操作。例如,字符串 s ="hello",指针p指向字符串s,要求将字符串中的字母l转换或字符a,程序如下:
while(p)
{ if(*p==′l′)
*p=′a′;
p++;
}
【考点17】 字符串处理函数
1.strcpy()字符串复制函数
例如:
char a[]="abc";
char b[]="b";
strcpy(a,b);/*调用结束后,a = b*/
C语言中不可以应用“=”直接将一个字符串的值复制给另外一个字符串,但可以用库函数中的 strcpy()函数来实现。
2.strcat()字符串连接函数
例如:
char a[]="abc";
char b[]="b";
strcat(a,b);/*调用结束后,a =abcb*/
3.strlen()字符串长度函数(从起始指针到\0处为止的字符总数)
例如:
char a[100]="abc";
int b = strlen(a);/*调用后b = 3*/
4.strcmp()字符串比较函数
例如:
char a[]="abc";
char b[]="b";
int c = strcmp(a,b);/*调用结束后,c = -1 */
即按字典顺序排列,靠后的字符串比较大。a<b,返回-1;a>b,返回1;a=b,返回0。
题型剖析:这里主要是牢记各个函数的功能和调用方法。利用字符串处理函数可以方便地对字符串进行处理。在上机过程中,熟练使用字符串处理函数(除非题目要求不能使用),可以大大减少我们的工作量。
(七) 结构体、共用体和用户定义类型
【考点18】 结构体变量的定义与表示方法
1.结构体的声明
struct 结构体名
{
类型标识符 成员名;
类型表示符 成员名;
…
}
2.结构体变量的声明
(1)可以直接跟在结构体声明之后,例如:
struct{
…
}array[10];
(2)先声明结构体类型,再单独定义,例如:
struct student{
…
};
struct student array[10];
(3)先声明一个结构体类型名,再用新类型名来定义变量,例如:
typedef struct{
…
}ST
ST array[10];
3.结构体变量的引用
格式:结构体变量名.成员名
可以将一个结构体的变量直接赋值给另外一个结构体变量,结构体嵌套时逐级引用。
题型剖析:考点主要是结构体的定义和结构体变量的几种声明形式,主要在填空题中考查,比如根据上下文补全结构体中的成员等。
【考点19】 链表
1.指针指向结构体的引用方法
例如,struct*p = a;则下面3种引用成员的方式是一致的。
a.b;
(*p).b;
p->b;
2.链表的组成
(1)头指针,存放第一个数据结点的地址。
(2)结点,包括数据域和指针域。
链表的结构可以用下图表示。
3.链表的操作
链表是一种重要的数据结构,可以动态地进行数据的存储分配。对链表的操作包括链表的建立、链表结点的插入和删除等。
(1)插入结点:比如要在结点a、b之间插入c,则需要将指针指向a,然后将“c->next = a->next;a->next = c;”,便得到“a->c->b;”。
(2)删除结点:比如在a、c、b这3个连续结点中删除c,则将指针指向a后,再将a->next = c->next。
总之,链表操作的原则是:保证操作顺利完成而且不至于让指针丢失。
题型剖析:
1.单个链表元素
相当于同时考查结构体和指针。
(1)结构体指针的定义,要注意先赋值再使用。
(2)结构体内的成员用指针的引用同直接用结构体变量名引用形式上的区别。结构体变量的指针及结构体变量指针引用结构体成员赋值,尤其要注意字符数组的赋值。
2.链表
多考查于填空题和修改题,主要是对链表的操作,往往还连带着前后元素的链接关系,所以需要特别注意指针指向的调整以及先后顺序。
【考点20】 命名类型
格式:typedef 定义体 新名称
例如:typedef int INT
之后便可以使用INT来定义一个int型的变量,如INT a=0与int a=0等价。
题型剖析:该知识一般在填空题中考查,只要理解了别名和原定义体实际上是同一个类型即可。
【考点21】 宏定义
1.不带参数的宏定义
格式:#define 宏名替换文本
例如:#define R 13
#define PI 3.14
2.带参数的宏定义
格式:#define 宏名(参数列表) 字符串
例如:#define MV(x,y)((x)*(y))
题型剖析:不带参数的宏替换比较简单,只需要将宏名替换成相应的常量即可。进行带参数的宏替换时要注意,程序不会将预定义字符串的运算结果进行替换,而是简单的字符替换,例如,#define MV(x,y)x*y与#define MV(x,y)(x)*(y)是不同的,当程序引用MV(a+3,5)时,该表达式被分别替换为:MV(a+3*5)和MV((a+3)*5)。
(八) 文件
【考点22】 文件的打开与关闭
1.文件的定义
文件存储在外部介质上数据的集合,是操作系统进行数据管理的基本单位。文件分为ASCII文件和二进制文件。C语言把文件看作是一个字符(字节)的序列,即由一个个字符(字节)的数据顺序组成。一个输入输出流就是一个字节流或二进制流。
2.文件的打开与关闭
文件类型指针:FILE *fp;
打开文件:fp = fopen(文件名,文件使用方式);
关闭文件:fclose(fp);
注意文件打开和关闭函数的形式,其参数和返回值为文件指针。文件打开时,自动生成一个文件结构体;关闭后,结构体自动释放。
文件的打开方式如下表所示。
题型剖析:这部分是概念知识,考查考生对知识、概念记忆的准确性,通常会以填空题和修改题的形式出现,如补全文件名称、文件使用方式、操作完成后文件是否被关闭等。
【考点23】 文件的读写
fpute(ch,fp);
功能:将字符(ch的值)输出到fp所指向的文件中。
fgetc(fp);
功能:从fp所指向的文件中返回一个字符。
fgets(char *str,int n,FILE *fp);
功能:从指定的文件读入一个字符串。
fputs(const str,FILE *fp);
功能:向指定的文件输出一个字符串。
fprintf(文件指针,格式字符串,输出表列);
功能:将字符串输出到文件。
fscanf(文件指针,格式字符串,输入表列);
功能:从文件读入一个字符串。
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
功能:数据块读/写函数,用于向文件读写一组数据,其中,buffer是一个指针,表示起始地址;size是要读/写的字节数;count表示要进行读/写多少个size字节的数据项。
题型剖析:这部分内容在考试中以概念考查为主,因此要熟练掌握这些函数的功能、调用格式以及参数的含义。
【考点24】 文件检测函数
int feof(FILE *stream);
功能:检测文件是否结束,如果结束,返回1,否则返回0。
ferror(*fp);
功能:返回0表示文件未出错,非零表示出错。
fseek(文件类型指针,位移量,起始点);
起始点有:
文件开头 SEEK_SET0
文件当前位置 SEEK_CUR1
文件结尾 SEEK_END2
题型剖析:重点考查feof()函数的调用格式和参数的含义,例如:
int a = 2;fseek(fp,0,a);