C语言易错知识点总结1

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 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 <stdio.h>
#include <string.h>
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 <stdio.h>
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 <stdio.h>
#include <string.h>
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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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 <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

第 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 <stdio.h>
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 <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

 

相关文章
|
1月前
|
C语言
C语言学习笔记-知识点总结上
C语言学习笔记-知识点总结上
75 1
|
2月前
|
C语言 C++
C语言函数调用的易错点
在 C 语言中,函数调用时常见的易错点包括:参数类型不匹配、缺少或多余参数、返回值未使用、函数未声明、递归调用未终止、指针传递错误、使用未初始化的变量等。C 语言不支持函数重载,在 C++ 中使用时需注意区分。正确处理这些易错点可以提高代码的稳定性和可维护性。
|
6月前
|
编译器 C语言
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(下)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
42 0
|
4月前
|
存储 编译器 C语言
|
5月前
|
编译器 C语言
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)二
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)二
49 3
|
5月前
|
存储 编译器 C语言
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)一
C语言学习记录——操作符详解知识点选记(算术操作符、单目操作符、移位操作符、关系操作符、逻辑操作符、条件操作符......)一
40 1
|
4月前
|
前端开发 C语言
C语言08----注释扩展知识点,注释快捷键:ctrl+k,ctrl + C,取消快捷键 ctrl + K,ctrl + U
C语言08----注释扩展知识点,注释快捷键:ctrl+k,ctrl + C,取消快捷键 ctrl + K,ctrl + U
|
6月前
|
C语言
C语言基础 - 字符串/字符数组最易错考点
该文探讨了C语言中&#39;\0&#39;字符对字符串和字符数组的重要性,以及`strlen`和`sizeof`的区别。&#39;\0&#39;作为字符串的结束标志,确保了正确打印和计算字符串长度。示例代码显示,未包含&#39;\0&#39;的字符数组打印时可能出现随机值。`strlen`计算字符串长度,不包含&#39;\0&#39;,而`sizeof`返回变量或数组的总字节数,包括&#39;\0&#39;。文章还提醒注意转义字符在字符串中的影响,例如`\t`和`\62`。最后总结了字符串和字符数组处理时应注意的要点。
63 0
C语言基础 - 字符串/字符数组最易错考点
|
5月前
|
C语言
C语言----关于二维数组传参的本质相关的知识点(数组指针、指针数组)
C语言----关于二维数组传参的本质相关的知识点(数组指针、指针数组)
|
5月前
|
存储 缓存 C语言
C语言易错小贴士
C语言易错小贴士