练习错题
题目一:
关于C语言关键字说法正确的是:( )
A.关键字可以自己创建
B.关键字不能自己创建
C.关键字可以做变量名
D.typedef不是关键字
正确答案:B
答案解析:
C语言关键字:C语言定义的,具有特定含义、专门用于特殊用途的C语言标识符,也 称为保留字
A:错误,关键字是语言自身定义的
B:正确
C:错误,关键字具有特殊含义,不能作为变量名
D:错误,typedef是用来给类型取别名的关键字
老师点评:
关键字是语言自身自带的,不能由人去创建
关键字不可以做变量名、函数名、
typedef是取别名的关键字
题目二:
关于C语言变量说法错误的是?
A.变量是用来描述生活中经常发生变化的值
B.变量可以分为局部变量和全局变量
C.局部变量是放在内存的静态区的,全局变量是放在内存的栈区
D.当全局变量和局部变量名字相同的情况,且都可以使用的时候,局部变量优先
正确答案:C
答案解析:
局部变量是放在内存的栈区的,全局变量是放在内存的静态区
老师点评:
变量是用来描述变化的值的,变量可以保存值,其保存的值可以被改变,
变量可根据作用域的不同分为局部变量和全局变量,局部变量存在栈区,全局变量存在静态区
当一个变量分别有局部和全局时,采用就近原则,也就是局部优先
综上,本题C选项错误
题目三:
关于关系操作符说法错误的是?
A. C语言的关系操作符就是用来比较大小关系的
B. 关系操作符中判断是否相等使用==
C. ==操作符可以用来比较2个字符串是否相等
D. 关系操作符参与的关系表达式,通常返回0或1,表示真假
正确答案:C
老师点评:
答案解析:
两个字符串是否相等不能使用==,应该使用strcmp函数
题目四:
关于switch说法不正确的是:( )
A. switch语句中的default子句可以放在任意位置
B. switch语句中case后的表达式只能是整形常量表达式
C. switch语句中case子句必须在default子句之前
D. switch语句中case表达式不要求顺序
正确答案:C
答案解析:
A:正确,可以放在任意位置,但是一般建议最好还是放在最后
B:正确,case语句后一般放整形结果的常量表达式或者枚举类型,枚举类型也可以看成是一个特殊的常量
C:错误,没有规定case必须在default之前,一般case最好放在default之前
D:正确,但一般还是按照次序来
因此:选择C
老师点评:
题目五:
以下叙述中不正确的是:( )
A. 在不同的函数中可以使用相同名字的变量
B. 函数中的形式参数是在栈中保存
C. 在一个函数内定义的变量只在本函数范围内有效
D. 在一个函数内复合语句中定义的变量在本函数范围内有效(复合语句指函数中的成对括号构成的代码)
正确答案:D
答案解析:
A:正确 不同的函数属于不同的作用域,因此不同的函数中定义相同名字的变量不会冲突
B:正确 在C语言中,函数的形参一般都是通过参数压栈的方式传递的
C:正确 在函数内定义的变量,称为局部变量,局部变量只能在其定义的函数中使用
D:错误 复合语句中定义的变量只能在复合语句中使用
因此:选择D
老师点评:
题目六:
在C语言中,以下哪个选项描述了变长数组(Variable Length Array,VLA)的特点?
A. 变长数组的大小在编译时确定,不能改变。
B. 变长数组的大小可能在运行时确定,比如使用变量来指定数组大小,一旦确定大小后,它的大小是固定的,无法改变。
C. 一旦确定大小后,它的大小是固定的,无法改变
D. 变长数组只能用于存储字符类型的数据。
正确答案:C
答案解析:
变长数组( variable-length array),C语言术语,也简称VLA。是指用 整型变量或表达式声明或定义的数组 ,而不是说数组的长度会随时变化,变长数组在其生存期内的长度同样是固定的 。
代码示例:
int n; scanf ("%d", &n); int array[n];
注意上述语法在C99之前是不支持的。
A选项错误:编译时无法确定,编译时候编译器不知道n是什么值,n的值要等到程序运行起来后,用户输入之后n的值确定了,才能确定数组的大小
B选项:说法不严谨,一定是在运行时确定大小的,而不是可能
C选项正确
D选项错误:存储什么类型数据,看定义时候给数组名前放什么类型,比如int a[n]就是存放int类型 short a[n]就是存在short类型
老师点评:
题目七:
关于C语言函数描述正确的是:( )
A. 函数必须有参数和返回值
B. 函数的实参只能是变量
C. 库函数的使用必须要包含对应的头文件
D. 有了库函数就不需要自定函数了
正确答案:C
答案解析:
A:错误,可以没有参数和返回值类型,根据具体功能实现
B:错误,函数的实参可能是变量,也可能是常量,也可能是宏,也可能是指针等等
C:正确,在使用库函数时,必须要包含该库函数所在的头文件,否则编译器将不能识别
D:错误,库函数是语言设计者为了让用户能够更好的使用,而给出的,但并不能解决用户的所有问题,因此其他问题还需要用户自己写方法解决
老师点评:
试卷错题(总结)
1、算术运算符、赋值运算符、关系运算符 的运算优先级从高到抵依次为:算术运算、关系运算、赋值运算。(注:赋值运算优先级最低)
2、逻辑运算符,运算优先级从高到低一次为: !&& ||
3、z=(2, 3, 4) (整个是赋值表达式) 这个时候 z 的值为 4。
z= 2, 3, 4 (整个是逗号表达式)这个时候 z 的值为 2。
例题:1)下面表达式中,正确的C赋值表达式是:(C)
A、a = 7 + b + c = a + 7
B、a = 7 + b++ = a + 7
C、a = (7 + b, b++, a + 7)
D、a = 7 + b, c = a + 7
2)设 f 是实型变量,下面表达式中不是逗号表达式的是:(D)
A、f = 3.2, 1.0;
B、f > 0, f < 10
C、f = 2.0, f > 0;
D、f = (3.2, 1.0);
注:(3.2,1.0)这个是逗号表达式
但 f = (3.2, 1.0); 这个整体是赋值表达式
以下是我对逗号表达式知识点的理解。(如有不对,欢迎讨论)
4、C语言中有符号数据类型(signed)和无符号数据类型(unsigned)的本质区别:signed最高位为符号位,unsigned全部为数值位
5、b == a = 2; 会出现报错,表达式必须是可修改的左值
6、求解逗号表达式 x = a = 3, 6 * a; 表达式值、x、a 的值依次为:18、3、3
注:逗号表达式的值是整个表达式最右边的值,而x、a的值是通过赋值表达式进行赋值的。
7、C语言中逻辑真是用 非0 表示,逻辑假用 0 表示。
8、以下叙述错误的是:C
A、对于double类型的数组,不可以直接用数组名对数组进行整体输入或输出
B、数组名代表的是数组所占存储区的首地址,其值不可改变
C、当程序执行时,数组元素的下标超出所定义的下标范围时,系统将给出“下表越界”的出错信息
D、可以通过赋初值的方式确定数组元素的个数
解析:答案选C。因为系统不会报错。对于A,double类型数组指的是小数组成的数组,而通过%s使用数组名打印是打印字符串,因此对于double类型数组,不可以直接用数组名对数组进行整体输入或输出。
9、有以下程序,执行的输出结果是 D
main()
{
char s[] = "abcde";
s += 2;
printf("%d\n", s[0]);
}
A、输出字符a的ASCII码值
B、输出字符c的ASCII码值
C、输出字符c
D、程序出错
解析:答案为D 整体程序出错的原因是
s 是数组名,是一个指针常量。
10、字符数组并不要求它的最后一个字符为’\0’,甚至可以不包含’\0’,向下面这样写是完全合法的。 char str[5]={‘C’,‘h’,‘i’,‘n’,‘a’};
对字符数组,有以下几种定义方法:
-
char str[]="12345";
或给字符串加上大括号:char str[]={“12345”};
这种方法定义时,系统会自动在字符串的末尾加上字符串结束符,即 ‘\0’,
-
char str[10]={'1','2','3','4','5'};
这种方法定义时,系统会自动从未初始化的元素开始,将之后的元素赋为\0,如上面的数组str中的元素实际上是:‘1’,‘2’,‘3’,‘4’,‘5’,’\0’,’\0’,’\0’,’\0’,’\0’
-
char str[]={'1','2','3','4','5'};
这种方法定义时,系统不会自动在字符串的末尾加上字符串结束符;
11、定义一个字符指针数组,改数组有4个元素,对该指针数组的第一个元素进行内存分配,分配空间为100bytes
解析:
char *ch[4];
ch[0] = (char *)malloc(100);
注意:强制转换
12、
char *p = NULL;
指针定义为NULL,意味着不能对这个指针进行解引用操作,会出现段错误。
13、不能对未初始化的指针进行赋值操作。(初始化:指针=NULL)
14、无符号和有符号运算,有符号会先转成无符号,再和无符号进行运算。
15、
若有以下定义和语句,则对s数组元素的正确引用形式是()C
int s[4][5], (*ps)[5];
ps = s;
A 、ps+1 B、*(ps+3) C、ps[0][2] D、*(ps+1)+3
16、如果最常用的操作是取第i个节点及其前驱,则采用()存储方式最节省时间。D
A、单链表 B、双链表 C、单循环链表 D、顺序表
17、若用一个大小为6的数组来实现循环队列,且当前rear和front的值分别0和3。当从队列中删除一个元素,再加入两 个元素后,rear和front的值分别为()B
A、1和5 B、2和4 C、4和2 D、5和1
18、在栈中,栈顶指针的动态变化决定栈中元素的个数。
19、设栈S和队列Q的初始状态为空,元素e1、e2、e3、e4、e5、e6依次通过栈S,一个元素出栈后即进入队列Q,若6个元素出队的序列是e2、e4、e3、e6、e5、e1,则栈S的容量至少应该是:(3)
20、在一个长度为n(n>1)的单链表中,设有头和尾指针,执行(删除单链表中的最后一个元素)操作与链表的长度有关。
21、线性表采用顺序存储时,其地址(必须是连续的)。
22、对于链表,预先未知表中元素的多少时宜采用链表,插入和删除操作方便,无需采用连续的存储空间进行数据存储。
23、不含任何节点的空树是一棵树也是一棵二叉树
24、若一棵二叉树具有10个度为2的节点,5个度为1的节点,则度为0的节点个数为(11)。
二叉树性质n0 = n2 + 1
25、关键字static的作用
1、限制变量的作用域 2、设置变量的存储域
26 、什么是平衡二叉树
平衡二叉树也叫AVL树,它或者是一颗空树,或者具有以下性质的二叉排序树:它的左子树和左子树的高度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
27、
下面test函数设计正确的是:( )BD
char* arr[5] = {"hello", "bit"};
test(arr);
A. void test(char* arr);
B. void test(char** arr);
C. void test(char arr[5]);
D. void test(char* arr[5]);
解析:指针的数组传递给子函数变为指针的指针,也就是二级指针。但是允许中括号写法,写成char **arr、char *arr[]、char * arr[5]都可。所以BD正确。
28、
下面代码中print_arr函数参数设计哪个是正确的?( )C
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10}; print_arr(arr, 3, 5);
A. void print_arr(int arr[][],int row, int col);
B. void print_arr(int* arr, int row, int col);
C. void print_arr(int (*arr)[5], int row, int col);
D. void print_arr(int (*arr)[3], int row, int col);
解析:二维数组相当于数组的数组,传到子函数变成数组的指针。int arr[3][5]相当于是3个元素的arr,每个元素是int [5],所以int [5]是类型说明不能省略。丢失的信息只有数组的元素个数,也就是3。A丢了类型中的5,B选项指针层级都错了,D选项5写成了3,故选C。