谁有计算机二级考试资料书?关于C语言的

当前位置: >>
全国计算机等级考试二级C语言考前复习资料(真的非常全的笔试资料)
全国计算机等级考试 二级 C 语言考前复习资料(笔试)思维导图 1:C 语言程序设计知识结构第 1 页 共 78 页 第一课 C 语言程序设计基础思维导图 2:第一课 C 语言程序设计基础第 2 页 共 78 页 本课主要知识点: 高级语言编写的程序。 翻译的方式有两种,一个是编译,一 1.知识点:C 程序基础 ? C 语言是一种结构化程序设计语言。三种基本结构:顺序、 个是解释。C 语言程序仅可以编译。 选择、循环。 例 3: ()以下叙述中错误的是( D) 例 1: ()以下关于结构化程序设计的叙述中正确的 A)C 语言的可执行程序是由一系列机器指令构成的 是(C) A) 一个结构化程序必须同时由顺序、分支、循环三种结构 B)用 C 语言编写的源程序不能直接在计算机上运行 组成 B) 结构化程序使用 goto 语句会很便捷 C)通过编译得到的二进制目标程序需要连接才可以运行 C) 在 C 语言中,程序的模块化是利用函数实现的 D)在没有安装 C 语言集成开发环境的机器上不能运行 C 源程 D) 由三种基本结构构成的程序只能解决小规模的问题 例 2: ()计算机高级语言程序的运行方法有编译执 序生成的.exe 文件 行和解释执行两种,以下叙述中正确的是(A) A)C 语言程序仅可以编译执行 B)C 语言程序仅可以解释执行 【解析】C 程序开发过程:编辑―&(.c)编译―&(.obj)链 接―&可执行文件(.exe)2.知识点:C 语言程序的构成 ? C 程序是由函数构成的,一个 C 程序有且仅有一个 C)C 语言程序既可以编译执行又可以解释执行 main 函数。一个函数由两部分组成:函数的首部和函数体。 函数体包括声明部分和执行部分。 一个 C 程序总是从 main 函 D)以上说法都不对 数开始执行(即程序的入口) ,由 main 函数结束, (即程序的 【解析】计算机不能直接理解高级语言,只能直接理解机器语 出口) 。 例 1: ()以下叙述正确的是(B) 言,所以必须要把高级语言翻译成机器语言,计算机才能执行 A) C 语言程序是由过程和函数组成的第 3 页 共 78 页 B) C 语言函数可以嵌套调用,例如:fun(fun(x)) C) C 语言函数不可以单独编译 D) C 语言中除了 main 函数,其他函数不可作为单独文件 形式存在 例 2: ()以下叙述中错误的是 (C) A.C 语言编写的函数源程序,其文件名后缀可以是 C B.C 语言编写的函数都可以作为一个独立的源程序文件②预定义标识符 (有特殊含义,可以改变)③用户自定义的标识符 字,见名知意格式合法,不能使用关键例 1: ()以下 C 语言用户标识符中,不合法的是 (D) C.C 语言编写的每个函数都可以进行独立的编译并执行 A)_1 B)AaBc C)a_b D.一个 C 语言程序只能有一个主函数 D)a-b 3.知识点:标识符 4.知识点:数据类型 ? 命名规则: 例 1: ()以下关于 C 语言数据类型使用的叙述中 ①标识符中只能包含字母 (a-z,A-Z), 数字(0-9),下划线(_)。 错误的是(D) A)若要准确无误差的表示自然数,应使用整数类型 ②第一个字符必须是字母或下划线。 B)若要保存带有多位小数的数据,应使用双精度类型 C)若要处理如“人员信息”等含有不同类型的相关数据,应自 类型说明符:int,float,double 等 ? 分类 定义结构体类型 ①关键字(32 个) 语句定义符:if,for,while 等 D)若只处理“真”和“假”两种逻辑值,应使用逻辑类型 都 是 【解析】 结构数据类型是根据已定义的一个或多个数据类型用 (有固定含义,不可改变) 小 构造的方法来定义的,一个结构类型的值可以分解成若干个 写 “成员”或“元素” ,每个“成员”都是一个基本数据类型或 库函数的名字:printf , scanf 等 又是一个构造类型,C 项正确。C 语言没有逻辑类型,故 D 项编译预处理命令名:include 等第 4 页 共 78 页 错误。 例 2: ()定义无符号整数类为 UInt,下面可以作为A.所谓常量,是指在程序运行过程中,其值不能被改变的量B.常量分为整型常量、实型常量、字符常量和字符串常量 类 UInt 实例化值的是(B) C.常量可分为数值型常量和非数值型常量 D.经常被使用的变量可定义成常量 A)-369 B)369 C)0.369 D) 整 数 集 合 【解析】根据常量的基本概念,则不难判断 A、B、C 均正确。 {1,2,3,4,5} 例 1: ()以下选项中,能用作数据常量的是(D) A)o115 B)0118 C)1.5e1.5 D)115L 【解析】无符号整数类型为只有正整数和 0,所有选择 B。 【解析】八进制整常数以 0 开头,A 项错误;八进制整常数的 5.知识点:常量 数码味 0-7,B 项错误;实型常量的指数形式 E 后必为整数, ? 整型常量 故 C 项错误;长整型数后缀为 L 或 l,故 D 项正确。 十进制整常数:没有前缀,其数码为 0-9。例如 65535,-568 例 2: ()以下选项中可用作 C 程序合法实数的是 八进制整常数:以 0 开头,其数码为 0-7。例如 015 十六进制整常数: 以 0X 或 0x 开头, 其数码为 0-9, A-F 或 a-f。 ( A) 例如 0x2A A).1e0 B)3.0e0.2 C)E9 D)9.12E 长整型数:整型常数后缀为 L 或 l。例如 358000L 无符号数:整型常数后缀为 U 或 u。例如 158u 【解析】实型指数表示方式“E 前 E 后比有数,E 后必须是整 ? 实型常量的形式 ,故选 A 小数形式:必须有小数点,小数点前后不能同时没有数字。 数” 指数形式:aEn(其中 a 表示十进制数,E 阶码标志,n 阶码) 。 ? 字符常量:用单引号‘’括起来的一个字符。包括普通字 E 前 E 后必须有数字, E 后必为整数, 可以带符号。 例如 2.1E-3、 符常量和转义字符。 5E8 普通字符常量:如‘a’ 、 ‘A’ 、 ‘1’ 。 例 1: ()以下选项中关于 C 语言常量的叙述错误的 转义字符:由一对单引号引起来的以\开头的若干字符的组合。 是: (D) 如‘\n’表示回车换行、 ‘\\’表示反斜线符、 ‘\?’表示单引号第 5 页 共 78 页 符、 ‘\”’表示双引号、 ‘\ddd’表示八进制数、 ‘\xhh’表示十 以考试标准 Viusal c++6.0 为例,说明各类型变量所占的位数。 六进制数。 所占 所占 所占 所占 例 3: ()以下选项中能表示合法常量的是(C) 类型 字节 类型 字节 位数 位数 A)整数:1,200 B)实数:1.5E2.0 C)字符斜杠: ‘\\’ 数 数 D)字符串: “\007” short 16 2 unsigned 32 4 【解析】表示整常量不能用逗号分隔,A 项错误;实型常量的 int 指数形式 E 后必为整数,故 B 项错误;?\007?是转义字符,只 int 32 4 unsigned 32 4 能用单引号括起来,不能用双引号或其他括号,故 D 项错误。 long 例 4: () 以下选项中不能用作 C 程序合法常量的是 long 32 4 float 32 4 ( B) unsigned 16 2 double 64 8 short A)1,234 B)'\123' C)123 例 1: ()有以下程序 D)&\x7G& #include &stdio.h& 【解析】 A 中的 ‘, ’ 在编译时会出错的, 直接写成 1234 即可, main(0) {int s,t,A=100;double B=6; B 是一个三位八进制数代表的字符,C 是一个数字常量,D 是 s=sizeof(A); t=sizeof(B); 一个字符串,其中\x7 是一个一位十六进制数代表的字符,也 printf(“%d,%d\n”,s,t); } 即 D 中的字符串是两个字符, 如果 sizeof 的话是 3, 如果 strlen 在 VC6 平台上编译运行,程序运行后的输出结果是(C) A)2,4 B)4,4 C)4,8 D)10,6 的话是 2。 【解析】在 VC6 平台上,int 型占 4 个字节,double 型占 8 个 6.知识点:变量 字节,故答案是 C。 ? 整型变量和实型变量 ? 字符变量:一个字符变量只能存放一个字符。字符串不能第 6 页 共 78 页 存放在字符变量中,只能用字符数组或指针存放字符串。 定值 例 1: ()有以下定义语句,编译时会出现编译错误 【解析】?A?的 ASCII 码值为 65,?8?的 ASCII 码值为 56,?4? 的是(C) 的 ASCII 码值为 52,65+56-52=69, 对应于字符?E?。 ?5?的 ASCII A)char a=?a?; B)char a=‘\n’ ; C)char a=‘aa’ ; 码值为 53,65+56-53=68,对应于字符?D?。字符变量 c1 以%c D)char a=‘\x2d’ ; 格式输出,即?E?。字符变量 c2 以%d 格式输出,即 68。故答 【解析】一个字符变量只能存放一个字符,A 项字符变量存放 案是 A。 的是普通字符常量;B、D 项字符变量存放的转义字符;字符 8.知识点:进制转换 常量只能是单个字符,不能是字符串,?aa?不是单个字符,故 ? 十进制转换成二进制、八进制、十六进制:将十进制的数 C 项错误。 字除以 2(8、16) ,得到的商数继续除以 2,直到商为 0,然 7.知识点:ASCII 码 后将各次相除所得的余数从后往前排列。 ? ?0?的 ASCII 码值为 48; ?A?的 ASCII 码值为 65; ?a?的 ASCII ? 二进制、八进制、十六进制转换成十进制:将二(八、十 码值为 97。 六)进制数的每一位数从高位到低位乘以 2 的 n-1 次幂,n 为 ? 大写字母与小写字母的 ASCII 码值相差 32。 该位所在的位数。 例 1: ()有以下程序 ? 二进制与八进制之间的转换:每个八进制数字转换成 3 位 #include &stdio.h& 二进制数字。 main() ? 二进制与十六进制之间的转换:每个十六进制数字转换成 {char c1,c2; 4 位二进制数字。 c1=?A?+?8?-?4?; 例 1: (2010-09) 以下程序运行后的输出结果是 2008 。 c2=?A?+?8?-?5?; #include &stdio.h& printf(“%c,%d\n”,c1,c2); main() } {int a=200,b=010; 已知字母 A 的 ASCII 码为 65,程序运行后的输出结果是(A) printf( “%d%d\n”,a,b) ; A)E,68 B)D,69 C)E,D D) 输出无 }第 7 页 共 78 页 【解析】八进制数 010 转换成十进制数为 8,按“%d%d”格 式分别输出 a、b,即 2008。 9.知识点:运算符的优先级 级别由大到小:(逻辑)非 &算(术运算符) &关(系运算符) &(逻辑) 与 &(逻辑)或 &条(件运算符) &赋(值运算符) 10.知识点:强制类型转换运算符 ? 一般形式: (类型说明符) (表达式) ? 功能:把表达式的运算结果强制转换成类型说明符所表示 的类型 例 1: ()表达式(int)((double)(5/2)+2.5)的值是 4。 【解析】(int)((double)(5/2)+2.5)→(int)((double)2)+2.5)→ (int)(2..5)→(int)(4.500000) →4。 例 2:以下程序运行后的输出结果是 () 。 main() { a=(int)((double)(3/2)+0.5+(int)1.99*2); printf(&%d\n&,a); } 答案:3第 8 页【解析】(3/2)=1,(double)(3/2)+0.5=1.5,(int)1.99*2=2,所以 (double)(3/2)+0.5+(int)1.99*2=3.5,故 a=3。 11.知识点:算术运算符: +、―、*、/、% %:参与运算的量均为整型。 /:当除号左右两边都是整数的时候,商也要是整数,如果不 是整数则舍弃小数部分。当参与运算量有一个为实型,则商为 double 型。 例 1: ()若有定义语句:int a=10;double b=3.14;, 则表达式‘A’+a+b 值得类型是 (C) A.char B.int C.double D.float 【解析】各种类型数据混合运算时,最终结果的类型可依据以 下转换规律: char -& short -& int -& long -& float -& double 例 1: ()如有定义语句:int x=12,y=8,z;,在其后执 行语句 z=0.9+x/y,则 z 的值为 (B) A.1.9 B.1 C.2 D.2.4 【解析】 x,y,z 均为整型变量, 因此 x/y 结果为 1, 即 z=0.9+1=1.9, z 最终结果为 1 例 1: ()有以下定义:int a;long b;double x,y; 则以下选项中正确的表达式是(A) A)a%(int)(x-y) B)a=x!=y ; C) (a*y)%b D)y=x+y=x共 78 页 【解析】参与%运算的左右操作数均为整型,故 A 项正确,C 项错误。B 项是赋值语句,不是表达式。赋值运算符左边必须 是变量,而不是表达式,而 D 项中 x+y=x,错误。 12.知识点:逗号表达式 ? 一般形式:表达式 1,表达式 2??表达式 n ? 求值过程:自左向右依次求解,最后一个表达式的值为整 个逗号表达式的值。 例 1: ()设有定义:int x=2;以下表达式中,值 不为 6 的是(D) A)x*=x+1 B)x++,2*x C)x*=(1+x) D)2*x,x+=2 【解析】A 项 x=x*(x+1)=2*(2+1)=6;B 项 x++后,x 的值为 3,2*x 的 值 为 6 , 整 个 逗 号 表 达 式 的 值 为 6 ; C 项 x=x*(1+x)=2*3=6;D 项 x=x+2=2+2=4,整个逗号表达式的值 为 4。故答案是 D。 13.知识点:自增自减运算符 ++i i 自加 1 后再参与运算 i++ i 参与运算后再自加 1 --i i 自减 1 后再参与运算 i-i 参与运算后再自减 1 ++和- -的运算对象只能为变量,不能是常量或表达式。 例 1: ()若有定义语句:int a=5;则表达式:a++ 的值是 5 。第 9 页【解析】表达式 a++的值是 a 未加 1 之前的值,即 5。. ? 当++或―与 printf 语句结合时,若++/--x 的形式,则先自 增/自减,然后输出;若 x++/--的形式,则先输出 x 原值, 在进行自增/自减操作。 例 2: ()有以下程序 #include main() { int x=011; printf(&%d\n&,++x); } 程序运行后的输出结果是(C) A)12 B)11 C)10 D)9【解析】011 是一个八进制的数,转为十进制则为 1*8+1=9; ++x 是 x 先自增 1 再参与其他运算,所以先 x 自增 1 为 10 再 输出即为 10,故选 C。共 78 页 14.知识点:赋值表达式 a=a+0=0+0=0。故答案是 D。 ? 一般形式:变量名=表达式 15.知识点:位运算 ? 赋值运算符左边必须是变量,而不是表达式。 ? 按位与运算& 例 1: ()若有定义:double a=22;int i=0,k=18; 规则:0&0=0 0&1=0 1&0=0 1&1=1 则不符合 C 语言规定的赋值语句是( C) ? 按位或运算| A)a=a++ , i++ ; B)i= ( a+k ) &=(i+k) ; C)i=a%11 ; 规则:0|0=0 0|1=1 1|0=1 1|1=1 D)i=!a; ? 按位异或运算∧ 【解析】a 为 double 型,参与%运算的操作数均为整型,故 C 规则:0∧0=0 0∧1=1 1∧0=1 1∧1=0 项错误。 ? 求反运算~ ~1=0 例 2: ()若有定义语句:int a=3,b=2,c=1;,以下选 规则:~0=1 ? 左移运算&& 项中错误的赋值表达式是(A) 规则:把&&左边的运算数的各二进位全部左移若干位,高位丢 0。左移一位相当于该数乘以 2。左移 n 位相当于 A)a=(b=4)=3; B)a=b=c+1; C)a=(b=4)+c; 弃,低位补 n 该数乘以 2 。 D)a=1+(b=c=4); 例 1: ()有以下程序 #include &stdio.h& 【解析】赋值表达式的左边必须是变量不能是表达式。而答案 main() {short c=124; A 中, (b=4)是一个赋值表达式。 c=c____D____; ? 复合赋值运算符和表达式 printf(“%d\n”,c); +=、―=、*=、/=、%=、&&=、&&=、 &=、 ^=、 |= } 例 2: ()表达式 a+=a-=a=9 的值是(D) 若要使程序的运行结果为 248,应在下划线处填入的是 A)9 B)-9 C)18 D)0 A)&&2 B)|248 C)&0248 【解析】赋值运算符的结合性是从右到左, a=9→a=a-9=0 →第 10 页 共 78 页 D)&&1 于 4,故答案是 C。 【解析】左移一位相当于该数乘以 2,124&&1 相当于 124 乘以 16.知识点:关系运算符和表达式 2,等于 248。故答案是 D。 例 1: ()在 C 语言中,当表达式值为 0 时表示逻辑 例 2: ()有以下程序 值“假” ,当表达式值为 #include &stdio.h& 非0 时表示逻辑值“真” 。 main() 例 2: ()设 x 为 int 型变量,请写出一个关系表达 {int a=5,b=1,t; 式 (x%3==0)&&(x%7==0) ,用以判断 x 同时为 3 和 t=(a&&2)|b; 7 的倍数时,关系表达式的值为真。 printf(“%d\n”,t); 17.知识点:逻辑运算符和表达式 } ? 逻辑运算符优先级从高到低: ! 、&&、|| 程序运行后的输出结果是(A) ? 逻辑运算的真值表 A)21 B)11 C)6 D)1 a b a&&b a||b !a 2 【解析】左移 2 位相当于该数乘以 2 。5&&2 相当于 5 乘以 4 真 真 真 真 假 等于 20。20|1=21。故答案是 A。 真 假 假 真 假 ? 右移运算&& 假 真 假 真 真 把&&左边的运算数的各二进位全部右移若干位。高位补 0,低 假 假 假 假 真 n 位丢弃。 右移一位相当于该数除以 2。 右移 n 位相当于除以 2 。 ? 进行逻辑运算时,若&&左边的值为 0,则不再对右边的运 例 3: ()若有以下程序段 算对象进行运算,整个表达式的值为 0。 int r=8; 例 1: ()若有定义语句:int k1=10,k2=20;,执行表 printf(“%d\n”,r&&1); 达式 (k1=k1&k2) &&(k2=k2&k1)后, k1 和 k2 的值分别为(B) 输出结果是(C) A. 0 和 1 B.0 和 20 C.10 和 1 D. 10 和 20 A)16 B)8 C)4 D)2 【解析】k1&k2 为假,因此 k1= k1&k2 结果 0,逻辑与左边表 【解析】右移一位相当于该数除以 2。8&&1 相当于除以 2,等 达式为假,右边表达式不再处理,因此 k1 结果为 0,k2 不变,第 11 页 共 78 页 仍为 20 例 2:int a=2;则表达式(!a==1)&&(a++==2)的值为 0,a 的值 为 2。 【解析】 !a 为 0, !a==1 的值为 0,&&左边的值为 0,则不再 对右边的运算对象进行运算,所以 a 的值为 2。 ? 若||左边的运算对象的值为 1,则不再对右边的运算对象进 行运算,整个表达式的值为 1。 例 2: () 若 a 是数值类型, 则逻辑表达式(a==1)||(a!=1) 的值是(A) A)1 B)0 C)2 D)不知道 a 的值, 不 能确定 【解析】a 的值有两种情况:a 等于 1 或 a 不等于 1。故逻辑表 达式(a==1)||(a!=1)的值为 1。 18.知识点:格式输入函数 printf() (1)一般形式:printf(“格式控制字符串”,输出列表); (2)遇到控制字符,按照控制字符的规定输出,遇到非格式字 符串按原样输出。 例 1: ()若变量 x,y 已定义为 int 类型且 x 的值为 99,y 的值为 9,请将输出语句 printf(“ x/y=%d ”,x/y);补 充完整,使其输出的计算结果形式为:x/y=11。 例 2 : (
) 程 序 段 : int x=12;double y=3.141593;printf(“%d%8.6f”,x,y);的输出结果是(A) A)123.141593 B)12 3.141593 C)12,3.141593第 12 页D)123.1415930 【解析】以%8.6f 格式输出,即输出的总宽度为 8,小数的位 数为 6。 19.知识点:格式输入函数 scanf() (1)一般形式:scanf(“格式控制字符串”,地址列表); (2)若格式控制字符串中有非格式字符串,则按原样输入。 若格式控制字符串中没有非格式字符作输入数据之间的间隔, 则可用空格、Tab、回车作间隔。 例 1 : () 若 有 定 义 : int a,b;, 通 过 语 句 scanf(“%d;%d”,&a,&b);,能把整数 3 赋给变量 a,5 付给变量 b 的输入数据是 A.3 5 B.3,5 C.3;5 D.35 【解析】scanf 格式字符串中两个%d 之间带有非格式字符分 号,运行时应原样输入。 例 1:()有以下程序 main() {int m,n,p; scanf(“m=%dn=%dp=%d”,&m,&n,&p); printf(“%d%d%d\n”,m,n,p); }若想从键盘上输入数据,使变量 m 中的值为 123,n 中的值 为 456,p 中的值为 789,则正确的输入是(A) A)m=123n=456p=789 B)m=123 n=456 p=789共 78 页 C)m=123,n=456,p=789 D)123 456 789 例 3: ()有以下程序 【解析】scanf(“m=%dn=%dp=%d”,&m,&n,&p); 格式控制字符 #include &stdio.h& 串中有非格式字符串,则按原样输入,故答案是 A。 main() {int a1,a2; char c1,c2; 例 2:()有以下程序段 scanf(“%d%c%d%c”,&a1,&c1,&a2,&c2); char name[20]; printf(“%d,%c,%d,%c”,a1,c1,a2,c2); }若想通过键盘输入,使得 a1 的值为 12,a2 的值为 34,c1 的 值为字符 a,c2 的值为字符 b,程序输出结果是:12,a,34, scanf(&name=%s num=%d&,&num); b 则正确的输入格式是(以下_代表空格,&CR&代表回车) A)12a34b&CR& B)12_a_34_b&CR& C)12,a,34,b&CR& 当执行上述程序,并从键盘输入:name=Lili num=1001&回车& D)12_a34_b&CR& 【解析】空格会被当作字符赋值给变量,故 B、D 错误;C 项 后,name 的值(A) 中逗号会被当作字符赋值给变量,故 C 项错误。 A)Lili B)name=Lili C)Lili num= D)name=Lili (4)格式字符串 ? 一般形式:%[*][输入数据宽度][长度]类型 num=1001 ? *表示该输入项,读入后不赋予相应的变量。 【解析】scanf 中格式字符串的非格式字符串原样输入,如其 ? 输入数据宽度:用十进制数指定输入的字符数。 ()有以下程序 中的‘name=’和‘num=’ ,所以接受到的 name 值是后面的 例 4: #include &stdio.h& Lili,num 值为 1001。故选 A。 main() (3)在输入字符数据时,若格式控制字符串中无非格式字符, {int x,y; 则认为所有输入的字符均为有效字符。 空格会被当作字符赋值 scanf(“%2d%ld”,&x,&y); printf(“%d\n”x+y); } 程 序 运 行 时 输 入 : 1234567 程 序 的 运 行 结 果 是 给变量。第 13 页 共 78 页 34579 。 }若程序运行时从键盘输入 48&回车&,则输出结果为 (09) 。 【解析】 %2d 输入的数据宽度为 2, x 的值为 12, y 的值为 34567, 【解析】输入 48,则 c1=48,c2=48+9,以字符输出 c1 和 c2, x+y=34579。 则为输出 ASCII 码为 48 和 57 对应的字符,分别为 0 和 9。 例 5: ()若有定义语句:double x,y,*px,*py;执行 20.知识点:字符输出函数 putchar() 了 px=&x;py=&y;之后,正确的输入语句是(C) 一般形式:putchar(?a?);putchar(?\101?); A) scanf(“%f%f”,x,y); 21.知识点:字符输入函数 getchar() B)scanf(“%f%f”,&x,&y); 一般形式:getchar();或 ch=getchar(); C)scanf(“%lf%le”,px,py); D)scanf(“%lf%lf”,x,y); 例 1: ()有以下程序 【解析】A、D 项地址列表,应为&x,&y;x、y 为 double 型, #include &stdio.h& 格式控制字符串不是%f%f,故 B 项错误。 main() ? 当定义的变量类型和 scanf 中“格式符”类型不一致时(这 {char a,b,c,d; 里只限定在字符型和整型两种类型,其他数据类型不可 scanf(“%c%c”,&a,&b); 以。 )整型和字符型之间通过 ASCALL 可以相互转化。 c=getchar(); d=getchar(); 例 6: ()有以下程序 (说明:字符 0 的 ASCII 码 printf(“%c%c%c%c\n”,a,b,c,d); }当执行程序时,按下列方式输入数据(从第 1 列开始,&CR& 值为 48) 代表回车,注意:回车也是一个字符) main() 12&CR& 34&CR& { char c1,c2; 则输出结果是(B) scanf(&%d&,&c1); A)1234 B)12 C)12 D)12 3 34 c2=c1+9; 【解析】以%c 格式读取一个字符,以 getchar()形式也是读取 一个字符。空格会被当作字符赋值给变量。所以, printf(&%c%c\n&,c1,c2);第 14 页 共 78 页 a=?1?,b=?2?,c=?\n?,d=?3?。 ? getchar 经常作为 while 循环条件, 判断输入哪一个字符时, 循环结束。例如,输入字符串,直到输入‘0’ ,程序结束, 则可写成 while( getchar()!='0') 例 2: ()有以下程序段 main() { ? while( getchar()!='\n'); ? }以下叙述中正确的是(C)A)此 while 语句将无限循环 B) getchar()不可以出现在 while 语句的条件表达式中 C)当执行此 while 语句时,只有按回车键程序才能继续执行 D)当执行此 while 语句时,按任意键程序就能继续执行 【解析】while 条件表达式 getchar()!='\n'只要输入的字符不是 回车,就一直执行循环,而循环内是一个空语句,所以按回车 键程序才能继续执行,选择 C。第二课 选择结构与循环结构第 15 页共 78 页 本课重要知识点:第 16 页1.知识点:if 语句共 78 页 ? if (表达式) , 其中表达式可以是任意合法的 C 语言表达式。 b=c;} 例 1: ()下列条件语句中输出结果与其他语句不同 C)if(a&b) c=a; a=b; b=c; D)if(a&b){ c=a; a=b; 的是(D) b=c;} A.if(a) printf(“%d\n”,x); else printf(“%d\n”,y); 【解析】对于单个 if 语句,其后跟随的受 if 控制的只能是 1 B.if(a==0) printf(“%d\n”,y); else printf(“%d\n”,x); 个语句或者是 1 个复合语句。故 C 项,if(a&b)条件成立时,语 C.if(a!=0) printf(“%d\n”,x); else printf(“%d\n”,y); 句 c=a;才被执行,而无论 if(a&b)条件成立与否,语句 a=b;b=c; D.if(a==0) printf(“%d\n”,x); else printf(“%d\n”,y); 都会被执行。A、B、D 项,只有 if(a&b)条件成立时,语句 c=a; 【解析】作为 if 语句的条件,a 等价于 a!=0,因此 A 和 C 是 a=b;b=c; 才被执行。 等价的。 例 2: ()以下程序运行后的输出结果是 200 例 2: ()if 语句的基本形式是:if(表达式)语句,以 下关于“表达式”值的叙述中正确的是(D) A)必须是逻辑值 是任意合法的数值 【解析】表达式不限于关系表达式、逻辑表达式,也可以是任 意的数值类型,其中非 0 为真,0 为假。故选 D。 } 【解析】x=10,y=20,所以 x==y 为 false,t=x;不执行,直接执 B)必须是整数值 C)必须是正数 D)可以 main() { int x=10,y=20,t=0; if(x==y)t=x;x=y;y=t; printf(&%d %d\n&,x,y);? 对于单个 if 语句,其后跟随的受 if 控制的只能是 1 个语句 行 x=y;y=t;x 为 20, y 为 0。 注意和 if(x==y){t=x;x=y;y=t;}区别。 或者是 1 个复合语句。 例 1: ()设有定义:int a=1,b=2,c=3;以下语句中执 ? 当多个 if(表达式)单分支形式并行出现时,其执行顺序是: 行效果与其它三个不同的是(C) 先判断第一 if 单分支的条件,如果为真,执行其后面的语 A)if(a&b) c=a, a=b, b=c; B)if(a&b){ c=a, a=b, 句,执行完后,继续向下执行。判断第二个 if 单分支语句,第 17 页 共 78 页 依次类推。如果第一个 if 表达式的值为假,则不执行其后 例 2: ()有以下程序 的语句,而去判断第二个 if 单分支条件。 #include &stdio.h& main() 例 1: ()有以下程序 {int a=1,b=0; main() if(!a) b++; else if(a==0) if(a) b+=2; { else b+=3; scanf(&%d&,&x); printf(“%d\n”,b); }程序运行后的输出结果是(A) if(x&15) printf(&%d&,x-5); A)0 B)1 C) 2 D)3 【解析】else 总是与前面最近的且未曾配对的 if 语句配对,组 if(x&10) printf(&%d&,x); 成一对 if-else 语句。即 else b+=3; if(x&5) printf(&%d\n&,x+5); 与 if(a) b+=2;配对。if(!a)不成立,不执行 b++;else if(a==0)不成 } 若程序运行时从键盘输入 12& 回车 & ,则输出结果为 立,不执行 if(a) b+=2; else b+=3;故直接执行 printf(“%d\n”,b);,输出结果为 0。 1217 3.知识点:条件表达式 【解析】输入 12,比较不大于 15 所以不执行 if(x&15)内的语 ? 一般形式:表达式 1?表达式 2:表达式 3 ? 执行过程:表达式 1 的值为真,条件表达式取表达式 2 的 句 ; 大 于 10 执 行 printf(&%d&,x); 输 出 12 ; 大 于 5 执 行 值;表达式 1 的值为假,条件表达式取表达式 3 的值。 例 1: () 以下程序段中, 与语句: k=a&b?(b&c?1:0):0; printf(&%d&,x+5);输出 17。 功能相同的是(A) 2.知识点:if 语句的嵌套 A)if((a&b)&&(b&c)) k=1; B) ? 内嵌结构中,else 总是与前面最近的且未曾配对的 if 语句 if((a&b)||(b&c)) k=1; 配对,组成一对 if-else 语句。第 18 页 共 78 页 else k=0; C) if(a&=b) k=0; k=1; else if(b&=c) k=1; if(b&c) k=1;else k=0; 1:b++; D) if(a&b) default:a++;b++; default:a++;b++; else } } C)switch((int)x%2) else D)switch((int)(x)%2) k=0; {case 0:a++; {case 【解析】条件运算符的结合性是从右至左。当 b&c 时, b&c?1:0 0.0:a++; 的值为 1,k=a&b?1:0,同时当 a&b 时,a&b?1:0 的值为 1,此 case 1:b++; case 时 k=1。否则 k=0。故答案为 A。 1.0:b++; 4.知识点:switch 语句 default:a++;b++; ? switch 语句的圆括号中的表达式的值必须是整型或字符 default:a++;b++; 型,不能为实型。 } } ? case 后的表达式可以是求得整型和字符型的常量表达式, 【解析】 switch 语句的圆括号中的表达式的值必须是整型或字 但不能含有变量。 符型,不能为实型。x 是 double 型,x%2 不合法,A 项错误。 ? default 的位置对程序的执行没有影响。 (int)x%2.0 不合法,B 项错误。(int)x%2 值为整型,故 C 项正 例 1: ()若有定义语句 int a,b;则下列选项 确。 case 后面的表达式可以是求得整型量和字符型量的常量表 中没有错误是(C) 达式,故 D 项错误。 A)switch(x%2) B) 例 2: ()有以下程序 switch((int)x%2.0) #include &stdio.h& {case 0:a++; {case main() 0:a++; {int c=0,k; case 1:b++; case for(k=1;k&3;k++)第 19 页 共 78 页 switch(k) { {default:c+=k; scanf(&%d&,&s); case 2:c++; case 4:c+=2; while(s&0) } { switch(s) printf(“%d\n”,c); }程序运行后的输出结果是(A) { case1:printf(&%d&,s+5); A)3 B)5 C)7 D)9 【解析】当 k=1 时,没有匹配的 case,执行 default 语句, case2:printf(&%d&,s+4); c=c+k=0+1=1。继续往下执行 case 2 后边的语句,c++,c 变为 case3:printf(&%d&,s+3); 2,遇到 break 语句,于是退出内层 switch 结构。当 k=2 时, 找到匹配的 case 2,执行 c++; c 变为 3,遇到 break 语句,于 default:printf(&%d&,s+1); 是退出内层 switch 结构。执行外层循环 for 结构的 k++,k 变 } 为 3,k&3 不成立,跳出 for 语句。最后输出结果为 3。 ? 当 switch 语句和循环语句(for、while)时,要注意 switch scanf(&%d&,&s); 里面的 break 语句退出的位置。解决这一问题的方法是: } 首先划分结构,确定循环的语句体包括哪些语句。然后, 在继续划分循环体内的语句,如果循环体内的语句只有一 } 运行时,若输入 1 2 3 4 5 0&回车&,则输出结果是 条 switch 语句, 其内部出现了 break,遇到 break, 要结束当 (A) 前 switch 语句的执行,继续执行下一次循环。 例 1: ()有以下程序 main()第 20 页A)6566456 D)6666656共 78 页B)66656C)66666 【解析】while 循环 s&=0 时退出循环,输入 1 2 3 4 5 0,只有 printf(“%d\n”,a); 当输入 0 时退出循环, switch 中当 s=1 时, 执行 case 1, case 2, }程序运行后的输出结果是 (B) 由于 case 1 后面没有 break,会继续执行 case 2,遇到 break, A.- 1 B.0 C.1 D.7退出 switch;当 s=2 时,执行 case 2,退出 switch;当 s=3 时, 【解析】此类题一定要注意标点符号的位置,while(a--);该 执行 case 3,default,由于 case 3 后面没有 break,会继续执行 行末尾的分号即为一条空语句,来作为 while 的循环体。 ()有以下程序 default, 遇到 break, 退出 switch; 当 s=4 和 5 时, 执行 default, 例 1: #include &stdio.h& 退出 switch。所以输入 1 时,输出 65;输入 2 时,输出 6;输 main() {int a=1,b=2; 入 3 时,输出 64;输入 4 时,输出 5;输入 5 时,输出 6。故 while(a&6) {b+=a;a+=2;b%=10;} 选择 A。 printf(“%d,%d\n”,a,b); }程序运行后的输出结果是(B) 5.知识点:while,do-while,for 三种循环结构 A)5,11 B)7,1 例 1: ()有以下程序: D)6,1 #include &stdio.h& 例 2: (2011-03)有以下程序段 main() { int a=7; while(a--);第 21 页C)7,11main() { ? while( getchar()!='\n');共 78 页 无限循环 【解析】while(y--)后面的分号是一个空语句,当 y--不等于 0 }以下叙述中正确的是(C) 时执行空语句,当 y―等于 0 时,执行 printf 函数输出 y 值, 当 y―等于 0 时退出循环,此时 y 值变成-1。 A)此 while 语句将无限循环 ? 如果第一次判断表达式的值为 0,则循环一次也不执行。 B) getchar()不可以出现在 while 语句的条件表达式中 即 while 循环体最少执行 0 次。 例 4: (2011-03)当执行下列程序时,输入 &CR&, C)当执行此 while 语句时,只有按回车键程序才能继续执 则其中 while 循环体将执行 0 次。 #include &stdio.h& 行 main() D)当执行此 while 语句时,按任意键程序就能继续执行 { 【解析】while 条件表达式 getchar()!='\n'只要输入的字符不是 while((ch=getchar()==?0?)) printf(?#?); 回车,就一直执行循环,而循环内是一个空语句,所以按回车 } 键程序才能继续执行,选择 C。 【 解 析 】 ch=getchar() , ch 第 一 次 读 入 的 值 为 ?1? , 故 ? 循环体部分可以只有一条空语句,不做任何操作。 while((ch=getchar()==?0?))不成立,循环一次也不执行。 例 3: ()有以下程序 ? while 循环与 switch 结构 #include &stdio.h& 例 5、 (2011-03)有以下程序 main() main() {int y=10; while(y--); { printf(“y=%d\n”,y); scanf(&%d&,&s); }程序执行后的输出结果是(B) A)y=0 B)y=-1 C)y=1 D)while 构成 while(s&0) ?第 22 页 共 78 页 { switch(s) { case1:printf(&%d&,s+5); case2:printf(&%d&,s+4); case3:printf(&%d&,s+3); default:printf(&%d&,s+1); }执行 case 3,default,由于 case 3 后面没有 break,会继续执行 default, 遇到 break, 退出 switch; 当 s=4 和 5 时, 执行 default, 退出 switch。所以输入 1 时,输出 65;输入 2 时,输出 6;输 入 3 时,输出 64;输入 4 时,输出 5;输入 5 时,输出 6。故 选择 A。6.知识点:do-while 语句 例 1: (
) 以 下 程 序 运 行 后 的 输 出 结 果 是 scanf(&%d&,&s); 5 。 #include &stdio.h& } main() } 运行时,若输入 1 2 3 4 5 0&回车&,则输出结果是(A) {int a=1,b=7; do{ A)6566456 B)66656 C)66666 b=b/2; a+=b; }while(b&1); D)6666656 printf(“%d\n”,a);} 【解析】 :while 循环 s&=0 时退出循环,输入 1 2 3 4 5 0,只有 ? do-while 循环体最少执行 1 次。 (2007-09)若变量已正确定义,有以下程序段 当输入 0 时退出循环, switch 中当 s=1 时, 执行 case 1, case 2, 例 2: i=0; 由于 case 1 后面没有 break,会继续执行 case 2,遇到 break, do printf(“%d,”,i); while(i++); 其输出结果是 (B) 退出 switch;当 s=2 时,执行 case 2,退出 switch;当 s=3 时, printf(“%d\n”,i); A)0,0 B)0,1 C)1,1 D) 程序进入第 23 页 共 78 页 无限循环 不能,则输出 i+b,如果可以则输出 i+c,注意 if(i%2)是求表 【解析】执行 do-while 循环,输出 i 的值为 0,接着判断循环 达式 i%2 是否为 true,即其结果是不是非 0。所以 i 为 0 时, 条件 i++,i++的值为 0,i 的值为 1,故答案是 B。 7.知识点:for 语句 输出 0+A=A,i 为 1 时,输出 1+a=b,i 为 2 时,输出 2+A=C, 例 1: (2011-03)有以下程序 i 为 3 时,输出 3+a=d,i 为 4 时,输出 4+A=E,i 为 5 时,输 main() { char b,c; b='a'; c='A'; 出 5+a=f。故选 B。? 表达式 1、表达式 2、表达式 3 可以缺省,但两个分号不能 省略。 表达式 1 省略的情况如下: for(i=0;i&6;i++) 例 2: ()有以下程序 { if(i%2) putchar(i+b); #include &stdio.h& main() else putchar(i+c); {int a=1,b=2; } for(;a&8;a++) {b+=a;a+=2;} printf(“%d,%d\n”,a,b); printf(&\n&); }程序运行后的输出结果是(D) } 程序运行后的输出结果是(B) A)9,18 B)8,11 C)7,11 D)10,14 ? 表达式 1 和表达式 3 也可以是逗号表达式。 A)ABCDEF B)AbCdEf C)aBcDeF 例 3: ()以下程序段中的变量已正确定义 for(i=0;i&4;i++,i++) D)abcdef for(k=1;k&3;k++) printf(“*”);程序段的输出结果是 (B) 【解析】 :for 循环执行 6 次,每次判断 i 能否被 2 整除,如果 A)******** B)**** C)** D)*第 24 页 共 78 页 【解析】 外层 for 循环,表达式 3 是逗号表达式,即 i 自加 2。. switch (n) ? for 循环与 switch 结构 { case 1: 例 4: ()有以下程序 #include &stdio.h& case 3:printf(&%d\n&,n); main() case 2: {int a[]={2,3,5,4},i; for(i=0;i&4;i++) case 4:printf(&%d\n&,n); switch(i%2) {case 0:switch(a[i]%2) case 0:exit(0); {case 0:a[i]++; } case 1:a[i]--; } printf(&%d\n&,n); case 1:a[i]=0; } 以下关于程序段执行情况的叙述,正确的是(D) } for(i=0;i&4;i++) printf(“%d”,a[i]); printf(”\n”); A)for 循环语句固定执行 8 次 }程序运行后的输出结果是( C) B)当产生的随机数 n 为 4 时结束循环操作 A)3 3 4 4 B) 2 0 5 0 C)3 0 40 C)0 3 0 4 例 5、 (2011-03)有以下程序段 C)当产生的随机数 n 为 1 和 2 时不做任何操作 int i,n; D)当产生的随机数 n 为 0 时结束程序运行 for(i=0;i&8;i++) 【解析】 :rand()是随机产生一个整数,rand()%5 即随机得到 { n=rand()%5; 0-4 这五个数字,for 循环控制随机产生 8 次,当得到 1,3 时第 25 页 共 78 页 执行 printf(&%d\n&,n) 并退出 switch ,当得到 2 , 4 时执行 达式也可以是逗号表达式,本题表达式 1 是一个逗号表达式, printf(&%d\n&,n)并继续循环,当得到 0 时,exit(0)正常结束程 i 赋值为 0,同时 k 赋值为-1。所以判断表达式 2:k=1 是 k 赋 序。所以循环不一定执行 8 次,故选择 D。 ? for 循环与数组 例 6: ()有以下程序 #include &stdio.h& main() {int i,n[]={0,0,0,0,0}; for(i=1;i&=4;i++) {n[i]=n[i-1]*3+1; printf(“%d ”,n[i]);} }程序运行后的输出结果是 1 4 13 40 ? 注意区 赋值语句和判断语句 值为 1,故无限循环,选择 D。8.知识点:循环嵌套 例 1: ()有以下程序 #include &stdio.h& main() {int i,j,m=1; for(i=1;i&3;i++) { for(j=3;j&0;j--) 。 {if(i*j&3) m*=i*j; } 例 7: (2011-03)若 i 和 k 都是 int 类型变量,有以下 for 语句 } for(i=0,k=-1;k=1;k++) printf(&*****\n&); printf(“m=%d\n”,m); }程序运行后的输出结果是 (A) 下面关于语句执行情况的叙述中正确的是 (D) A)m=6 B)m=2 C)m=4 A)循环体执行两次 B)循环体执行一次 例 2: (2011-03)有以下程序 main() C)循环体一次也不执行 D)构成无限循环 { int x=1,y=0; if(!x) y++; 【解析】 : for 循环的表达式 1 和表达式 3 可以是一个简单的表 else if(x==0)第 26 页 共 78 页D)m=5 if (x) y+=2; main() else y+=3; {int k=1,s=0; printf(&%d\n&,y); do{ }程序运行后的输出结果是 (D) if((k%2)!=0) A)3 B)2 C)1 D) 0 s+=k; k++; 【解析】 :if-else 的嵌套,注意 else 总是与前面最近的且未配 }while(k&10); 对的 if 语句配对组合。 if(!x)中 x 为 1, ! x 为 0 为 false, 即 if(!x) printf(“s=%d\n”,s); 后的语句不执行,else if(x==0),x 为 1 也不等于 0,也不成立, } 故 else if 内的语句也不执行, 而 if (x) y+=2;else y+=3;均为 else 【解析】k=1,if((k%2)!=0)条件成立,执行 continue 语句,结 if 内的语句。所以直接输出 y 为 0,故选 D。 束本次循环, 判断表达式 k&10, 值为 0, 故跳出 do-while 循环, 9.知识点:break 语句 执行 printf(“s=%d\n”,s);则输出结果为 s=0。 ? 功能:跳出整个 switch 语句;跳出循环体,防止死循环。 ? break 语句只能出现在 switch、 while、 do-while、 for 循环中, 不能出现在其他地方。 ? 作用范围:所在循环体从属的最内层循环,而不是外层的 某个循环。 6.知识点:continue 语句 ? 功能:结束本次循环,接着判断是否继续下一次循环。 ? continue 语句只能出现在 while、do-while、for 循环中。 ? 作用范围:所在循环体从属的最内层循环,而不是外层的 某个循环。 例 1: ()以下程序运行后的输出结果是 s=0 #include &stdio.h&第 27 页 共 78 页 第三课 数组第 28 页共 78 页 本课重要知识点:第 29 页1.知识点:一维数组的定义共 78 页 例 1: () 下列选项中, 能正确定义数组的语句是 (D) 限,已经越界,故 C 项错误。m[4]=1,没有越界,故 D 项正 A)int num[0…2008]; B)int num[]; 确。 C)int N=2008; D)#define N 2008 例 2:(2011-03)以下程序运行后的输出结果是 13715 int num[N]; int num[N]; main() 【解析】数组的长度必须是一个整型常量、整型常量表达式, { int i,n[5]={0}; 故 A 项错误。定义数组时,不能省略数组长度,B 项错误。数 组的长度不能是变量, C 项错误。 数组的长度可以是符号常量, for(i=1;i&=4;i++) D 项正确。 { n[i]==n[i-1]*2+1; printf(&%d&,n[i]); } 例 2: ()若要定义一个具有 5 个元素的整型数组, 以 下错误的定义语句是(D) printf(&\n&); A)int a[5]={0}; B)int b[]={0,0,0,0,0}; C)int c[2+3]; D)int i=5,d[i]; } 【解析】 可以只给数组的前面一部分元素设定初值, A 项正确。 【解析】 :n[1]=1,n[2]=1*2+1=3,n[3]=3*2+1=7,n[4]=7*2+1=15 对全部数组元素赋初值时,可以不指定数组元素的个数,B 项 正确。数组的长度可以是一个整型常量表达式,C 项正确。数 3.知识点:一维数组的初始化 ? 顺序列出数组元素的全部初值,例如 int a[5]={1,2,3,4,5}; 组的长度不能是变量,D 项错误。 ? 只给数组的前面一部分元素设定初值,未赋初值的元素自 2.知识点:一维数组元素的引用 动取 0 值。例如,int a[5]={1,2}; 例 1:()若有定义语句:int m[]={5,4,3,2,1},i=4;则下 ? 对全部数组元素赋初值时,可以不指定数组元素的个数。 面对 m 数组元素的引用中错误的是 (C) 例如,int a[]={1,2,3,4,5}; A)m[--i] B)m[2*2] C)m[m[0]] 4.知识点:二维数组的初始化 D)m[m[i]] 【解析】m 数组元素的引用的下限为 0,上限为 4。i=4,--i ? 按行分段给二维数组赋初值 的值为 3,A 项正确。B 项没有越界,正确。m[0]=5,超过上 ? 按行连续赋值第 30 页 共 78 页 ? 对部分元素赋初值,未赋初值的元素自动取 0 值 ? 若对全部元素赋初值,则第一维的长度可以不指定 例 1: ()以下数组定义中错误的是(B) A) int x[][3]={0}; B) int x[2][3]={{1,2},{3,4},{5,6}}; C) int x[][3]={{1,2,3},{4,5,6}}; D) int x[2][3]={1,2,3,4,5,6}; 【解析】若对全部元素赋初值,则第一维的长度可以不指定, C 项正确。二维数组的初始化可以按行连续赋值,D 项正确。 C 项二维数组的初始化超过第一维度长度,故错误。 5.知识点:二维数组和 for 语句 例 1: ()有以下程序 #include &stdio.h& main() {int i,j,a[][3]={1,2,3,4,5,6,7,8,9}; for(i=0;i&3;i++) for(j=i;j&3;j++) printf(“%d”,a[i][j]); printf(“\n”); }程序运行后的输出结果是 123569 。 6.知识点:字符串 定义:由“”引起来的,由若干个字符所组成的序列。 字符串的结束标志:?\0? 如字符串“china”,在内存中存储形式是第 31 页china\0该字符串的长度为 5 字节,所占的存储空间为 6 字节。 7.知识点:字符数组的定义及初始化 ? 字符数组名是地址常量,不能赋值给数组名。 例 1: ()以下选项中正确的语句组是(D) A)char s[];s=”BOOK!”; B)char *s;s={“BOOK!”}; C)char s[10];s=”BOOK!”; D)char *s;s=”BOOK!”; 【解析】字符数组名是地址常量,不能赋值给数组名,故 A、 C 项错误,D 项指针 s 是个变量,将字符串常量赋值给 s,是 正确的。B 项中给 s 赋值时不能用花括号将字符串括起来。 例 2: ()下面是有关 C 语言字符数组的描述,其中 错误的是(D) A)不可以用赋值语句给字符数组名赋字符串 B)可以用输入语句把字符串整体输入给字符数组 C)字符数组中的内容不一定是字符串 D)字符数组只能存放字符串 8.知识点:字符数组的输入与输出 例 1: ()有以下程序 #include &stdio.h& main() {char a[20]=”How are you?”,b[20];共 78 页 scanf(“%s”,b);printf(“%s %s\n”,a,b); for(i=0;s[i]!=0;i++) }程序运行时从键盘输入:How are you?&回车& if(s[i]&='0'&&s[i]&='9') n++; 则输出结果为 How are you? How printf(&%d\n&,n); 【解析】scanf 函数输入,以空格作为字符串输入结束的标志, } 程序运行后的输出结果是 (B) 故字符数组 b 只接收到字符串”How”。 A)0 B)3 C)7 D)8 例 2: (2011-03)有以下程序 【解析】 :for 循环读取字符数组 s 中的字符,当读到 0 时退出 main() 循环, 注意 0 和 ‘0’ 的区别, 字符 ‘0’ 的 ASCII 码为 48, ‘\0’ { char a[30],b[30]; 的 ASCII 码才是 0,所以读取的字符为“012xy”中的字符, scanf(&%s&,a); for 循环读取到字符后判断是不是数字字符,如果是 n 自增 1, gets(b); “012xy”中的数字字符只有三个,所以选择 B。 printf(&%s\n %s\n&,a,b); 9.知识点:字符串处理函数 }程序运行时若输入:how are you? I am fine&回车&则输出结果 例 1:()有以下程序: 是(B) #include&stdio.h& A)how are you? B)how #include&string.h& I am fine are you?I am fine main() C)how are you? I am fine D)row are you? { char 【解析】 :scanf 以空格作为字符串输入结束的标志,而 gets(s) a[5][10]={“china”,”beijing”,”you”,”tiananmen”,”welcome”}; 不会。所以 a 得到的是“how” ,b 得到的是剩下的“are you? I int i,j; char t[10]; am fine” 。故选择 B。 for(i=0;i&4;i++) 例 3: (2011-03)有以下程序 for(j=i+1;j&5;j++) main() if(strcmp(a[i],a[j])&0) { char s[]=&012xy\08s34f4w2&; { strcpy(t,a[i]); strcpy(a[i],a[j]); strcpy(a[i],t);} int i, n=0; puts(a[3]);第 32 页 共 78 页 }程序运行后的输出结果是 (C) main() A.beijing B.china C.welcome D.tiananmen {char a[20]=”ABCD\0EFG\0”,b[]=”IJK”; 【解析】双层 for 循环部分是典型的排序方法,通过 strcmp 比 strcat(a,b); printf(“%s\n”,a); 较两个字符串的大小,然后借助 t 数组作为中转数组,通过 }程序运行后的输出结果是(B) strcpy 函数完成 a[i]和 a[j]两个字符串的交换, 使 a 数组按从小 A)ABCDE\0FG\0IJK B)ABCDIJK C)IJK 到 大 排 序 , 即 {”beijing” , D)EFGIJK “china” , ”tiananmen”,”welcome” ,”you” } 【解析】 把字符数组 b 中的字符串连接到字符数组 a 中字符串 例 1:()有以下程序 的后面,并删去字符串 a 后的第一个字符串结束标志?\0?。故 #include &stdio.h& 输出结果为 ABCDIJK。 #include &string.h& 例 3: ()下列选项中,能够满足“若字符串 s1 等于 main() 字符串 s2,则执行 ST”要求的是 (A) {char x[]=”STRING”; A)if(strcmp(s2,s1)==0)ST; x[0]=0;x[1]=?\0?;x[2]=?0?; B)if(s1==s2)ST; printf(“%d %d\n”,sizeof(x),strlen(x)); C)if(strcpy(s1,s2)==1)ST; }程序运行后的输出结果是(B) D)if(s1-s2==0)ST; A)6 1 B)7 0 C)6 3 D)7 1 【解析】若字符串 s1 等于字符串 s2,strcmp(s2,s1)==0,故答 【解析】 经过 x[0]=0;x[1]=?\0?;x[2]=?0?;后, x[]=”0\00ING”。 strlen 案是 A。 测字符串的实际长度,不含字符串结束标志?\0?,故 strlen(x) 为 0。sizeof 测字符串所占的存储空间,包含字符串结束标志, 故 sizeof(x)为 7。 例 2:()有以下程序 #include &stdio.h& #include &string.h&第 33 页 共 78 页 第 34 页共 78 页 第四课 指针第 35 页共 78 页 本课重要知识点:第 36 页1.知识点:指针的概念与指针变量共 78 页 ? 指针就是地址。指针变量是用来存储地址,而一般变量是 【解析】*和++同级别,按自左向右的结合方向,因此 D 选项 用来存储数值。 可转变为*(p++) ,从而只是使指针发生移动,而不能将 p 所 例 1.(09-09-26)有如下程序输出结果为 1,2,2,1 指变量增 1 #include &stdio.h& 例 2.(06―04―24)若有说明语句: double *p, a; 则能通过 scanf main() 语句正确给输入项读入数据的程序段是 (D) { int m=1,n=2,*p=&m,*q=&n,*r; A)*p=&a; scanf(&%lf&,p); r=p=q= B)*p=&a; scanf(&%f&,p); printf(“%d,%d,%d,%d\n”,m,n,*p,*q) ; C)p=&a; scanf(&%lf&,*p); } D)p=&a; scanf(&%lf&,p); 【解析】p、q 为指针,初始化时 p 指向 m,q 指向 n。执行 【解析】对于 scanf 函数,输入数据列表必须是合法地址 r=p=q=p 和 q 的值交换,从而 p 指向 n,q 指向 m。指 表达式(可以使地 针的改变不会应用 m、 n 的值, 最后输出*p 和*q 的值分别为 n、 址常量、指针),A 选项、B 选项*使用错误。 m 的值。 例 3.(09-03-16) 若 有 定 义 语 句 doule x,y,*px,* 执 行 了 2.知识点:指针的引用 px=&x;py=&y;之后,正确的输入语句是(C) ? 指针的引用是通过两个运算符实现“&”和“*”实现的 A) scanf(&%f%f&,x,y); B) scanf(&%f%f&&x,&y); &是取地址符号, 它的一半格式是: &变量名。 例如: C) scanf(&%f%le&,px,py); D) scanf(&%lf%lf&,x,y); &i 表示取 i 的地址。 【解析】 A,D 选项中的 x,y 缺少取地址符, B 项中&x 之前缺少 * 是取值运算符,它的一般格式: * 指针变量名。例如 :int 逗号,格式不正确。 i=10,*p=&i; *p 表示取 i 的值 10 3.知识点:指针变量的初始化 例 1.()若定义语句:int year=2009,*p=&,以下不 ? 指针变量在使用前必须要初始化,把一个具体的地址赋给 能使变量 year 中的值增至 2010 的语句是 (D) 它,否则引用时会出错,如果不指向任何数据就赋“空值” A.*p+=1; B.(*p)++; C.++(*p); NULL。 D.*p++; ? 指针变量两种初始化方法:方法一:int a=2,*p=&a;(定第 37 页 共 78 页 义的同时初始化) 方法二: int a=2, *p; p=&a; (先定义后初始化) 例 1.(07―04―29)设已有定义:float x;则以下对指针变量 P 进行定义且赋初值的语句中正确的是 (D) A)float *p=1034; B)int *p=(float)x; C)float p=&x; D)float *p=&x; 【解析】 可以给一个指针赋值的只能是一个与该指针同类型的 指针(或地址值);故 A、B 选项错误;C 选项声明指针出错,P 前面的指针说明符*不能省略。 4.知识点:指针的运算 ? *p++和(*p)++之间的差别:*p++是地址变化,(*p)++是指 针变量所指的数据变化。一个指针变量加一个整数不是简 单的数学相加,而是连续移动若干地址。当两个指针指向 同一数组时,它们可以比较大小进行减法运算。 例如:int a[10],*p; p=a; p++;表示 p 移动一个存储单元,p 指向 a[1],只有当指着指向数组元素时,指针的运动才有意义。 5:知识点:指针与数组 ? 指针与一维数组 数组名代表数组的首地址。一维数组中,第一个元素的地 例 2.(11-03-24)设有定义:double x[10],*p=x;,以下能给数组 x 址即为该数组的起始地址。建立指针变量与一维数组的联系: 下标为 6 的元素读入数据的正确语句是( C ) 例如: int a[6],* pa=a;或 pa=&a[0]; 说明:①数组名 a 代表该数组的首地址,也即 a[0]的地址。 A)scanf(&%f&,&x[6]); B)scanf(&%lf&,*(x+6));第 38 页 共 78 页② pa=a;或 pa=&a[0];使 pa 保存了数组 a 的首地址, pa,a,&a[0]都指向一个地址。 ③以上操作可等价于 int a[6],*pa=a; ④如果 pa=&a[3];表示*pa 的值就是 a[3]的地址。 注意:数组 a 是一个地址常量,它永远指向数组的首地址,不 能重新赋值。因此 a=&i;或 a++都是错误的。 例 1.(08―04―23)有以下程序 #include&stdio.h& main() {int a[]={1,2,3,4),y,*p=&a[3]; --p;y=*p;printf(&y=%d\n&,y); } 程序的运行结果是(D) A)y=0 B)y=l C)y=2 D)y=3 【解析】程序中定义一个一维数组,并初始化,再一定义了一 变量和一个指针(将指针指向数组下标为 3 的一个元素),执行 --p;(注意,当指针指一个元素后,指针变量加上“*”时,表 示引用的是元素的值,当不加“*“时表示引用的是地址),向 前移动一个位置,指向 a[2],y=+p;(将 p 指针指向的值 3 赋 给变量 y),输出 y 的值为 3。 例如:int *p,a[5]; p=a; 说明:①p[0]表示 p 指针指向的内存单元,p[1]表示 p 指向 【解析】数组名是数组的首地址,p=x,指针 p 指向数组的首 的内存单元 ②a[i]的等价引用方法:a[i]、p[i]、*(a+i)、*(p+i) 地址,要表示数组 x 下标为 6 的元素的地址可以有&x[6],x+6, ③a[i]的地址等价引用方法:&a[i]、&p[i]、a+i、p+i p+6, &p[6],scanf 后面的参数列表必须是地址列表, B 中* (x+6) 例 1.(09-03―29)若有以下定义 int x[10],*pt=x; D 中 p[6]都是取数组 x 下标为 6 的元素的值, A 中格式控制符%f 则对 x 数组元素的正确应用是 B A)*&x[10] B)*(x+3) C)*(pt+10) D)pt+3 与 double 类型不匹配,所以选 C。 【解析】引用数组元素时,注意取地址运算符&与指针运算符 6.知识点:用指针访问数组元素 t 的作用;指针运算符+用来取得指针变量所指存储空间的内 ? 通过指针引用数组元素 容,取地址运算符&用来取得变量的地址值;A 选项数组下标 例如:int *p,a[5]; p=&a[0]; 越界;B 选项中+(x+3)等价于元素 X[3];C 选项中。(pt+10)等 说明:①指针变量 p 指向了数组元素 a[0],可以使用访问 价于 x[10],数组下标越界;D 选项 pt+3 是元素 x[3]的地址, 运算符“*”来引用变量 a[0]; 与&x[3]等价;故正确答案是 B。正确答案:B 例:*p=18;等价于 a[0]=18; 例 1.()有以下程序 ②*(p+1)表示 a[1] p+1 表示&a[1] #include &stdio.h& ? 通过数组的首地址引用数组元素 void fun(int *p) 例如:int a[5]; {printf(“%d\n”,p[5]);} 说明:①a 是数组名,表示收地址,可以把 a 当做一个指针 main() 常量。 {int a[10]={1,2,3,4,5,6,7,8,9,10}; ②*a 等价与 a[0], *(a+1)等价与 a[1]; a 等价于&a[0], fun(&a[3]); a+1 等价与&a[1]; }程序运行后的输出结果是 (D) ? 用带下标的指针变量引用一维数组元素 C)scanf(&%lf&,p+6); D)scanf(&%lf&,p[6]);第 39 页 共 78 页 A.5 B.6 C.8 D.9 语句正确的是(B) 【解析】 fun 函数被调用时将&a[3]通过传递付给了形参指针变 A)pk=k; B)pk[0]=&k[1][2]; C)pk=k[0]; D)pk[1]=k; 量 p, 此时可用*p 或 p[0]来表示 a[3],因此 p[5]亦可表示 a[8], 【解析】题目中定义了一个二维数组和一个指针数组,pk 是 所以输出结果为 9 指针数组名,不能被赋值,指针数组 pk 中的元素是指针,并 7.知识点:指针与二维数组 且二维数组名是指向一维数组的指针常量,相当于行指针,二 ? 任何一个二维数组均由若干个一维数组组成,a[0]、a[1]和 者不可转换,所以 A、C、D 选项均有误,本题答案选 B。 a[2]是一维数组名,数组名代表数组的首地址,因此 a[0] 例 2.(09-09-27) 若有定义语句: int a[4][10],*p,*q[4];且 0&=i&4, 就代表数组元素 a[0][0]的地址,也即&a[0][0]。 则错误的赋值是 (A) 注意:a 的值与 a[0]相同,但它们的基类型不同,a 可以等价 A)p=a B)q[i]=a[i] C)p=a[i] D)p=&a[2][1] 于一个二维指针,而 a[0]是一维指针。因此 int a[3][4],*p=a; 【解析】p 为基类型为 int 的指针,指向一个整形数据,也就 错误 可以指向一个数组元素,所以 D 正确。指针数组 q 的每个数 取数组元素 a[i][j] 的地址的几种方法: &a[i][j] ; a[i]+j ; 组元素 q[i]的基类型也为 int,所以 p、a[i]、a[i]的基类型一致, *(a+i)+j; 选项 B、C 也是正确的。 ? 指针数组的定义方式: 8.知识点:指针与函数 *指针数组名[常量表达式];如:int *p[3]; 例 1.(08―04―40)设有定义语句 int(*f)(int); ,则以下叙述正确 ? 行指针的一般定义形式如下: 的是__B_______。 类型名 (*指针数组名)[常量表达式]; 如:int (*p)[2]; A)f 是基类型为 int 的指针变量 ? 指针数组与行指针的区别 B)f 是指向函数的指针变量, 该函数具有一个 int 类型的形 1、int *p[3];定义的是指针数组,表示一个数组,含有 3 个元 态 素 p[0]、p[1]、p[2],且这 3 个元素只能存放整型元素的地址 C)f 是指向 int 类型一维数组的指针变量 2、int (*p)[3];定义的是行指针,表示一个指针变量,它仅有 D)f 是函数名,该函数的返回值是其类型为 int 类型的地 一个存储空间,只能存放一个长度为 2 的一维数组指针。 址 例 1.(06―09―33)若有定义语句:int k[2][3],*pk[3];则以下 【解析】在 c 语言中,函数名代表此函数的入口地址,所第 40 页 共 78 页 因此,可以定义一种指向函数的指针来存放函数的入口地址, }程序运行后的输出结果是 (B) 定义方式是:函数返回值类型(*函数指针名)(参数类型列表); A.abc B.789 C.7890 D.979898 本题答案选 B。 例 11.()若有定义语句: char *s1=” OK” ;*s2=” ok” ;, 9.知识点:指针与字符串 以下选项中,能够输出“OK”的语句是 (D) ? 可以通过字符指针来处理字符串 A.if(strcmp(s1,s2)==0) puts(s1); 例如:char *p=&China&或者 char *p;p=&China&;把字符串赋值给 B.if(strcmp(s1,s2)!=0) puts(s2); 指针 p, 实质是把保存字符串&China&的那段内存的首地址赋值 C.if(strcmp(s1,s2)==1) puts(s1); 给指针 p,使得指针 p 指向了字符串,这样就可以通过指针来 D.if(strcmp(s1,s2)!=0) puts(s1); 操作字符串了。 【解析】strcmp 函数作为字符串比较函数,当 s1 等于 s2 所指 【注意】char str[10] ; str=&China&;是错误的!数组名是地址 字符串时结果为 0, 当 s1 大于 s2 所指字符串时结果为 &0, 当 常量,不能进行赋值操作! s1 小于 s2 所指字符串时结果为 &0 ? “三名主义” (考试的重点) 例 11.(07―04―44)有下列程序: 数组名:表示第一个元素的地址。数组名是地址常量名,不 main() 能进行赋值和自加(减)等运算。 (考了很多次) {char ch[]=“uvwxyz” ,*pc; 函数名:表示该函数的入口地址。 pc=ch;printf(”%c\n” ,*(pc+5)); 字符串常量名:表示第一个字符的地址。 } 程序运行后的输出结果是(A) 例 11.()有以下程序 (注: 字符 a 的 ASCII 码值为 97) A)Z B)0 C)元素 ch[5]的地址 D)字符 Y 的地址 #include &stdio.h& 【解析】 指针 P 指向了字符数组 ch, *(pc+5)--&ch[5]--&?z?, printf main() 函数要求以%c 形式输出,故输出字符 Z。 { char *s={“abc”}; 例 12.(09-09-37)设有定义:char *c;.以下选项中能够使字符 do 型指针 c 正确指向一个字符串的是(A) {printf(“%d”,*s%10);++s;} A)char str[]=”string”; c= B)scanf(“%s”,c); while(*s); C)c=getchar(); D)*c=”string”;第 41 页 共 78 页 【解析】选项 A 为正确用法。先将字符串存于字符数组中, 然后将数组名赋给字符指针。选项 B 为无语法错误,但运行 时可能会出现问题。原因是字符指针没有被赋值,是一个不确 定的值,指向一个不确定的内存区域,这个区域可能存放有用 的指令或数据。在这个不确定的区域重新存放输入的字符串, 可能会发生无法预知的错误。选项 C 错误。getchar()函数输入 一个字符给字符型变量,而不应该是字符指针。选项 D 错误。 *c=”string”应该改为 c=”string”才是正确的。第五课 函数第 42 页 共 78 页 本课重要知识点:第 43 页1、知识点:函数的概述共 78 页 例 1:下列叙述中正确的是( C ) A)C 语言程序将从源程序中第一个函数开始执行 函数体包括声明部分和执行语句部分组成。 B)可以在程序中由用户指定任意一个函数作为主函数,程 序将从此开始执行 ? C语言程序可以由多个源程序组成,其中一个源程序文件 C)C 语言规定必须用 main 作为主函数名, 程序将从此开始 包含 main 函数,其他函数可以写在另外的源程序文件中, 执行,在此结束 D)main 可作为用户标识符,用以命名任意一个函数作为主 为单独文件,并且可以单独编译。 函数。 例 1: (10-03-11)以下叙述正确的是( B ) ? 在一个函数的函数体内,不能再定义另一个函数,即不能 A)C 语言程序是由过程和函数组成的 嵌套定义。 B)C 语言函数可以嵌套调用,例如:fun(fun(x)) C)C 语言函数不可以单独编译 例 1、下列叙述中正确的是( D ) D)C 语言中除了 main 函数, 其他函数不可以作为单独文件 A)每个 C 程序文件中都必须要有一个 main()函数 形式存在 B)在 C 程序中 main ()函数的位置是固定的 【解析】选项 A 错误,C 语言中没有过程的概念;选项 B 正 C)C 程序中所有函数之间都可以是固定的 确,C 语言可以嵌套调用(此知识点在后面介绍) ;选项 C 错 D)在 C 程序的函数中不能定义另一个函数 误,C 语言中可以对包含一个或多个函数的源程序单独编译; 【解析】一个 C 源程序可以由多个 C 程序文件,但只能有一 选项 D 错误,C 语言函数可以单独存在。 个 main()函数, 并不是每个 C 程序文件都必须要有一个 main(), ? C源程序是由函数组成的, 函数由函数首部与函数体组成, ? C程序的执行总是从 main 函数开始,完成对其它函数的 main()函数可以放在任意位置,且不允许被其他函数调用,因 此正确答案是 D。 调用后再返回到 main 函数,最后由 main 函数结束整个程 2、知识点:函数的定义 序。main 函数可以调用其它函数,而不允许被其它函数调 例 1:以下正确的函数定义形式是: (C) A)double fun(int x,int y);{} B) double fun(int 用。一个C源程序必须有,也只能有一个主函数 main。第 44 页 共 78 页 int y){} 致,以函数类型为准。 C) double fun(int x,int y){} D) double fun(int x, 例 2:(06-04-23)已定义以下函数 y);{} 【解析】在函数中对形参的说明,要求对每个形参都必须说明 int fun(int *p){return *p;} fun 函数返回值是( B ) 类型,各参数之间用“,”隔开,函数定义后应无“; ” 。 A)不确定的值 B)一个整数 C)形参 P 中存放的值 D) 形 ? 函数返回 return 语句的一般形式:return 表达式;或 return 参 P 的地址值 (表达式); 在函数中允许有多个 return 语句,但每次只能有一个 【解析】函数返回性类型取决于定义函数时函数名称前的 return 语句被执行。 例 1: (10-03-24)以下关于 return 语句叙述中正确的是( B) 类型, fun 前是 int, 表明函数 fun 执行完毕后返回一个整型数。 A)一个自定义函数中必须有一条 return 语句 正确答案:B B)一个自定义函数中可以根据不同情况设置多条 return 语句 ? return 后的表达式可以是常量、变量、表达式,也可以空。 C)定义 void 类型的函数中可以有带返回值的 return 语句 如: return 0; return (a+b); D) 没有 return 语句的自定义函数在执行结束时不能返回到 调用处。 3、知识点:形参和实参及函数调用 【解析】自定义函数中可以没有 return 语句(如不需要返回值 ? 形参出现在函数定义中(即定义函数时函数名后面括号中 的函数,常见 void 类型) ) ,可以有多条 return 语句(如在分 的参数) ,实参出现在主调函数中(调用函数时函数名后面 支结构中,可以从不同分支中返回到调用程序,常见 if..else) ; 括号中的参数) 定义成 void 类型的函数,不允许从该函数取得返回值,也不 ? 形参在本函数体内都可以使用,离开该函数则不能使用。 允许使用 return 语句。没有 return 语句的函数在执行到函数的 实参在主调函数中内有效,进入被调函数后,实参变量也 最后一条语句后自动返回达到调用处。 不能使用。 (注: 在进行函数调用时, 函数必须有确定的值) ? 函数值的类型与函数定义中函数的类型保持一致,如不一 ? 实参向形参单向传递数值,不能将形参的值反向的传送给第 45 页 共 78 页 实参。实参和形参在数据上、类型上、顺序上要一致。在 函数调用过程中,形参的变化不会改变实参的变化。 例 1、 (09-09-24)有以下程序 #include &stdio.h& void fun(int p) { int d=2; p=d++; printf(“%d”,p); } main() { int a=1; fun(a); printf(“%d\n”,a); } 程序运行后的输出结果是( C ) A) 32 B)12 C)21 D)22 【解析】此题考点为函数参数的传递。C 语言中函数参数的传 递是值传递,是把实参的值传给形参,是单向传递,形参的改 变不会影响到实参的值。程序中,把实参 a 的值传给形参 p, p=1,然后 p=d++,再次赋值后 p=2,输出 p 的值 2。返回到主 程序中,输出 a 的值为 1。 (形参 p 的改变不会影响到实参 a 的值,a 的值仍为 1).因此答案为 C. ? 在传递数值时,形参和实在分别占据不同的存储单元(形 参变量只有在被调用时才分配内存单元,调用结束后,即 刻释放分配的内存单元) 例 1、(07-04-25)若函数调用时的实参为变量时,以下关于 函数形参和实参的叙述中正确的是( D) A)函数的实参和其对应的形参共占同一存储单元第 46 页B)形参只是形式上的存在,不占用具体存储单元 C)同名的实参和形参占同一存储单元 D)函数的形参和实参分别占用不同的存储单元 【解析】本题考点是函数的参数定义,在函数中,主调数 中里边的参数叫做实参,而被调函数里边的参数叫做形参,当 函数传递时,传递的是值,它们占用的不是同一存储单元,而 且在传递中,是单向传的,由实参传向形参。 ? “传值”与“传址”的区别:传数值的话,形参的变化不 会改变实参的变化。传地址的话,形参的变化就有可能改 变实参所对应的量。 例 1: (10-03-26)有以下程序 #include &stdio.h& void fun(char *c,int d) { *c=*c+1; d=d+1; printf(“%c,%c”,*c,d); } main() { char b=?a?, a=?A?; fun(&b,a); printf((“%c,%c\n”,b,a); } 程序运行后的输出结果是( A) A) b,B,b,A B)b,B,B,A C)a,B,B,a D)a,B,a,B 4、知识点:函数调用的一般形式和调用方式共 78 页 ? 函数调用的一般形式为:函数名(实际参数表) ; 例 1、(06-09-32)若有以下函数首部 实参可以是常数、变量或其他构造类型数据及表达式,也 int fun(double x[10],int *n) 可以没有(当为无参函数时) 则下面针对此函数声母语句中正确的是(D) ? 函数调用的方式: A)int fun(double x,int *n); B)int fun(double,int); (1)函数表达式:函数作为表达式中的一项出现在表达式 C)int fun(double*x,int n); D)int fun(double *,int。); 中,以函数返回值参与表达式运算。例如:z=max(x,y); 【解析】本题考点是对函数的声明,在函数声明的时候,其格 (2)函数语句:函数调用的一般形式上加上分号。例如: 式如下:返回值类型函数名(参数类型[参数名],参数类型[参 printf(“%d\n”,a); 数名]??)其中, 参数名可以不写, 但是参数类型一定要写全 (3) 函数实参: 函数作为另一个函数调用的实际参数出现。 ? 省去主调函数中对被调函数的函数说明的几种情况: 例如:printf(“%d”,max(x,y)); (1)被调函数的返回值是整型或字符型时(返回值自动按 ? 程序从 main 函数进入,上往下执行,当碰到函数名后,把 整型处理) 值传给调用函数,当程序得到了返回值或调用函数结束, (2)当被调函数的函数定义在主调函数之前时 再顺序往下执行,最后到 main 函数结束。 (3)在所有函数定义之前,在函数外预先说明了各个函数 5、知识点:函数的声明及其位置 的类型 ? 函数要“先定义后调用” ,或“先声明再调用后定义” 。函 例 2: (10-09-24)有以下程序 数的声明一定要有函数名、函数返回值类型、函数参数类 #include &stdio.h& 型,但不一定要有形参的名称。 int f(int x); 一般形式为: main() 类型说明符 被调函数名(类型 形参,类型 形参…); { int n=1,m; 或 类型说明符 被调函数名(类型,类型…); m=f(f(f(n))); printf(“%d\n”,m); 注意:其末尾“; ”不能省 } 例如:int max(int a,int b); 或 int max(int ,int); 两者 int f(int x) 功能相同 { return x*2;}第 47 页 共 78 页 程序运行的输出结果( D ) A) 1 B)2 C)4 D)8 【解析】 f 函数定义在 main 下面, 但在外部进行声明 int f(int x); 因此在 main 中可直接调用。 三 次 调 用 函 数 :f(n)=f(1)=2 f(2)=4 f(4)=8 m=f(f(f(n)))=f(f(f(1)))=f(f(2))=f(4)=8答 案 : double avg(double ,double );avg(doublea,doubleb);或double【解析】 当函数定义在调用之后, 调用前必须对函数进行申明, 申明的形式和函数定义中的函数头部分相同,最后加分号即例 3: (11-03-12)有以下程序,请在 【12】 处填写正确语句, 可。 使程序可正常编译运行。 【12】; main() { double x,y,(*p)(); scanf(&%lf%lf&,&x,&y); p= printf(&%f\n&,(*p)(x,y)); } double avg(double a,double b) { return((a+b)/2);}第 48 页6、知识点:函数的嵌套调用 ? C 语言中不允许作嵌套的函数定义,但是允许在一个函数 的断定仪中出现对另一个函数的调用,即嵌套调用。 例 1: (06-04-33)有以下程序 int funl(double a){return a*=a;} int fun2(double x,double y) {double a=0,b=0; a=funl(x);b=funl(y);return (int)(a+b); } main() {double w;w=fun2(1.1,2.0);??} 程序执行后变量 w 中的值是( C ) A)5.2l B)5 C)5.0 D)0.0 【解析】此题考查函数的嵌套调用。main 函数中调用了 fun2 函 数 ; fun2 函 数 中 又 调 用 了 如 fun1 函 数共 78 页 w=fun2(1.1,2.0)--&w=(int)(funl(1.1)+funl(2.0))?w=(int)5.21 ; w 值为 5,但是 w 是 double 类型变量,故将 5 转换成 5.0 赋值 给变量 w 例 2、 (09-3-24)有以下程序 #include&stdio.h& int f(int x,int y) {return ((y-x)*x);} main() { int a=3,b=4,c=5,d; d=f(f(a,b),f(a,c)); printf(“%d\n”,d); } 程序运行后的输出结果是( B ) A) 10 B)9 C)8 D)7 【解析】程序的 main()函数中,定义了 4 个变量,前 3 个分别 初始化,D 用来接收调用函数后返回的值,主函数一共调用了 3 次 f()函数,第一次传递 a,b 的值,给形参 x,y,返回(y-x) *x 的值为 3,第二次将 a,c 的值传递给形参 x,y,返回(y-x) *x 的值为 6,接着将 f(a,b) ,f(a,c)的值 3、6 传递给形参,执 行后返回值 9,赋值变量 d,最后输出结果为 9 7、知识点:函数的递归调用 ? 函数直接或间接地调用自己称为函数的递归调用。递归调 用必须有一个明确的结束递归的条件。在做递归题时可把 递归的步骤一步步写下来,不要弄颠倒了。第 49 页例 1、(04-09-37)在函数调用过程中,如果函数 funA 调用 了函数 funB,函数 funB 又调用了函数 funA,则 ( B ) A)称为函数的直接递归调用 B)称为函数的间接递归调用 C)称为函数的循环调用 D)C 语言中不允许这样的递归调用 【解析】此题考查函数递归的基本概念。一个函数直接或间接 调用自己称为函数的递归调用;若直接调用了自己,则称为直 接递归调用,若间接调用了自己则称为间接递归调用;根据间 接递归调用的概念可知,本题中的函数调用为间接递归调用。 例 2、 (09-09-15) #include &stdio.h& fun(int x) { if(x/2&0) fun(x/2); printf(“%d ”,x); } main() { fun(6); printf(“\n”);} 程序运行后的输出结果是 __1 3 6______ 【解析】程序的执行过程是先递推、后递归的过程。当 x=1 时,条件不成立,递推终止。程序执行流程参照示意图。共 78 页 else return 0;x=6 main() fun(6) printf(\n) fun(3) printf(6) x=3 fun(1) printf(1) printf(3) x=1}程序运行后的输出结果是( B) A) 4 【 B) 10 解 C)14 D)6 析 】s=f(a,4)=t[3]+f(a,3)=4+f(a,3)=4+t[2]+f(a,2)=4+3+f(a,2)=7+t[1]+f (a,1) =7+2+f(a,1)=9+t[0]+f(a,0)=9+1+f(a,0)=10+0=10例 3: (10-03-33)有以下程序 例 4: (11-03-32)设有如下函数定义 #include &stdio.h& int fun(int k) int f(int t[],int n); { main() else if(k==1) return 1; { int a[4]={1,2,3,4},s; else return fun(k-1)+1; s=f(a,4); printf(“%d\n”,s); }若执行调用语句:n=fun(3);,则函数 fun 总共被调用的次数 } 是( B) int f(int t[],int n) A)2 { if(n&0) return t=[n-1]+f(t,n-1);第 50 页 共 78 页if (k&1) return 0;B)3C)4 D)5【解析】 函数递归调用, fun(8,fun(5,6)),其中 fun(5,6)因为 5!=6,【解析】递归调用,fun(3)―& fun(2)―& fun(1) ;fun(1)―1―& return ((x+y)/2)为 5, 所以 fun(8,fun(5,6))为 fun(8,5), 8!=5, return fun(2)―2―& fun(3)―3―&n; 所以 fun 总共被调用的次数是 3, ((x+y)/2)为 6 最后 n 为 3。 例 5: (11-03-34)有以下程序 int fun (int x,int y) { if (x!=y) return ((x+y)/2); else return (x); } main() { int a=4,b=5,c=6; printf(&%d\n&,fun(2*a,fun(b,c))); }程序运行后的输出结果是( B) A)3 D)12 B)6 8、知识点:局部变量和全局变量 ? 在一个函数内部或复合语句内部定义的变量,它只在本函 数范围内有效,也就是说只有在本函数内才能使用它们, 在函数以外是不能使用这些变量的。这称为局部变量,局 部变量又称为内部变量。函数的形参也属于局部变量。 ? 在函数外部定义的变量,称为全局变量,又称为外部变量。 全局变量可以被本文件的其他函数所共用。 例 1、(07-09-40)在一个 C 语言源程序文件中所定义的全局变 量,其作用域为(D) A)所在文件的全部范围 B)所在程序的全部范围 C)所在函数的全部范围 D)由具体定义位置和 extem 说 明来决定范围 【解析】 本题考点是全局变量的作用域, 全局变量的作用域是, 从变量定义开始,一直到程序程结束为止,当然,也可以在其 它文件中用这个以定义的全局变是, 但是要通过 extern 来进行 C)8 声明,本题答案选 D。 例 2、(09-09-11)有以下程序 #include&stdio.h&第 51 页 共 78 页 int a=5; void fun(int b) { int a=10; a+=b; printf(“%d”,a) } main() { int c=20; fun(c); a+=c; printf(“%d\n”,a); }程序运行后的输出结果是____3025____ 【解析】全局变量的作用域为定义开始到文件结束。局部变量 的作用域为定义其函数内部。当局部变量与全部变量同名时, 在局部变量作用域内,全部变量不起作用。 执行函数 fun(c): 实参 c 将值传给形参 b,即 b=20,函数内部 定义局部变量 a 起作用,a=10,a+=b a=a+b=10+20=30,输出 a 的值为 30 返回到主函数: a+=c 此 时 a 为 全 局 变 量 的 值 a=a+c=5+20=25 输出 a 值 25 注意格式控制符无空格,所以连续输出(1)在编译时分配存储空间,所占存储单元直到程序结束时 才释放,它的值在程序运行过程中一直存在,且变量的初始化 只进行一次。 (2) static 说明符可以用于全局变量, 也可用于局部变量 (auto 和 resgiter 不可以定义全局变量)但是,当它说明变量后,只 要这个变量还在程序中存在,那么不管用到还是没有用到,它 都将会占用内存单元。 例 1: (10-09-36)有以下程序: #include &stdio.h& int f() { static int x=1; x+=1; } main() { int i,s=1; for(i=1;i&=5;i++) s+=fun(); printf(“%d\n”,s); } 程序运行后的输出结果是( B) A)11 B)21 C)6 D)120 9 知识点:变量存储类别(auto 变量、register 变量、static 【解析】fun 函数被调用了 5 次,每次调用后的值返回值累加 到 s 上。 变量) 第 一 次 : 静 态 局 部 变 量 定 义 有 效 , x=2, 返 回 值 为 2 。 s=s+fun()=1+2=3;从第 2 次调用开始,静态局部变量的定义相 ? 静态变量(static) :第 52 页 共 78 页 当于不存在,直接使用 x 的值。 第二次:x=3 s=3+3=6 第三次:x=4 s=6+4=10 第四次:x=5 s=10+5=15 第五次:x=6 s=15+6=21 例 2: (11-03-34)有以下程序 int fun() { static int x=1;而且只初始化一次。所以第一次调用后,x 的值为 2,返回后 s 的值为 2,第二次调用后,x 的值为 2*2=4,返回后 s 的值为 2*4=8 ,第三次调用后, x 的值为 4*2=8 ,返回后 s 的值为 8*8=64,故选 D。? 自动变量(auto) (1)自动变量的存储空间是当程序执行到定义它的函数或语 x*=2; 句块时才分配, 当函数执行结束后自动释放, 变量的值也就不 再存在。 (2)局部变量的存储类别默认为 auto,可以省略不写,但它 } 不能定义全局变量。 ? 寄存器变量(register) : main() 例 1、(08-04-39)在 C 语言中,只有在使用时才占用内存单元 { int i,s=1; 的变量,其存储类型是( A ) 。 A)auto 和 register B)extern 和 register C)auto 和 static for(i=1;i&=3;i++) s*=fun(); D)static 和 register 【解析】auto 变量在进入函数体时,系统为其分配存储单元, printf(&%d\n&,s); 退出时自动释放; register 是建议编译程序将变量的值保存在 }程序运行后的输出结果是(D) cpu 的寄存器中,而不是占用内存单元;extern 可以对全局变 量加以说明,扩展其作用域,在整个程序中都有效,所以会一 A)0 B)10 C)30 D)64 直占用内存单元;static 说明符可以用于全局变量,也可用于 【解析】 静态变量 static 类型, 在函数执行完后空间并不释放, 局部变量,使变量在整个程序执行期间一直占用内存单元,本第 53 页 共 78 页 题答案选 A。 sqrt(fbs(pow(n,x)+pow(x,e))) 例 2: (10-09-34)设函数中有整形变量 n,为保证其在未赋初 C)sqrt(fabs(pow(n,x)+exp(x,e))) 值的情况下初值为 0,应该选择的存储类别是( C ) D)sqrt(fabs(pow(x,n)+exp(x))) A)auto B)register C)static D)auto 或 【解析】exp()函数的功能是返回以自然数 e 为底、函数参数 register x 为幂的指数值pow(n,x)函数是计算 nx ;fabs()函数的功 【解析】 对于静态局部变量(static), 如在定义时不赋初值的话, 能是返回函数参数的绝对值;sqrt()用于返回函数参数的平方 编译时自动赋初值 0 (对数值型变量) 或空字符 (对字符变量) 。 根。所以正确答案为 C。 而对于自动变量(auto 或者缺省不写) ,如果不赋初值则它的 例 2:以下说法不正确的是(B) 值是一个不正确的值。 A)标准库函数按分类在不同的头文件中声明 B)用户可以重新定义标准库函数 10、内部函数与外部函数 C)系统不允许用户重新定义标准库函数 ? 用 static 进行说明的函数称为静态函数,也叫内部函数。 D)用户若需要调用标准库函数,调用前必须使用预编译命令 静态函数只能被本编译单元体内的函数调用。一般形式: 将该函数所在文件包括到用户源文件中 static 类型标识符 函数名(形参表) 例如: static int 【解析】对每一类库函数,都有相应的头文件名,调用某个 fun(){…} 库函数时, 用户在源程序中须用 include 命令包含其头文件名。 11、知识点:库函数 每一类标准库函数是 C 语言本身提供的,用户不能重新定义 ? 函数可以分为库函数和用户自定义函数。库函数由 C 系统 标准库函数。 提供,用户无须定义,在调用 C 语言标准库函数时要包含 12、知识点:数组与函数 include 命令,include 命令行以#开头; ? 数组用作函数参数有两种形式:把数组元素(下标变量) 例 1、 (07-04-17)若有代数式 | n x ? e x | (其中 e 仅代表自然对数 作为实参使用和把数组名作为函数的形参和实参使用。 的底数,不是变量),则以下能够正确表示该代数式的 C 语言 ? 数组元素作函数的实参与普通变量并无区别,所进行的传 表达式是( C) 递是值,形参变量和实参变量占据由编译系统分配的两个 A)sqrt(abs(nx+ex)) B) 不同的内存单元;第 54 页 共 78 页 ? 数组名作为函数参数时,所进行的传递是地址(相当于把 } 实参数组的首地址赋予形参数组名或指针名) , 形参数组与 答案:i-1 实参数组为同一数组,共同拥有一段内存单元; 例 1: ()以下程序的主函数中调用了在其前面定义 【解析】a[i]的值赋给 a[i-1] 的 fun 函数 例 2: (10-09-32)有以下程序 #include&stdio.h& #include &stdio.h& main() #define N 8 {double a[15],k; void fun(int *x,int i) k=fun(a); { *x=*(x+i); } }则以下选项中错误的 fun 函数首部是 ( D) A.double fun(double a[15]) B.double fun(double *a) main() { int a[N]={1,2,3,4,5,6,7,8},i; C.double fun(double a[]) D.double fun(double a) fun(a,2); 【解析】当一维数组名 a 作为实参时,对应形参有三种表示形 for(i=0;i&N/2;i++) 式:*a、a[ ]、a[N]( 注:N 为定义 a 数组时的元素个数) { printf(“%d”,a[i]);} 例 1: (11-03-11)己知 a 所指的数组中有 N 个元素。函数 fun printf(“\n”); 的功能是, 将下标 k(k&0)开始的后续元素全部向前移动一个位 }程序运行后的输出结果是( C ) A) 1 3 1 3 B)2 2 3 4 C) 3 2 3 4 D) 置。请填空。 1 2 3 4 【解析】数组名代表数组首地址,即 a[0]的地址。函数调用: Void fun(int a[N],int k) fun(a,2) 参数传递后,形参指针 x 获得数组首地址,即指向 { a[0],形参变量 i=2;*x 即为 a[0],*(x+2)即 a[2],*x=*(x+2)相 当于 a[0]=a[2],a[0]变为 3,a[2]不变。返回到主程序:循环 4 for(i=k;i&N;i++) a[【11】] = a[i]; 次,输出 a 数组前 4 个元素: 3 2 3 4第 55 页 共 78 页 例 3: (10-09-25)有以下程序 #include &stdio.h& void fun(char *s) { while (*s) {if (*s%2==0) printf(“%c”,*s); s++;} } main() { char a[]={“good”}; fun(a);printf(“\n”); }注意:字母 a 的 ASCII 码值为 97,程序运行后的输出结果是 ( A ) A) d B)go C)god D)good 【解析】调用 fun(a)函数,实参字符数组名 a 传递给形参字符 指针 s,使 s 指向字符串“good” ;在函数 fun 中对字符串进行 遍历,如果指针 s 指向字符 ASCII 码值是偶数则输出该字符。 在字符串“good”中,只有“d”的 ASCII 码值为偶数不能少 例 1: (09-09-33)设有以下函数: void fun(int n,char *s){…} 则下面对函数指针的定义和赋值 均正确的是( A ) A)void (*pf)(); pf= B)void *pf(); pf= C)void *pf(); *pf= D)void (*pf)(int,char);pf=& 【解析】本题考点为指向函数的指针的用法。函数名代表函数 的入口地址,可以赋值给指向函数的指针。指向函数的指针应 该定义为 void (*pf)().如定义为 void *pf(),则表示函数 pf 返回值为一个基类型为 void 的指针。 ? 函数指针变量不能进行算术运算。 ? 指针型函数是指返回指针值的函数。定义的一般形式为: 类型说明符 *函数名(形参表){…} 例如:int *ap(int r &n x,int y){} 例 1:(10-09-11)有以下程序 #include &stdio.h & m=1 n=2 13 指针与函数 int *f(int *p,int *q) ? 函数指针变量是指向函数的指针变量。 main() 定义的一般形式为 : 类型说明符 ( * 指针变量名) (); p q { int m=1,n=2,*r=&m; 例如: int (*pf)(); r=f(r,&n) ; printf(”%d\n”,*r) ; 调用函数的一般形式: (*指针变量名) (实参表) 例如: } z=(*p)(x,y); int *f(int *p,int *q) ?注: (*指针变量名)中的“()”第 56 页 共 78 页 { return (*p&*q) ?p :} 程序运行后的输出结果是______2_____ 【解析】本题中 f 是个指针型函数,返回值为指针值。如示意 图。主程序中,指针 r 指向 m,函数调用 f(r,&n)时,实参传递 给形参,形参指针 p 指向 m,指针 q 指向 n,*p 的值为 m 的 值 1,*q 的值为 n 的值 2,所以函数返回值为 q,返回给主程 序中的指针 r,即指针 r 指向了 n,最后输出*r 的值为 n 的值 2. 例 2:(11-03-29)有以下程序 void fun(char *c) { while(*c) { if(*c&=?a?&&*c&=?z?) *c=*c-(?a?-?A?); c++; } } main() { char s[81];gets(s); fun(s); puts(s): }当执行程序时从键盘上输入 Hello Beijing&回车&,则程序的 输出结果是( C ) A)hello beijing D)hELLO Beijing 【解析】gets(s)将输入的 Hello Beijing 赋给了字符数组 s,调 用 fun(s),将字符数组 s 的首地址传给了 c,c 指向的即为字符 数组的首地址, 通过指针变量 c 取得字符数组中的字符判断是 不是小写字母,如果是变成大写字母。 *c=*c-(?a?-?A?)完成小 写换大写的功能。故选 C。另外注意 gets(s)和 scanf(“%s”,s); 的区别:scanf 以空格作为字符串输入结束的标志,而 gets(s) 不需要 B)Hello Beijing C)HELLO BEIJING第五课 结构体、链表与共用体第 57 页 共 78 页 本课重要知识点:第 58 页1.知识点:用 typedef 定义类型共 78 页 ? 功能:为已有数据类型取别名 ? 类型

我要回帖

更多关于 计算机二级考试资料 的文章

 

随机推荐