一、选择题,可多选(每题3分,共12分)
1、从完成C源文件编辑后,到执行程序前,需要进过那些步骤( )
A、编译,运行
B、编译,链接
C、链接,运行
D、预编译,编译
2、下面哪些是标准C语言中的保留字(关键字) ( )
A、do
B、new
C、auto
D、default
E、foreach
F、union
G、NULL
3、存在字符数组char name[] = "This name is";以下哪些语句能在屏幕上输出"is"字串( )
A、printf("%s", name + 2);
B、printf("%s", &name[2]);
C、printf("%s", *(name + 2));
D、printf("%s", name+10);
E、printf("%s", &name[10]);
F、printf("%s", *(name + 10));
4、存在函数 char* strcpy(char* src, char* des), 以下对函数指针赋值的语句,哪些是是正确的( )
A、char* (*p) () = strcpy(src, des);
B、char* (*p) = strcpy();
C、char* (*p)(char*,char*) = strcpy;
D、char* (*p) = *strcpy;
二、填空题(共12分)
1、在GB2312-80标准中,一个汉字由_______个字节组成,按bit计算,由______bit组成。
2、在标准C语言中,#define negate(num) !num
int i = 2*negate(3-3); i的值是_________。
3、在VC6.0环境中,char *p = "double";
sizeof(double)的值为_____;sizeof("double")的值为_______;sizeof(p)的值为______。
三、找错题,请找出程序中存在的问题,或潜在的问题,说明原因并修正。(每题9分,共18分)
1、本程序判断输入的年份是否为闰年,是闰年,显示nnnn"是闰年;不是闰年,显示nnnn"非闰年。其中nnnn表示输入的年份。
提示:判断是闰年的条件,(1).若年份后两位不是00,且能被4整除,则为闰年;(2).若年份后两位是00,且年份前2位能被4整除,则为闰年。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned short year;
char s_year[4];
if(argc < 2)
{
printf("请在参数中输入年份\n");
return -1;
}
if(strlen(argv[1]) != 4)
{
printf("年份长度错误\n");
return -1;
}
strcpy(s_year, argv[1]);
year = atoi(s_year);
switch(!(year % 400) || !(year & 3) && year % 100)
{
case 0:
printf("%d"非闰年\n",year);
default:
printf("%d"是闰年\n",year);
}
return 0;
}
2、以下程序实现了对int型数组排序的函数sort,并写了测试程序。
#include <stdio.h>
void sort(int *datas,int count)
{
int i,j;
int temp;
for(i = 0, i < count, i++)
{
for(j = i + 1, j < count-1, j++)
{
if(datas + i < datas + j)
temp = datas + i;
datas + i = datas + j;
datas + j = temp;
}
}
}
int main(int argc, char *argv[])
{
int ints[6] = {5, 1, 8, 6, 2, 9};
sort(ints, 6);
return 0;
}
当我手动录完这份题目的时候,我都疑问,我当时答了个什么玩意儿????
只有代码在屏幕上的时候我才知道它写了些什么玩意儿!!如果按答题选人,大概凉了吧,哈哈!
公布下答案:
一、选择题
1、答案 B
解释:编译器是把源代码转换成可执行代码的程序。可执行代码 是用计算机的机器语言表示的代码。这种语言由数字码表示的指令组成。如前所述,不同的计算机使用不同的机器语言方案。C 编译器负责把C代码翻译成特定的机器语言。此外,C编译器还将源代码与C库(库中包含大量的标准函数供用户使用,如printf()和scanf())的代码合并成最终的程序(更精 确地说,应该是由一个被称为链接器的程序来链接库函数,但是在大多数系 统中,编译器运行链接器)。其结果是,生成一个用户可以运行的可执行文件,其中包含着计算机能理解的代码。——《C Primer Plus 第6版 中文版》
2、答案 A C D F
解释:关键字是C语言的词汇。它们对C而言比较特殊,不能用它们作为标识 符(如,变量名)。许多关键字用于指定不同的类型,如 int。还有一些关 键字(如,if)用于控制程序中语句的执行顺序。在表 2.2 中所列的C语言关 键字中,粗体表示的是C90标准新增的关键字,斜体表示的C99标准新增的 关键字,粗斜体表示的是C11标准新增的关键字。
如果使用关键字不当(如,用关键字作为变量名),编译器会将其视为 语法错误。还有一些保留标识符(reserved identifier),C语言已经指定了它 们的用途或保留它们的使用权,如果你使用这些标识符来表示其他意思会导 致一些问题。因此,尽管它们也是有效的名称,不会引起语法错误,也不能 随便使用。保留标识符包括那些以下划线字符开头的标识符和标准库函数 名,如printf()。——《C Primer Plus 第6版 中文版》
3、D E
考点:
(1)字符串在内存中的存储方式,结尾为\0,即0x00。(这个很重要,掉坑了)
(2)数组名做指针
(3)获取数组元素的地址
(4)printf函数格式化输出应用,对输入格式(转换说明)的理解
(5)获取指针指向对象的值
解释:
A:name 指向数组首个元素的地址,+2偏移至 "This name is"字符串 "This" 中i所在的地址。%s转换说明,因为没有限制输出长度,所以会从is开始输出,直至字符串结尾。注意字符串结尾是\0而不是 空格 。我当时竟然搞错了。哇.....
B:取数组的第二个元素的地址,最终结果与A相同。
C:对指向数组第二个元素的指针取值,即数组第二个元素。此语句执行会出错误。修改为printf("%c", *(name + 2));可执行。
D E F与A B C意义相同。D E可得到所需结果。
迷惑答案,AB,空格不是\0,说多都是泪,T=T~~。
上机测试结果
4、答案:C
解释:
函数指针的定义方式:
函数返回值类型 (* 指针变量名) (函数参数列表);
二、填空题
1、2 16
解释:参考GB3212编码表
2、-3
解释:在#define中使用参数可以创建外形和作用与函数类似的类函数宏。带有 参数的宏看上去很像函数,因为这样的宏也使用圆括号。类函数宏定义的圆括号中可以有一个或多个参数,随后这些参数出现在替换体中,如图所示。
题中代码预处理后为 int i = 2 *!3 - 3; 结果为 i= -3。
注意:替换体为直接带入替换,若为公式,在带入替换后计算。本题已得出错误答案0。
3、答案:8 7 4
解释:
sizeof(double),double是C与言关键字,在VC6.0中,使用8字节表示一个浮点数。不同的系统类型长度可能不同。
sizeof("double")计算的是字符串"double"的长度,字符串的结尾是\0,因此为7。
sizeof(p)计算的是指针p的长度,因此为4。
三、找错题
1、错误
(1)printf函数中"输出未使用转义字符
(2)switch结构中的case分枝未使用break,会连续打印
考点:
(1)运算符优先级,单目运算>多目运算,逻辑与>逻辑或,因此关于判断闰年部分代码并无错误
(2)转义字符
(3)switch语法
解释:C语言运算符优先级
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
---|---|---|---|---|---|
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | |
() | 圆括号 | (表达式) | |||
. | 成员选择(对象) | 对象.成员名 | |||
-> | 成员选择(指针) | 对象指针->成员名 | |||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
(类型) | 强制类型转换 | (数据类型)表达式 | |||
++ | 自增运算符 | ++变量名 | 单目运算符 | ||
-- | 自减运算符 | --变量名 | 单目运算符 | ||
* | 取值运算符 | *指针变量 | 单目运算符 | ||
& | 取地址运算符 | &变量名 | 单目运算符 | ||
! | 逻辑非运算符 | !表达式 | 单目运算符 | ||
~ | 按位取反运算符 | ~表达式 | 单目运算符 | ||
sizeof | 长度运算符 | sizeof(表达式) | |||
3 | / | 除 | 表达式 / 表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | 双目运算符 | ||
% | 余数(取模) | 整型表达式%整型表达式 | 双目运算符 | ||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | 双目运算符 | ||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | 双目运算符 | ||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | 双目运算符 | ||
< | 小于 | 表达式<表达式 | 双目运算符 | ||
<= | 小于等于 | 表达式<=表达式 | 双目运算符 | ||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | 双目运算符 | ||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | |
/= | 除后赋值 | 变量/=表达式 | |||
*= | 乘后赋值 | 变量*=表达式 | |||
%= | 取模后赋值 | 变量%=表达式 | |||
+= | 加后赋值 | 变量+=表达式 | |||
-= | 减后赋值 | 变量-=表达式 | |||
<<= | 左移后赋值 | 变量<<=表达式 | |||
>>= | 右移后赋值 | 变量>>=表达式 | |||
&= | 按位与后赋值 | 变量&=表达式 | |||
^= | 按位异或后赋值 | 变量^=表达式 | |||
|= | 按位或后赋值 | 变量|=表达式 | |||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 |
思考:题目中存在一些误导,与判断闰年没有关系,考察重点甚至不是运算符优先级的记忆。
正确答案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned short year;
char s_year[4];
if (argc < 2)
{
printf("请在参数中输入年份\n");
return -1;
}
if (strlen(argv[1]) != 4)
{
printf("年份长度错误\n");
return -1;
}
strcpy(s_year, argv[1]);
year = atoi(s_year);
switch (!(year % 400) || !(year & 3) && year % 100)
{
case 0:
printf("%d\"非闰年\n",year);
break;
default:
printf("%d\"是闰年\n",year);
break;
}
while (1)
{
;
}
return 0;
}
运行结果:
2、错误:
(1)for语法错误,for(表达式1;表达式2;表达式3),使用;(分号)风格
(2)for (j = i + 1; j < count -1; j++)语句遍历数组缺少最后一个下标,应修改为for (j = i + 1; j < count; j++)
(3)通过指针操作数据,需使用*运算符得到该指针所指向对象的值
(4)if语句比较数据大小后同时执行以下三条语句:temp = *(datas + i); *(datas + i) = *(datas + j); *(datas + j) = temp;
正确答案:
#include <stdio.h>
void sort(int *datas, int count)
{
int i, j;
int temp;
for (i = 0; i < count; i++)
{
for (j = i + 1; j < count; j++)
{
if (*(datas + i) < *(datas + j))
{
temp = *(datas + i);
*(datas + i) = *(datas + j);
*(datas + j) = temp;
}
}
}
}
int main(int argc, char *argv[])
{
int ints[6] = { 5, 1, 8, 6, 2, 9 };
int i;
sort(ints, 6);
printf("排序结果:");
for (i=0;i<6;i++)
{
printf("%d ",ints[i]);
}
while (1)
{
;
}
return 0;
}
运行结果: