zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C语言易错题集 第三部

C语言 错题
2023-09-11 14:15:52 时间

一、C语言程序exe相关

用 C 语言编写的源程序须经过编译连接后,生成扩展名为 .exe 的可执行文件,才能运行。()

A   正确
B   错误
答案:  B
C语言编写的程序,肯定是要经过一系列的编译,链接,生成可执行的文件。

在windows系统中,执行文件都是.exe为扩展名的。

不过在linux系统中就不一样了,linux系统并不区分扩展名,所以也就无所谓什么.exe之类的文件,
只要知道最终生成可执行的二进制文件就可以了。

二、sizeof和strlen相关

下面程序的输出结果为多少(32位机器上)#include<stdio.h>
#include<string.h>
void Func(char str_arg[2])
{
    int m = sizeof(str_arg);
    int n = strlen(str_arg);
    printf("%d\n", m);
    printf("%d\n", n);
}
int main(void)
{
    char str[] = "Hello";
    Func(str);
}

A   5 5
B   5 4
C   4 5
D   4 4
答案:  C
1,对于void Func(charstr_arg[2]) 这一句不要被那个2误导了
下面这些写法都可以的。
voidFunc(charstr_arg[])
voidFunc(charstr_arg[1])
voidFunc(charstr_arg[2])
voidFunc(charstr_arg[3])
voidFunc(charstr_arg[4])
...
voidFunc(charstr_arg[200])
...

也可以写成
voidFunc(char *str_arg)

之所以能这样写,是因为Func的参数是一个地址

2,对于sizeof的参数,是一个指针,因为这是32位系统, 32 = 8*4,需要4字节存储指针。
如果是64位系统  64 = 8*8,需要8字节

3,对于strlen,就是字符串的长度,"Hello"长度是5

三、小端存储相关

在x86的机器上,int a=0xabcd1234 char b=((char*&a)[0]请问b是多少
A    0xa
B    0x4
C    0xab
D    0x34
答案:   D
x86是小端存储,即高位存储在高地址,低位存储在低地址。
int a = 0xabcd1234;
内存中 ab  cd  12   34,b作为一个char,右边表达式指针指向为' 4 '转化为16进制为 0x34.-->

四、break和continue相关

C语言中breakcontinue语句说法正确的是()
A  break语句只应用于循环体中
B  continue语句只应用于循环体中
C  break是无条件跳转语句,continue不是
D  breakcontinue的跳转范围不够明确,容易产生问题
答案:  B
A:break语句可以用于循环语句中,终止当前循环;也用于在switch语句中结束一个case 。A项错误。
B:continue语句只能用于循环语句,正确。
C:无条件跳转语句有return , break , continue , goto 。C项错误。
D:在switch语句中,break用来使执行流程跳出switch语句。
在循环语句中,break语句用来使执行流无条件跳出本层循环体。
continue的功能是:结束本次循环,接着进行下一次是否执行循环的条件判定。breakcontinue语句跳转范围明确。D选项错误。
综上本题选B。

五、函数声明相关

若有以下程序 
#include<stdio.h> 
void f(int n); 
int main() { 
   void f(int n); 
   f(5); 
} 
void f(int n) 
{ 
   printf("%d\n",n); 
} 
则以下叙述中不正确的是()。

A   若只在主函数中对函数f进行说明,则只能在主函数中正确调用函数f
B   若在主函数前对函数f进行说明,则在主函数和其后的其它函数中都可以正确调用函数f
C   对于以上程序,编译时系统会提示出错信息:提示对对f函数重复说明
D   函数f无返回值,所以可用void将其类型定义为无值型

答案:   A C
     
A   若只在主函数中对函数f进行说明,则只能在主函数中正确调用函数f
//解释:  在f函数定义的后面,其它的函数也是可以调用f函数的
  
B   若在主函数前对函数f进行说明,则在主函数和其后的其它函数中都可以正确调用函数f
 
//正确
 
C   对于以上程序,编译时系统会提示出错信息:提示对f函数重复说明
//解释:   在C语言中变量或函数可以重复声明,但是不能重复定义
  
D  函数f无返回值,所以可用void将其类型定义为无值型
//正确

六、递归相关

下列代码的输出是?(注:print已经声明过)
main()
{     
    char str[]="Geneius";
    print (str);
} 
print(char *s)
{
  if(*s){
       print(++s);
       printf("%c",*s); 
	}
}

A   suiene
B   neius
C   run-time error
D   suieneG
答案: A

在这里插入图片描述

1*s为G,执行print(e),printf(e)被压入倒数第1层,应该输出e;
2*s为e,执行print(n),printf(n)被压入倒数第2层,应该输出n;
3*s为n,执行print(e),printf (e) 被压入倒数第3层,应该输出e;
4*s为e,执行print(i),printf (i) 被压入倒数第4层,应该输出i;
5*s为i,执行print(u),printf (u) 被压入倒数第5层,应该输出u;
6*s为u,执行print(s),printf (s) 被压入倒数第6层,应该输出s;
7*s为s,执行print(\0),printf (\0) 被压入倒数第7层,应该输出空格;
8、开始跳出print,从上向下得到压入栈中的printf,得到最后结果“ suiene”

七、预处理相关


源程序中凡是行首以#标识的控制行都是预处理指令。以上描述是否正确?
A   正确
B   错误
答案:   A
C语言有效的预处理命令总是以“#”开头
(1)头文件包含#include
(2)宏定义 #define
(3)条件编译 #ifdef  #endif

八、C语言程序的最小单元相关

C语言源程序的最小单位是()。

A   程序行
B   语句
C   函数
D   字符
答案:   D
C语言源程序的最小单位是字符,最小执行单元是函数。

九、指针相关

要使指针变量p指向2维数组A的第1个元素,正确的赋值表达式是()。

A   p=A或p=A[0]
B   p=A[0]或p=A[0][0]
C   p=A[0]或p=&A[0][0]
D   p=A或p=&A[0][0]
答案:   C

bingle头像bingle
P=A, 是错误的,A代表的是二维数组中,数组A[0]的地址,和元素A[0][0]的地址在 数值上是一样的,
但是不能直接把A赋给P,原因是它们的类型不同。
A[0][0]是二维数组,*p相当于一维数组,类型不同

十、数组初始化相关

下面对一维数组 a 进行正确的初始化的语句是()

int a[10] = (0, 0, 0, 0, 0);
int a[10] = {};
int a[10] = {10};
int a[10] = {10, 0, -1.23};
答案:  B C D
A:   是小括号,错误,应为大括号。
D:   浮点数会被强制的转换为整数,所以正确

在这里插入图片描述

十一、链接相关

由多个源文件组成的C程序,经过编辑、预处理、编译、链接等阶段会生成最终的可执行程序。下面哪个阶段可以发现被调用的函数未定义?

A   预处理
B   编译
C   链接
D   执行
答案:   C

链接是将各个编译单元中的变量和函数引用与定义进行绑定,保证程序中的变量和函数都有对应的实体,
若被调用函数未定义,就在此过程中会发现。编辑阶段创建和修改源程序;预处理阶段分析宏定义以及替换宏引用;
编译过程是把源程序翻译为与之等价的目标程序。

十二、负数变无符号数相关


有如下C语言程序段

short si = -32767;
unsigned short usi = si;
执行上述两条语句后,usi的值为 ( )

A  -32767
B   32767
C   32768
D   32769
答案:   D
因C语言中的数据在内存中为补码表示形式
先把-32767表示成原码形式是(因为补码不是一步可以得到的,先原码再补码)
(-32767)原码=1111 1111 1111 1111-32767)补码 =1000 0000 0000 0001
再把这个补码赋给usi,usi会把最高位符号位1也当做数值位
usi=1000 0000 0000 0001=32769

十三、负数变无符号数相关

#include<stdio.h>
int main()
{
    unsigned char i=7;
    int j=0;
    for(;i>0;i-=3)
    {
       ++j;
     }
     printf("%d\n",j);
     return 0;
}
请问该程序的输出是多少?

A   2
B   死循环
C   173
D   172
答案:   C
这题正着推不容易,可以考虑反着推
要想退出循环  最后必定是 i=0
0~255256个数
根据选项
A:        (0 + 2*3) % 256 = 6  不是7 , 所以A错误
C:          (0 + 173*3) % 256 = 7 ,           所以C可以
D:          (0 + 172*3) % 256 = 4 不是7,所以D错误
B: 既然C可以,当然B就错误

第二种思路:
-2的原码是1000 0010,反码是1111 1101,补码是1111 1110,计算机中存储的是补码,
即存的是1111 1110,又因为这里是无符号的,所以最高位的1不代表符号,
所以1111 1110254,同理,依次推,直到i为0,可得一共1737 4 1——3254 251....2——85255 252....3——853-30,就不会进入循环了,一共173

十四、union相关

在这里插入图片描述

A     1 4
B     4 4
C     1 2
D     4 8
答案:   D

在这里插入图片描述

十五、switch()相关

若有以下程序
#include<stdio.h>
main()
{ 
    int s=0,n;
    for(n=0; n<4; n++)
    {
        switch(n)
        {
           default:s+=4;
           case 1:s+=1;
           case 2:s+=2;
           case 3:s+=3;
        }
    }
    printf ("%d\n",s);
}
则程序的输出结果是?
A    6
B    18
C    10
D    24

答案: D
1次:s=0+4+1+2+3=10;case 12 3,依次比对,最后没有匹配的执行default 这时候开关相当于打开了,执行后面全部的。
第2次:s=10+1+2+3=16;3次:s=16+2+3=21;4次:s=21+3=24.switch-case语句中,多个case可以共用一条执行语句,: 
case 常量表达式1: 
case 常量表达式2: 
case 常量表达式3: 
语句; 
break; 
由此可以看出case语句的作用:
case后面的常量表达式实际上只起语句标号作用,而不起条件判断作用,即“只是开始执行处的入口标号”。

因此,一旦与switch后面圆括号中表达式的值匹配,就从此标号处开始执行;
而且执行完一个case后面的语句后,若没遇到break语句,就自动进入下一个case继续执行,
而不再判断是否与之匹配,直到遇到break语句才停止执行,退出switch语句。

因此,若想执行一个case分之后立即跳出switch语句,就必须在此分支的最后添加一个break语句。