C语言易错知识点总结1

生命周期&作用域

第 1 题(单选题)

题目名称:

局部变量的作用域是:

题目内容:

A .main函数内部

B .整个程序

C .main函数之前

D .局部变量所在的局部范围

答案解析: 

在C语言中,变量分为局部变量和全局变量。

  局部变量:一般将定义在函数中的变量称为局部变量,其只能在函数内部使用。

  全局变量:定义在全局作用域中的变量,即函数外的变量,称之为全局变量,全局变量的生命周期随程序启动而      生,随程序结束而消亡,在任何函数中都可以使用。

注意:全局变量使用起来方便,但为了防止冲突和安全性,尽量避免定义全局变量。

  A:main函数内部定义的局部变量作用域在main函数中,但是其他函数中的局部变量则不在,因此A选项不对。

  B:局部变量作用域在函数内部,全局变量是整个程序,因此B选项不对

  C:main函数之前,是系统做的一些事情,因此也不对

  D:正确,即在函数体内

  因此:选择D

第 2 题(单选题)

题目名称:

字符串的结束标志是:( )

题目内容:

A .是'0'

B .是EOF

C . 是'\0'

D .是空格

答案解析:

C语言规定:以'\0'作为有效字符串的结尾标记

A:错误,是'\0'不是字符0

B:EOF一般用来作为检测文本文件的末尾

C:正确

D:明显错误

因此:选择C

第 3 题(单选题)

题目名称:

下面那个不是转义字符?

题目内容:

A .'\n'

B .'\060'

C .'\q'

D .'\b'

答案解析:

A:'\n' 转义字符,代表换行

B:'\060' 转义字符,060八进制数据,十进制为48,表示ASCII码为48的'0'

C:'\q' 什么都不是

D:'\b' 转义字符,表示退格

因此:选择C

第 4 题(单选题)

题目名称:

下面代码的结果是:( )

#include 
#include 

int main()
{
    char arr[] = {'b', 'i', 't'};
    printf("%d\n", strlen(arr));
	return 0;
}

题目内容:

A .3

B .4

C .随机值

D .5

答案解析:

strlen是用来获取字符串的有效长度的,结尾标记'\0'不包含在内。

strlen获取的规则非常简单:从前往后依次检测,直到遇到'\0'是就终止检测。

而上体中arr是一个字符数组,不是一个有效的字符串,因为后面没有放置'\0',因此strlen在求解时,将有效字符检测完之后,还会继续向后检测,直到遇到'\0'是才终止,因此答案为不确定,就看紧跟在't'之后的第一个'\0'在什么位置。

因此:答案选C

第 5 题(单选题)

题目名称:

下面代码输出的结果是:( )

#include 
int num = 10;
int main()
{
    int num = 1;
    printf("num = %d\n", num);
	return 0;	
}

题目内容:

A . 程序有问题,不能编译

B .输出1

C .输出10

D .输出0 

答案解析:

本题主要考察变量的访问规则,C语言中:

  1. 不允许在同一个作用域中定义多个相同名称的变量

   比如:在一个班级中存在两个名字相同的学生王帅,当老师点王帅回答问题时,那个回答就冲突了

  2. 允许在不同的作用域中定义多个相同名称的变量

   比如:两个班级中各有一个王帅,老师在A班中点王帅回答问题,不会有任何歧义

  3. 不同作用域中定义的变量,在访问时采用就近原则。

   比如:你们村有一个小伙伴名字叫刘德华,那你在你们村喊刘德华时,你们村的刘德华就会跑过来响应你,

      而我们世界级别人见人爱的天王他不会理你,因为距离远听不见,但是两个刘德华可以同时存在这个      世界上,只要不在一个村,就不会冲突。

 根据以上描述可知,对于以上代码:

  1. 全局作用域中的num和main中的num可以同时存在,不会冲突,因为不是同一个作用域

  2. 在main函数中访问num时,采用就近原则,因此访问的是main中的num,相当于将全局作用域中的num屏蔽了

 A:错误:因为两个num不在同一个作用域中,可以通过编译

 B:正确,main中访问的是main中的num,而main函数中的num是1,因此打印1

 C:错误,应该访问main函数中的num,而不是全局作用域中的num

 D:错误,凑选择的

 因此:选择B

第 6 题(单选题)

题目名称:

下面程序的结果是:( )

#include 
#include 
int main()
{
    printf("%d\n", strlen("c:\test\121"));
    return 0;
}

题目内容:

A .7

B .8

C .9

D .10

答案解析:

strlen:获取字符串的有效长度,不包括'\0'

"c:\test\121": 在该字符串中,\t是转移字符,水平制表,跳到下一个tab的位置;而\121表示一个字符,是讲121看做8进制数组,转换为10进制后的81,作业为ASCII码值的字符,即:字符'Q' ,故上述字符串实际为:"c:  esty",只有7个有效字符

因此:选择A

简单数组

第 1 题(单选题)

题目名称:

关于C语言关键字说法正确的是:( )

题目内容:

A .关键字可以自己创建

B .关键字不能自己创建

C .关键字可以做变量名

D .typedef不是关键字

 答案解析:

  C语言关键字:C语言定义的,具有特定含义、专门用于特殊用途的C语言标识符,也称为保留字

  A:错误,关键字是语言自身定义的

  B:正确

  C:错误,关键字具有特殊含义,不能作为变量名

  D:错误,typedef是用来给类型取别名的关键字

  因此,选择B

第 2 题(单选题)

题目名称:

用在switch语言中的关键字不包含哪个?( )

题目内容:

A .continue

B .break

C .default

D .case

 答案解析:

 switch是用来进行多分支选择的语句,一般结构是:  

switch(变量表达式)

  {

    case xx1:

     // ...

     break;

    case xx2

     // ...

     break;

    default:

      // ...

  }  

 

当表达式的内容与某个case后的常量相等后,就执行该case下的语句,break表示该case以后的内容不会执行,如果没有跟break,会继续执行当前case之后的case分支。

  当变量表达式的内容没有与那个case匹配,就会执行default下的内容。

  switch中常用的关键字:case 、break、 default,当然case中语句比较复杂时,可能会用if进行判断。

  continue是用来结束本次循环的,而switch不是循环,因此其中不能使用continue关键字。

  因此:选择A

第 3 题(单选题)

题目名称:

关于数组描述错误的是:

题目内容:

A .数组是一组相同类型元素的集合

B .数组的下标是从1开始的

C .数组的下标是从0开始

D .数组如果初始化,可以不指定数组的大小

答案解析: 

数组的下标是从0开始的。

需要注意的是D:int a[] = {1,2,3},数组可以通过初始化确定大小。

因此:选择B

第 4 题(单选题)

题目名称:

C语言中下面哪个数组的创建错误的:( )

题目内容:

A .int arr[10] = {0}

B .int n = 10; int arr[n] ={0}

C .int arr[] = {1,2,3,4,5,6,7,8,9,0}

D .char ch[10] = "hello bit"

答案解析: 

数组的大小必须是常量

因此:选择B

第 5 题(单选题)

题目名称:

下面哪个不是关键字:( )

题目内容:

A .int

B .struct

C .define

D .continue

答案解析: 

  C语言关键字:C语言定义的,具有特定含义、专门用于特殊用途的C语言标识符,也称为保留字

  define不是关键字,是编译器实现的,用来定义宏的预处理指令,不是C语言中的内容。

  int、struct和continue都是C语言中包含的关键字。

  因此:选择C

指针大小

第 1 题(单选题)

题目名称:

关于static说法不正确的是:( )

题目内容:

A .static可以修饰局部变量

B .static可以修全局变量

C .static修饰的变量不能改变

D .static可以修饰函数

答案解析:  

本题主要考察static的特性

  1. static修饰变量

   a. 函数中局部变量:

      声明周期延长:该变量不随函数结束而结束

      初始化:只在第一次调用该函数时进行初始化

      记忆性:后序调用时,该变量使用前一次函数调用完成之后保存的值

      存储位置:不会存储在栈上,放在数据段

   b. 全局变量

     改变该变量的链接属性,让该变量具有文件作用域,即只能在当前文件中使用

   c. 修饰变量时,没有被初始化时会被自动初始化为0

  2. static修饰函数

   改变该函数的链接属性,让该函数具有文件作用域,即只能在当前文件中使用

  A:正确,原因参考上述注解

  B:正确,原因参考上述注解

  C:错误,const修饰的变量不能改变

  D:正确,原因参考上述注解

  因此:选择C

第 2 题(单选题)

题目名称:

下面代码的结果是什么?( )

#include 
int sum(int a)
{
    int c = 0;
    static int b = 3;
    c += 1;
    b += 2;
    return (a + b + c);
}
int main()
{
    int i;
    int a = 2;
    for (i = 0; i < 5; i++) 
    { 
        printf("%d,", sum(a)); 
    } 
} 

题目内容:

A . 6,8,10,12,14

B .8,10,12,14,16

C .10,12,14,16,18

D .12,14,16,18,20

答案解析:  

本题主要考察static修饰局部变量的特性,static修饰局部变量,该变量不会随函数的结束而消失,并且只在第一次调用时进行初始化,后序调用该函数时,使用的都是上次结束前该变量的值。

  第一次循环:a=2 b=5 c=1 a+b+c=8

  第二次循环:a=2 b=7 c=1 a+b+c=10

  第二次循环:a=2 b=9 c=1 a+b+c=12

  第二次循环:a=2 b=11 c=1 a+b+c=14

  第二次循环:a=2 b=13 c=1 a+b+c=16

  

  因此:选择B

第 3 题(单选题)

题目名称:

关于指针说法正确的是:( )

题目内容:

A .sizeof(char*)大小一定是1

B .指针变量是个变量,用来存放地址

C .指针变量的大小都是4个字节

D .指针不是变量

答案解析:  

本题主要考察指针的相关特性

  A:错误,指针是一种复合数据类型,指针变量内容是一个地址,因此一个指针可以表示该系统的整个地址集合,

   故按照32位编译代码,指针占4个字节,按照64位编译代码,指针占8个字节(注意:不是64位系统一定占8个字  节,关键是要按照64位方式编译)

  B:正确

  C:错误,参考A选项解释

  D:错误,该条描述比较模糊 指针可以认为是一种数据类型,也可以认为是定义出来的指针变量

  因此,选择B

if语句

第 1 题(单选题)

题目名称:

下面代码执行的结果是:( )

#include 

int main()
{
	int i = 0;
	for (i = 0; i<10; i++)
	{
		if (i = 5)
			printf("%d ", i);
	}
	return 0;
}

题目内容:

A .1 2 3 4 5 6 7 8 9 10

B .5 5 5 5 5 5 5 5 5 5

C .死循环的打印5

D .0 1 2 3 4 5 6 7 8 9

答案解析:   

上述代码本来的想法应该是:循环10次,每次循环时如果i==5则打印i的结果。

但if语句中表达式的==写成了赋值,相当于每次循环尽量都是将i的值设置成了5,5为真,因此每次都会打印5

i每次修改成5打印后,i的值永远不会等于10,因此造成死循环

故:死循环的打印5

因此:选择C

第 2 题(单选题)

题目名称:

关于if语句说法正确是:( )

题目内容:

A .if语句后面只能跟一条语句

B .if语句中0表示假,1表示真

C .if语句是一种分支语句,可以实现单分支,也可以实现多分支

D .else语句总是和它的对齐的if语句匹配

答案解析:   

 A:错误,if之后可以跟多条语句,跟多条语句时需要使用{}括起来

  B:错误,0表示假,非零表示真

  C:正确

  D:不一定,要看具体的代码,如果代码不规范,可能没有对齐,比如:

  if()
     if()
    else
     ;

   上述else虽然是和外层if对齐,但是会和内部if进行匹配。

  因此,选C

第 3 题(单选题)

题目名称:

int func(int a)
{
    int b;
    switch (a)
    {
        case 1: b = 30;
        case 2: b = 20;
        case 3: b = 16;
        default: b = 0;
    }
    return b;
}

则func(1) = (      )

题目内容:

A .30

B .20

C .16

D .0

答案解析:   

switch的每个case之后如果没有加break语句,当前case执行结束后,会继续执行紧跟case中的语句。

  func(1)可知,在调用func时形参a的值为1,switch(a)<==>switch(1),case 1被命中,因为该switch语句中所有分支下都没有增加break语句,因此会从上往下顺序执行,最后执行default中语句返回。

  因此:选择D

第 4 题(单选题)

题目名称:

switch(c)语句中,c不可以是什么类型( )

题目内容:

A .int

B .long

C .char

D .float

答案解析:   

 switch语句中表达式的类型只能是:整形和枚举类型

  D选项为浮点类型,不是整形和枚举类型

  因此:选择D

第 5 题(单选题)

题目名称:

下面代码的执行结果是什么( )

#include 
int main() {
	int x = 3;
	int y = 3;
	switch (x % 2) {
	case 1:
		switch (y)
		{
		case 0:
			printf("first");
		case 1:
			printf("second");
			break;
		default: printf("hello");
		}
	case 2:
		printf("third");
	}
	return 0;
}

题目内容:

A .secondthird

B .hello

C .firstsecond

D .hellothird

答案解析:   

 switch语句时多分支的选择语句,switch中表达式结果命中那个case,就执行该case子项,如果case子项后没有跟break语句,则继续往下执行。

  关于该题解析,请看以下注解:

  
#include 
  int main() {
  	int x = 3;
  	int y = 3;
  	switch (x % 2) {  // x%2的结果为1,因此执行case1
  	case 1:
  		switch (y)   // y是3,因此会执行case3,而case3不存在,那只能执行default
  		{
  		case 0:
  			printf("first");
  		case 1:
  			printf("second");
  			break;
  		default: printf("hello"); // 打印hello,打印完之后,内部switch结束,此时外部case1结束
  		}             // 因为外部case1之后没有添加break语句,所以继续执行case2
  	case 2:             // 打印third
  		printf("third");      // 外部switch结束
  	}
  	return 0;
  }
  

  即:先在内部switch的default位置打印hello,紧接着在外部case2中打印third

  因此:选择D

第 6 题(单选题)

题目名称:

关于switch说法不正确的是:( )

题目内容:

A .switch语句中的default子句可以放在任意位置

B .switch语句中case后的表达式只能是整形常量表达式

C .switch语句中case子句必须在default子句之前

D .switch语句中case表达式不要求顺序

答案解析:   

 A:正确,可以放在任意位置,但是一般建议最好还是放在最后

  B:正确,case语句后一般放整形结果的常量表达式或者枚举类型,枚举类型也可以看成是一个特殊的常量

  C:错误,没有规定case必须在default之前,一般case最好放在default之前

  D:正确,但一般还是按照次序来

  因此:选择C

for循环

第 1 题(单选题)

题目名称:

关于while(条件表达式) 循环体,以下叙述正确的是( )? (假设循环体里面没有break,continue,return,goto等等语句)  

题目内容:

A .循环体的执行次数总是比条件表达式的执行次数多一次

B .条件表达式的执行次数总是比循环体的执行次数多一次

C .条件表达式的执行次数与循环体的执行次数一样

D .条件表达式的执行次数与循环体的执行次数无关

答案解析: 

 while(条件表达式)

    循环体

  while循环中,当条件表达式成立时,才会执行循环体中语句,每次执行期间,都会对循环因子进行修改(否则就成为死循环),修改完成后如果while条件表达式成立,继续循环,如果不成立,循环结束

  故:while循环条件将会比循环体多执行一次。

  因此:选择B

第 2 题(单选题)

题目名称:

有以下程序

#include 
int main()
{
	int a = 0, b = 0;
	for (a = 1, b = 1; a <= 100; a++)
	{
		if (b >= 20) break;
		if (b % 3 == 1)
		{
			b = b + 3;
			continue;
		}
		b = b-5;
	}
	printf("%d\n", a);
	return 0;
}

程序的输出结果是?( )

题目内容:

A .10

B .9

C .8

D .7

答案解析:  

参考代码注释。  

#include 

  int main()

  {

   int a = 0, b = 0;

    // for循环将a和b的初始值均设置为1

   for (a = 1, b = 1; a <= 100; a++)

   {

   if (b >= 20) break;

   if (b % 3 == 1)

   {

   b = b + 3;

   continue;

   }

   b = b-5;

   }

   printf("%d\n", a);

   return 0;

  }

  第一次循环:a = 1,b=1--->b小于20,if不成立,b%3==1%3==1成立,b=b+3, 此时b的值为4

  第一次循环:a = 2,b=4--->b小于20,if不成立,b%3==4%3==1成立,b=b+3, 此时b的值为7

  第一次循环:a = 3,b=7--->b小于20,if不成立,b%3==7%3==1成立,b=b+3, 此时b的值为10

  第一次循环:a = 4,b=10--->b小于20,if不成立,b%3==10%3==1成立,b=b+3, 此时b的值为13

  第一次循环:a = 5,b=13--->b小于20,if不成立,b%3==13%3==1成立,b=b+3, 此时b的值为16

  第一次循环:a = 6,b=16--->b小于20,if不成立,b%3==16%3==1成立,b=b+3, 此时b的值为19

  第一次循环:a = 7,b=19--->b小于20,if不成立,b%3==19%3==1成立,b=b+3, 此时b的值为22

  第一次循环:a = 8,b=22--->b大于20,if成立,循环break提出

  最后打印a:8

  因此:选择C

 

你可能感兴趣的:(C语言练习题,c语言,算法,开发语言,易错点)