生命周期&作用域

答案解析: 

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

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

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

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

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

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

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

  D:正确,即在函数体内

  因此:选择D

答案解析:

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

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

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

C:正确

D:明显错误

因此:选择C

答案解析:

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

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

C:'\q' 什么都不是

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

因此:选择C

答案解析:

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

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

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

因此:答案选C

答案解析:

本题主要考察变量的访问规则,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

答案解析:

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

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

因此:选择A

简单数组

 答案解析:

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

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

  B:正确

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

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

  因此,选择B

 答案解析:

 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

答案解析: 

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

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

因此:选择B

答案解析: 

数组的大小必须是常量

因此:选择B

答案解析: 

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

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

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

  因此:选择C

指针大小

答案解析:  

本题主要考察static的特性

  1. static修饰变量

   a. 函数中局部变量:

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

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

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

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

   b. 全局变量

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

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

  2. static修饰函数

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

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

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

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

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

  因此:选择C

答案解析:  

本题主要考察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

答案解析:  

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

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

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

  B:正确

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

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

  因此,选择B

if语句

答案解析:   

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

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

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

故:死循环的打印5

因此:选择C

答案解析:   

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

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

  C:正确

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

  if()
     if()
    else
     ;

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

  因此,选C

答案解析:   

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

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

  因此:选择D

答案解析:   

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

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

  因此:选择D

答案解析:   

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

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

  
#include <stdio.h>
  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

答案解析:   

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

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

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

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

  因此:选择C

for循环

答案解析: 

 while(条件表达式)

    循环体

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

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

  因此:选择B

答案解析:  

参考代码注释。  

#include <stdio.h>

  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

 

08-03 18:09