C语言必会题目(1)

简介: C语言必会题目(1)

在学习语言时,最重要的就是练习,光听不练假把式。下面我就推荐一些C语言必会的题。



执行下面程序,正确的输出是( )

int x=5,y=7;
void swap()
{
int z;
z=x;
x=y;
y=z;
}
int main()
{
int x=3,y=8;
swap();
printf("%d,%d\n",x, y);
return 0;
}

A: 5,7 B: 7,5 C: 3,8 D: 8,3


看到上述代码,我们就得从变量开始入手。最开始先定义两个全局变量int x=5,y=7。接下来进入到主函数中也定义了局部变量int x=3,y=8。调用swap()时,使用的是全局变量,与主函数中变量无关,所以输出内容为3,8。我们在做这种题时,一定要考虑局部优先原则。答案:C



以下不正确的定义语句是( )


A: double x[5] = {2.0, 4.0, 6.0, 8.0, 10.0};


B: char c2[] = {'\x10', '\xa', '\8'};


C: char c1[] = {'1','2','3','4','5'};


D: int y[5+3]={0, 1, 3, 5, 7, 9};


本题考查了数组定义与转义字符,\ddd ddd表示1到3个八进制数 如:\130 转义为 字符X \xhh hh表示1到2位十六进制数 如:\x30 转义为 字符0。但是八进制中没有8,所以B选项错误。答案:B



下面这个程序执行后会有什么错误或者效果【多选】( )

#define MAX 255
int main()
{
unsigned char A[MAX], i;
for(i = 0; i <= MAX; i++)
A[i] = i;
return 0;
}

A: 数组越界 B: 死循环 C: 栈溢出 D: 内存泄露


本题考察变量的取值范围。此题使用宏define定义MXA为255,但是定义数组中使用unsigned char(0~255)在数组中应为0~254,所以第一个问题就是for循环中,数组越界。for循环停止的条件为i<=255,但是i的取值范围为(0~255)当超过255时就会返回起始点0继续增加。这会使循环进行循环


内存泄漏:创建的临时变量,在栈中,应该会由系统自动释放,所 以应该是不存在内存泄漏的问题。栈溢出:属于缓冲区溢出的一种。栈溢出是由于C语言系列没有内置检查机制来确保复制到 缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围。


答案A,B



请问下列代码的输出结果有可能是哪些【多选】( )

#include <stdio.h>
typedef union
{
int a;
struct
{
short b;
short c;
};
}X;
int main()
{
X x;
x.a = 0x20150810;
printf("%x,%x\n", x.b, x.c);
    return 0;
}

A: 2015,810 B: 50810,201 C: 810,2015 D:20150,810


次题目考察联合的特点,联合成员使共用同一块内存空间的。


这时我们就要考虑两种方向,计算机存储形式为大端存储与小端存储


对于0x20150810 如果按照大端模式存储:从低地址到高地址:20 15 08 10 输出从低地址到高地址:20 15 08 10 如果按照小端模式存储:从低地址到高地址:10 08 15 20 输出从高地址到低地址:08 10 20 15 此数以int类型赋值给联合体x.a,而以结构成员b和c分开访问,分别拿到低地址的2个字节和高地址的2个字节,大端下是 2015和810,小端下是810和2015


答案:A,C



 指出下列代码的缺陷【多选】( )

float f[10];
// 假设这里有对f进行初始化的代码
for(int i = 0; i < 10;)
{
if(f[++i] == 0)
break;
}

A: for(int i = 0; i < 10;)这一行写错了


B: f是float型数据直接做相等判断有风险


C: f[++i]应该是f[i++]


D: 没有缺陷


我们这种题可以通过选项进行排除选择。


A:for循环必须要有三要素,但是这三个要素可以使用;进行分割不展现其中内容。编译器默认为空内容。所以A选项没有问题。


B:一般float型只能精确到小数后六位(即1e-6),将float型数据的绝对值与1e-6比较,来判断是否相等(为零)。float的精度 误差在1e-6;double精度误差在1e-15;所以要判断一个float型数:if(fabs(f)<1e-6);要判断一个double型数:if(fabs(f)<1e15);若满足,则为零。所以B选项为代码缺陷。


C:这里考察的为前置++与后置++的区别,前置++是先加再进行使用,后置++是先使用此值再进行+1操作。所以 f[++i]应该是f[i++],否则会导致数组越界。


D:B、C都有缺陷所以不选D。


答案:B、C



如下函数 fun 计算 prod=1*2*3*…*n ,并返回计算结果值。但当 n>12 时,返回值不正确。要找出该程序的错 误,正确的调试方法是( )

int fun(int n)
{
int prod = 1 , i = 0;
for(i = 1;i <= n;i++)
{
prod *= i;
}
return prod;
}

 

A: 监视变量prod的值,在prod *= i;行处设置断点,然后单步运行,直到发现错误原因


B: 监视变量prod的值,在return prod;行处设置断点,程序中断后,即可发现错误原因


C: 在prod=1;处设置断点,然后在函数调用堆栈中即可发现错误原因


D: 监视变量i的值,在for (i=1; i<=n; i++)行处设置断点,然后单步运行,直到发现错误原因


fun函数在n<12时返回值正确,但是在n>=12后返回值出错,这时我们就要考虑是不是栈溢出问题,所以我们应该监视prod内容,在prod *= i设置断点。


答案:A



以下 scanf 函数调用选项中, 错误的是( )

struct T
{
char name[20];
int age;
int sex;
} a[5], *pa=a;

A: scanf("%s",a[0].name);


B: scanf("%d", &pa[0].age);


C: scanf("%d",&(pa->age));


D: scanf("%d", pa->age);


该题考察的是通过scanf函数的调用对结构体数据类型进行初始化。


scanf("输入控制符", 输入参数);功能:将从键盘输入的 字符转化为“输入控制符”所规定格式的数据,然后存入以输入参数的值为地址的变量中。scanf输入时要通过地址找空间, B、C用了&是正确的。name属于字符数组的数组名,相当于数组的首地址,A正确。单独的pa->age可用于输出语句获取 值的形式,用在scanf中的时候需要&操作符,D错误。


答案:A



有以下函数,该函数的功能是( )

int fun(char *s)
{
char *t = s;
while(*t++);
return(t-s);
}

A: 比较两个字符的大小


B: 计算s所指字符串占用内存字节的个数


C: 计算s所指字符串的长度


D: 将s所指字符串复制到字符串t中


这道题考察我们对指针的理解。


首先将s指针内容赋给t,循环在*t为0时停止,同时t++,t最后会停在字符串结束的'\0'之后的一个位置,返回(t-s)是指针位置的判断,指针相减可以得到字符串长度的大小。


答案:B



C 语言中,下列运算符优先级最高的是 ( )


A: !  B: %  C: >>  D: ==


单目运算符的优先级通常都比较高,具体情况可查阅运算符优先级表格


答案:A


要使 a 的低四位翻转,需要进行操作是( )


A: a|0xF  B: a&0xF  C: a^0xF  D: ~a


十六进制数0xF是4位1,参与运算时整型提升,高位都是0。低四位和1异或,0^1是1,1^1是0;高位和0异或,0^0是0,1^0 是1。故而可以通过异或F使得a的低四位翻转,并保持高位不变


答案:C



3、下面有关空指针和未初始化指针,说法错误的是( )


A: 对0x0这个地址取值是非法的


B: 空指针可以确保不指向任何对象或函数; 而未初始化指针则可能指向任何地方


C: 空指针与任何对象或函数的指针值都不相等


D: malloc在其内存分配失败时返回的是一个未初始化的指针


malloc函数在内存分配失败时返回NULL,其余选项都正确


答案:D


如果 x=2014 ,下面函数的返回值是( )

int fun(unsigned int x)
{
int n = 0;
while(x + 1)
{
n++;
x = x | (x + 1);
}
return n;
}

A: 20 B: 21 C: 23 D 25


运算符 “ | ” 的作用是:把参见运算两个数所对应的二进制位分别进行“或”运算,即:两位同为“0”,结果才为“0”。


x=x|(x+1)的作用是每次循环把x的二进制中从右往左数的最后一位0变成1


这个作用是对整型中0的个数进行统计,当数的二进制中的0全成为1时,栈溢出全为0循环停止。2014的二进制序列为:0000 0000 000 0000 0000 0111 1101 1110有23个0,所以返回值为23.


答案:C


以下选项中,对基本类型相同的两个指针变量不能进行运算的运算符是( )


A: +    B: -    C: =    D: ==


A错误,因为两个地址相加无意义也可能越界,所以规定不允许指针相加。B选项,可以求出两个数据元素储存位置之间的相 隔同数据类型的元素个数,C选项,赋值,没问题,D选项,判断两指针是否相同。


答案:A


关于代码的说法正确的是( )

#include <stdio.h>
int main()
{
int x = -1;
unsigned int y = 2;
if (x > y)
{
printf("x is greater");
}
else
{
printf("y is greater");
}
return 0;
}

A: x is greater  B: y is greater  C: 依赖实现  D: 随机


x是有符号数-1,内存中是全1,当有符号的x和无符号数进行比较时,x会隐式类型转换被当做无符号数,是一个很大的数。


算数转换与整型提升如果算数转换不理解的,可以看前面连接的博客进行学习


答案:A


下面函数的输出结果是( )

void func()
{
int k = 1^(1 << 31 >> 31);
printf("%d\n", k);
}

A: 0 B: -1 C: -2 D: 1


这里的考点就是移位操作符的使用。


<<(左移):就是把一个二进制数整体向左移动, 舍弃超出的部分,在移动的空白处加0。


>>(右移):算数右移:右边丢弃,左边补原来的符号位。


1的二进制:00000000000000000000000000000001


(1 << 31 );左移31位: 10000000000000000000000000000000


(1<<31>>31):右移31位:1111111111111111111111111111111111111


00000000000000000000000000000001^1111111111111111111111111111111111111 =


1111111111111111111111111111111111110 = -2


答案:C



读代码选结果( )

int count = 0;
int x = -1;
while(x)
{
count++;
x = x >> 1;
}
printf("%d",count);

A: 1   B: 2   C: 32   D: 死循环,没结果


算数右移是将右边丢弃,左边补原来的符号位。


负数的符号位是1,所以x永远不会变为0,是个死循环


答案:D



以下程序运行后的输出结果是( )

int main()
{
int a=1,b=2,m=0,n=0,k;
k=(n=b<a)&&(m=a);
printf("%d,%d\n",k,m);
return 0;
}

A: 0,0 B: 0,1 C: 1,0 D: 1,1


k=(n=b<a)&&(m=a);这是这道题的关键:执行顺序如下:先执行n=b<a,赋值运算符优先级低于关系运算符,所以b<a得到0n=0。(0)&&(m=a),&&运算前表达式为假,则 后面的括号(m=a)不运算,m值还是0,最后,&&的结果是0,即k=0


答案:A



以下逗号表达式的值为( )

(x = 4 * 5 , x * 5) , x + 5;

A: 25 B: 20 C: 100 D: 45


逗号表达式是从前到后依次计算子表达式,而其结果是最后一项的值,此题去掉括号后的表达式,和原表达式是等价的,先 计算4*5并赋值给x,x变为20,中间x*5并没有改变x的值,最后一项x+5值是25,也就是整个表达式的值。


答案:A



在下面的字符数组定义中,哪一个有语法错误( )


A: char a[20]="abcdefg";


B: char a[]="x+y=5.";


C: char a[15];


D: char a[10]='5';


D中的'5'是一个字符常量,不能给字符型数组a初始化


答案:D



已知 i,j 都是整型变量,下列表达式中,与下标引用 X[i][j] 不等效的是【多选】( )


A: *(X[i]+j)


B: *(X+i)[j]


C: *(X+i+j)


D: *(*(X+i)+j)


本题考查的是二维数组的元素访问,A选项是 正确的,X[i]就是第i行的数组名,数组名表示首元素的地址,X[i]表示第i行的第 一个元素的地址,+j后就是第i行下标为j的元素的地址,整体解引用就是X[i][j],A正确。B选项因为[]的优先级高于*,所以代 码相当于**((x+i)+j),X+i+j后就越界了,并不代表X[i][j],所以错误。C选项也明显不对,X是二维数组的数组名,数组名相当于第 一行的地址,X+i+j,跳过了i+j行,就越界了,C错误。D选项是标准的指针形式访问二位数组的一个元素。


答案:B、C



在上下文及头文件均正常的情况下,下列代码的输出是( )(注: print 已经声明过)  

int main()
{
char str[] = "Geneius";
print(str);
return 0;
}
print(char *s)
{
    if(*s)
    {
        print(++s);
        printf("%c", *s);
    }
}

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


代码实现了递归倒序打印字符串的功能,但是++s使得s的值发生了变化,回不到'G'的位置上,故而没有打印'G'


答案:A



在C语言中,以下正确的说法是( )


A: 实参和与其对应的形参各占用独立的存储单元


B: 实参和与其对应的形参共占用一个存储单元


C: 只有当实参和与其对应的形参同名时才共占用存储单元


D: 形参是虚拟的,不占用存储单元


在调用函数的时候,真实传递给函数的是实参,函数定义部分函数名后的参数是形参。形参和实参的名字是可以相同的,在 函数调用的时候,形参是实参的一份临时拷贝,分别占用不同的内存空间,所以A正确,B错误,及时形参和实参的名字相 同,也是占用不同的内存空间,所以B错误;函数如果不被调用时,函数的形参是形式上存在的,但是函数在被调用的时候, 形参是要分配内存空间的,所以D错误。


答案:A



5、在c语言中,一个函数不写返回值类型,默认的返回类型是( )


A: int B: char C: void D: 都不是


一个函数不写返回值类型,默认的返回类型是int,但不提倡这么做

答案:A



我们知道C语言的 break 语句只能跳出离它最近的一层循环,可是有时候我们需要跳出多层循环,下列跳出多层 循环的做法正确的是【多选】( )


A: 将程序写成函数用return结束函数,便可跳出循环


B: 修改外层循环条件例如  

for( int i = 0 ; i < MAX1 ; i ++ )
{
    for( int j = 0 ; j < MAX2 ; j ++ )
    {
        if( condition )
        {
            i = MAX1;
            break;
        }
    }
}

C: 在外层循环设置判断条件例如

for( ; symbol != 1 && condition2 ; )
{
    for( ; symbol != 1 && condition3 ; )
    {
        if( condition1 )
            symbol = 1 ;
    }
}

D: 在外层循环后面加入break例如

for( ; condition2 ; )
{
    for( ; condition3 ; )
    {
        if( condition1 )
            symbol = 1 ;
    }
    if( symbol == 1 )
        break ;
}

A选项可以使用return强制结束函数内容,跳出循环。


B选项将第一层跳出循环条件改成跳出条件,使用break跳出第二层循环也是不错的方法。


C选项是将两次循环跳出条件关联,改变symbol内容即可跳出两层循环。


D选项在外层使用break,当他已经第二层循环跳出时会判断symbol内容跳出。


此题旨在整理跳出多层循环的方法,每个选项都是正确的,代码为伪代码,condition代表逻辑表达式。


答案:ABCD



以下程序运行时,若输入 1abcedf2df 输出结果是( )  

#include <stdio.h>
int main()
{
    char ch;
    while ((ch = getchar()) != '\n')
    {
        if (ch % 2 != 0 && (ch >= 'a' && ch <= 'z'))
            ch = ch - 'a' + 'A';
        putchar(ch);
    }
    printf("\n");
    return 0;
}

A: 1abcedf2df B: 1ABCEDF2DF C: 1AbCEdf2df D: 1aBceDF2DF


我们首先得看函数的功能是什么?


函数功能为:将奇数内容并且为小写字母的转为大写。程序首先考虑ch的ASCII码值是不是奇数,再看是不是小写字母,同时满足时被改为大写字母。


答案:C


今天先分享这么多经典题目,更多题目尽情期待博主后期博客更新。希望这些题目可以帮助到你们更好的学习语言!!!

目录
相关文章
|
16天前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
2月前
|
存储 C语言 C++
C语言------------指针笔试题目深度剖析
C语言------------指针笔试题目深度剖析
19 1
|
7月前
|
存储 测试技术 C语言
【竞赛题目】木块(C语言详解)
【竞赛题目】木块(C语言详解)
32 0
|
5月前
2.C语言题目---字符串左旋
2.C语言题目---字符串左旋
50 1
|
7月前
|
存储 编译器 C语言
C语言: 数组指针/指针数组等相关的选择题目
C语言: 数组指针/指针数组等相关的选择题目
|
5月前
|
存储
1.C语言题目---指针类(基础)
1.C语言题目---指针类(基础)
34 1
|
12天前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
|
12天前
|
C语言
C语言 浙大版《C语言程序设计(第3版)》题目集 练习8-8 移动字母 (10分)
C语言 浙大版《C语言程序设计(第3版)》题目集 练习8-8 移动字母 (10分)
|
12天前
|
C语言
浙大版《C语言程序设计(第3版)》题目集 练习8-2 计算两数的和与差 (10分)
浙大版《C语言程序设计(第3版)》题目集 练习8-2 计算两数的和与差 (10分)
|
13天前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-6 删除字符 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-6 删除字符 (20分)