one
1.下面关于C语言的编译和链接说法错误的是?
A.C语言是一门编译型计算机语言
B.写出来的C语言代码直接就可以运行的
C.C语言代码需要经过编译和链接生成可执行程序才能运行的
D.C语言代码经过编译生成目标文件,目标文件和链
答案解析
C语言是一门编译型计算机语言,代码需要经过编译和链接生成可执行程序才能运行的,C语言代码经过编译生成目标文件,目标文件和链接库通过链接生成可执行程序。
2.关于集成开发环境描述错误的是?
A.集成开发环境简称IDE
B.集成开发环境一般都是将编辑、编译、链接、调试等功能集成在一起的一个开发环境
C.集成开发环境就是编译器
D.集成开发环境使用起来方便,大大提升了开发和调试的效率
答案解析
集成开发环境中集成了编译器,如果说集成开发环境就是编译器,有些片面了
3.关于C语言中源文件和头文件说法正确的是?
A.C语言的源文件的后缀是.cpp
B.头文件没什么用,只要有源文件就行了
C.C语言中源文件的后缀是.c,头文件的后缀是.h
D.C语言的源文件可以没有后缀
答案解析
很多C语言编译器就是通过文件的后缀来区分是源文件还是头文件的,一般都是要明确的写出文件后缀的
头文件的后缀是.h,是header的意思
源文件的后缀是.c
在稍微复杂的C语言程序中,头文件是很有必要的,一般是用来函数声明、类型声明等
4.C语言规定,在一个源程序中,main函数的位置( )
A.必须在最开始
B.必须在库函数的后面
C.可以任意
D.必须在最后
答案解析:
main函数的位置可以在任意位置,但是如果在主函数之中调用了哪些函数,必须在main函数前对其所调用函数进行生命或包含其被调用函数的头文件。
因此:选择C
5.关于main函数错误的是?
A.main函数是程序的入口
B.一个C语言程序中可以写多个main函数
C.main函数的名字是可以随便改的,比如:mian
D.main函数的名字是固定的,一个工程中,有且仅有一个main函数
答案解析
一个C语言程序中的main函数,有且仅有一个
main函数的名字是固定的,编译器以main函数作为程序的入口,程序是从main函数的第一行开始执行的。
6.printf和库函数描述错误的是?
作业内容
A.printf是库函数,不需要包含头文件就可以使用
B.库函数是C语言标准约定的,由各个C语言编译器的厂商实现的,所以各个编译器的库函数使用和功能是一样的,但是内部实现是有差异的。
C.printf函数是用来在标准输出上打印格式化的信息的
D.printf函数打印字符使用%c,打印整数使用%d指定格式
答案解析
printf是库函数,必须含头文件才能正确使用
7.下面哪个不是关键字:( )
A.int
B.struct
C.define
D.continue
答案解析:
C语言关键字:C语言定义的,具有特定含义、专门用于特殊用途的C语言标识符,也称为保留字
define不是关键字,是编译器实现的,用来定义宏的预处理指令,不是C语言中的内容。
int、struct和continue都是C语言中包含的关键字。
因此:选择C
8.用在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
9.关于C语言关键字说法正确的是:( )
A.关键字可以自己创建
B.关键字不能自己创建
C.关键字可以做变量名
D.typedef不是关键字
答案解析
C语言关键字:C语言定义的,具有特定含义、专门用于特殊用途的C语言标识符,也称为保留字
A:错误,关键字是语言自身定义的
B:正确
C:错误,关键字具有特殊含义,不能作为变量名
D:错误,typedef是用来给类型取别名的关键字
因此,选择B
10.关于字符的ASCII编码错误的是?
A.小写字母的ASCII码值+32就能得到对应的大写字母的ASCII码值
B.ASCII码值从0~31 这32个字符是非打印控制字符,在界面上不显示任何东西,比如:蜂鸣、回车、换行
C.数字字符0~9的ASCII码值是连续递增的
D.最初ASCII编码中只有128个字符的编码
答案解析
小写字母的ASCII码值-32就能得到对应的大写字母的ASCII码值
小写字母的ASCII码值比对应的大写字母的ASCII码值更大的。
11.字符串的结束标志是:( )
A.是'0'
B.是EOF
C. 是'\0'
D.是空格
答案解析:
C语言规定:以'\0'作为有效字符串的结尾标记
A:错误,是'\0'不是字符0
B:EOF一般用来作为检测文本文件的末尾
C:正确
D:明显错误
因此:选择C
12.下面代码的结果是:( )
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = {'b', 'i', 't'};
printf("%d\n", strlen(arr));
return 0;
}
答案解析:
strlen是用来获取字符串的有效长度的,结尾标记'\0'不包含在内。
strlen获取的规则非常简单:从前往后依次检测,直到遇到'\0'是就终止检测。
而上题中arr是一个字符数组,不是一个有效的字符串,因为后面没有放置'\0',因此strlen在求解时,将有效字符检测完之后,还会继续向后检测,直到遇到'\0'是才终止,因此答案为不确定,就看紧跟在't'之后的第一个'\0'在什么位置。
13.下面那个不是转义字符?
A.'\n'
B.'\060'
C.'\q'
D.'\b'
答案解析:
A:'\n' 转义字符,代表换行
B:'\060' 转义字符,060八进制数据,十进制为48,表示ASCII码为48的'0'
C:'\q' 什么都不是
D:'\b' 转义字符,表示退格
因此:选择C
14.下面程序的结果是:( )
#include <stdio.h>
#include <string.h>
int main()
{
printf("%d\n", strlen("c:\test\121"));
return 0;
}
答案解析:
strlen:获取字符串的有效长度,不包括'\0'
"c:\test\121": 在该字符串中,\t是转移字符,水平制表,跳到下一个tab的位置;而\121表示一个字符,是讲121看做8进制数组,转换为10进制后的81,作业为ASCII码值的字符,即:字符'Q' ,故上述字符串实际为:"c: estQ",只有7个有效字符
two
1.关于注释说法不正确的是?
A.注释是用来解释代码的,在代码中是适当的加上注释有利于代码的阅读和多人协作
B.注释基本没啥用,主要给自己看的
C.注释是给程序员看的,编译器在预处理阶段就会删除注释的
D.注释有C++注释风格,有C语言注释风格,推荐C++注释风格
答案解析
注释还是非常有用的,要学会写注释,能写注释,写好注释对工程中多人协作很关键的,写注释是一个程序员的好习惯。面试写代码,如果加上注释也是好的加分项。
2.关于C语言布尔类型错误的是?
A.C语言布尔类型是_Bool,使用需要包含头文件stdbool.h
B.布尔类型变量的取值是:true或者false
C.布尔类型是专门用来表示真和假的类型
D.布尔类型是C99标准之前就有的
答案解析
布尔类型是C99标准中引入的;
在早期的C语言标准(如ANSI C和C89)中,没有明确定义布尔类型。通常,程序员使用整数类型(如int)来表示布尔值,其中0表示假(false),非零值表示真(true)。
然而,在C99标准中引入了新的布尔类型(stdbool.h头文件),定义了bool类型和true/false常量。布尔类型只有两个取值:true和false,用于表示真和假。
3.下面哪个不是C语言内置的数据类型:
A.char
B.double
C.struct Stu
D.short
答案解析
C语言中内置类型包括:
char //字符数据类型 short //短整型 int //整形 long //长整型 long long //更长的整形 float //单精度浮点数 double //双精度浮点数
struct关键字是用户用来自定义的结构体类型,不属于C语言的内置类型。
因此:选择C
4.下面代码输出的结果是:( )
#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
5.关于C语言变量说法错误的是?
A.变量是用来描述生活中经常发生变化的值
B.变量可以分为局部变量和全局变量
C.局部变量是放在内存的静态区的,全局变量是放在内存的栈区
D.当全局变量和局部变量名字相同的情况,且都可以使用的时候,局部变量优先
答案解析
局部变量是放在内存的栈区的,全局变量是放在内存的静态区
6.关于C语言算术操作符说法正确的是?
A.除号两边都是小数才能执行小数除法
B.%操作符的操作数可以是整数,也可以是小数
C.%操作符计算的结果是两个操作数整除之后的商
D.负数求模的规则是,结果的正负号由第一个运算数的正负号决定。
答案解析
A:除号两边只要有一个是小数,就执行小数除法
B:%操作符的操作数只能是整数
C:%操作符计算的结果是两个操作数整除之后的余数
7.
下面代码输出的结果是啥:
#include <stdio.h>
int main()
{
int a = 7;
int b = 2;
float c = 2.0f;
printf("%d\n", 3);
printf("%f\n", a / c);
return 0;
}
A.3 3.500000
B.3.500000 3.500000
C.3.500000 3
D.3 3
答案解析
2个整数相除,执行的是整数除法,计算的结果也是整数
除法的2个操作数只要有一个数是浮点数,执行的就是小数除法,所以a/c是按照小数除法计算的,结果就是3.5
a/b 是按照整数除法计算的,结果是3.
8.计算带余除法
描述:给定两个整数a和b (0 < a,b < 10,000),计算a除以b的整数商和余数。
输入描述:一行,包括两个整数a和b,依次为被除数和除数(不为零),中间用空格隔开。
输出描述:一行,包含两个整数,依次为整数商和余数,中间用一个空格隔开。
答案
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int m = a/b;
int n = a%b;
printf("%d %d\n", m, n);
return 0;
}
9.被5整除问题
描述:判断一个整数是否能5整除是一个挺简单的问题,懒惰的KiKi还是不想自己做,于是找到你帮他写代码,你就帮帮他吧。
输入描述:输入包括一个整数M(1≤M≤100,000)。
输出描述:输出包括一行,如果M可以被5整除就输出YES,否则输出NO(结果大小写敏感)。
答案
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if(n%5==0)
printf("YES\n");
else
printf("NO\n");
return 0;
}
three
1.下面代码的结果是:( )
#include <stdio.h>
int main()
{
int a, b, c;
a = 5;
c = ++a;
b = ++c, c++, ++a, a++;
b += a++ + c;
printf("a = %d b = %d c = %d\n:", a, b, c);
return 0;
}
A.a = 8 b = 23 c = 8
B.a = 9 b= 23 c = 8
C.a = 9 b = 25 c = 8
D.a = 9 b = 24 c = 8
答案解析:
++运算符:分为前置++和后置++,
前置++:先加1,后使用,即先使用变量中内容,然后给结果加1
后置++:先使用变量中内容,整个表达式结束时,给变量加1
逗号表达式,取最后一个表达式的值。
#include <stdio.h>
int main()
{
int a, b, c;
a = 5;
c = ++a;// ++a:加给a+1,结果为6,用加完之后的结果给c赋值,因此:a = 6 c = 6
b = ++c, c++, ++a, a++;
// 逗号表达式的优先级,最低,这里先算b=++c, b得到的是++c后的结果,b是7
// b=++c 和后边的构成逗号表达式,依次从左向右计算的。
// 表达式结束时,c++和,++a,a++会给a+2,给c加1,此时c:8,a:8,b:7
b += a++ + c; // a先和c加,结果为16,在加上b的值7,比的结果为23,最后给a加1,a的值为9
printf("a = %d b = %d c = %d\n:", a, b, c); // a:9, b:23, c:8
return 0;
}
因此:选择B
2.关于scanf函数说法正确的是?
A.scanf中也有占位符,占位符和后边的参数提供的地址一一对应。
B.scanf()处理所有占位符时,会自动过滤起首的空白字符,包括空格、制表符、换行符
C.scanf的占位符%s表示读取一个字符串,遇到空白字符也全部读取
D.scanf是库函数,库函数不需要包含头文件
答案解析
B:scanf()处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符,scanf输出字符占位符的时候,不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。
C:scanf的占位符%s表示读取一个字符串,遇到空白字符就停止读取。
D:scanf需要包含stdio.h这个头文件的
3.关于printf函数说法错误的是?
A.printf()的作用是将参数文本输出到屏幕。它名字里面的f代表format(格式化),表示可以定制输出文本的格式。
B.printf()不会在行尾自动添加换行符,运行结束后,光标就停留在输出结束的地方,不会自动换行。
C.printf()可以在输出文本中指定占位符,“占位符”,就是这个位置可以用其他值代入。
D.printf()参数与占位符是一一对应关系,如果有n个占位符,printf()的参数就应该有n个
答案解析
printf()参数与占位符是一一对应关系,如果有n个占位符,printf()的参数就应该有n+1个
4.下面程序输出的结果是啥:
#include <stdio.h>
int main()
{
printf("%5d\n", 123456);
return 0;
}
A.12345
B.123456
C.23456
D.0
答案解析
printf()
允许限定占位符的最小宽度。%5d
表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。如果超过5位,正常输出就行,5是最少输出5位。
5.你是天才吗?
描述据说智商140以上者称为天才,KiKi想知道他自己是不是天才,请帮他编程判断。输入一个整数表示一个人的智商,如果大于等于140,则表明他是一个天才,输出“Genius”。
多组输入,每行输入包括一个整数表示的智商。
输出描述:针对每行输入,输出“Genius”
答案
#include <stdio.h>
int main()
{
int n = 0;
while(scanf("%d", &n) != EOF)
{
if(n>=140)
printf("Genius");
}
return 0;
}
6.判断2个数的大小
描述:KiKi想知道从键盘输入的两个数的大小关系,请编程实现。
输入描述:题目有多组输入数据,每一行输入两个整数(范围-231~231-1),用空格分隔。
输出描述:针对每行输入,输出两个整数及其大小关系,数字和关系运算符之间没有空格,详见输入输出样例。
答案
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
while(scanf("%d%d", &num1, &num2) != EOF)
{
if(num1>num2)
printf("%d>%d\n", num1, num2);
else if(num1<num2)
printf("%d<%d\n", num1, num2);
else
printf("%d=%d\n", num1, num2);
}
return 0;
}
7.线段图案
描述:KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的线段图案。
输入描述:多组输入,一个整数(1~100),表示线段长度,即“*”的数量。
输出描述:针对每行输入,输出占一行,用“*”组成的对应长度的线段。
答案
#include <stdio.h>
int main()
{
int n = 0;
while(scanf("%d", &n)!=EOF)
{
int i = 0;
for(i=0; i<n; i++)
{
printf("*");
}
printf("\n");
}
return 0;
}
four
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.打印3的倍数的数
写一个代码打印1-100之间所有3的倍数的数字
/*
解题思路:
1. 3的倍数一定能够被3整除,因此i%3==0表达式成立时,则i一定是3的倍数
2. 要输出1~100之间的3的倍数,那只需要从1~100循环100次即可,每次拿到i之后,用i%3==0检测
如果成立:i是3的倍数,输出
如果不成立:i不是3的倍数
*/
#include <stdio.h>
int main()
{
int i = 0;
for(i=1; i<=100; i++)
{
if(i%3==0)
{
printf("%d ", i);
}
}
return 0;
}
3.从大到小输出
写代码将三个整数数按从大到小输出。
例如:
输入:2 3 1
输出:3 2 1
/*
思路:
该题比较简单,参考代码
*/
#include <stdio.h>
int main()
{
int a = 2;
int b = 3;
int c = 1;
scanf("%d%d%d",&a, &b,&c);
if(a<b)
{
int tmp = a;
a = b;
b = tmp;
}
if(a<c)
{
int tmp = a;
a = c;
c = tmp;
}
if(b<c)
{
int tmp = b;
b = c;
c = tmp;
}
printf("a=%d b=%d c=%d\n", a, b, c);
return 0;
}
4.关于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
5.关于关系操作符说法错误的是?
A.C语言的关系操作符就是用来比较大小关系的
B.关系操作符中判断是否相等使用==
C.==操作符可以用来比较2个字符串是否相等
D.关系操作符参与的关系表达式,通常返回0或1,表示真假
答案解析
两个字符串是否相等不能使用==,应该使用strcmp函数
6.关于逻辑操作符说法错误的是?
A.&& 表示并且
B.|| 表示或者
C.|| 操作符的两个操作数只要有一个是假,则表达式结果为假
D.&& 短路的时候,&&的左边操作数为假,右边不再计算
答案解析
C:|| 操作符的两个操作数只要有一个是真,则表达式结果为真,两个同时为假,才为假
7.关于switch说法不正确的是:( )
A.switch语句中的default子句可以放在任意位置
B.switch语句中case后的表达式只能是整形常量表达式
C.switch语句中case子句必须在default子句之前
D.switch语句中case表达式不要求顺序
答案解析:
A:正确,可以放在任意位置,但是一般建议最好还是放在最后
B:正确,case语句后一般放整形结果的常量表达式或者枚举类型,枚举类型也可以看成是一个特殊的常量
C:错误,没有规定case必须在default之前,一般case最好放在default之前
D:正确,但一般还是按照次序来
因此:选择C
8.
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
9.switch(c)语句中,c不可以是什么类型( )
A.int
B.long
C.char
D.float
答案解析:
switch语句中表达式的类型只能是:整形和枚举类型
D选项为浮点类型,不是整形和枚举类型
因此:选择D
10.下面代码的执行结果是什么( )
#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
11.三角形判断
描述:KiKi想知道已经给出的三条边a,b,c能否构成三角形,如果能构成三角形,判断三角形的类型(等边三角形、等腰三角形或普通三角形)。
输入描述:题目有多组输入数据,每一行输入三个a,b,c(0<a,b,c<1000),作为三角形的三个边,用空格分隔。
输出描述:针对每组输入数据,输出占一行,如果能构成三角形,等边三角形则输出“Equilateral triangle!”,等腰三角形则输出“Isosceles triangle!”,其余的三角形则输出“Ordinary triangle!”,反之输出“Not a triangle!”
答案
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
int c = 0;
while(~scanf("%d %d %d", &a, &b, &c))
{
if((a+b>c) && (a+c>b) && (b+c>a))
{
//三角形
if(a==b && b==c)//等边三角形
{
printf("Equilateral triangle!\n");
}
else if(((a==b)&&(b!=c)) || ((a==c)&&(c!=b)) || ((b==c)&&(c!=a)))//等腰
{
printf("Isosceles triangle!\n");
}
else
{
printf("Ordinary triangle!\n");
}
}
else
{
//不是三角形
printf("Not a triangle!\n");
}
}
return 0;
}
12.数9的个数
编写程序数一下 1到 100 的所有整数中出现多少个数字9
答案
/*
思路:
1. 给一个循环从1遍历到100,拿到每个数据后进行一下操作
2. a. 通过%的方式取当前数据的个位,检测个位数据是否为9
如果是,给计数器加1
b. 通过/的方式取当前数据的十位,检测十位数据是否是9,
如果是,给计数器加1
循环一直继续,直到所有的数据检测完,所有9的个数已经统计在count计数中。
*/
#include <stdio.h>
int main()
{
int i = 0;
int count = 0;
for(i=1; i<=100; i++)
{
if(i%10==9)
count++;
if(i/10==9)
count++;
}
printf("%d\n", count);
return 0;
}
five
1.有以下程序
#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
2.关于while(条件表达式) 循环体,以下叙述正确的是( )? (假设循环体里面没有break,continue,return,goto等等语句)
A.循环体的执行次数总是比条件表达式的执行次数多一次
B.条件表达式的执行次数总是比循环体的执行次数多一次
C.条件表达式的执行次数与循环体的执行次数一样
D.条件表达式的执行次数与循环体的执行次数无关
答案解析:
while(条件表达式)
循环体
while循环中,当条件表达式成立时,才会执行循环体中语句,每次执行期间,都会对循环因子进行修改(否则就成为死循环),修改完成后如果while条件表达式成立,继续循环,如果不成立,循环结束
故:while循环条件将会比循环体多执行一次。
因此:选择B
3.关于rand函数说法错误的是?
A.rand函数生成了0~32767之间的随机数
B.rand函数生成的是真正的随机数
C.rand函数在使用之前,需要调用srand函数设置随机数的生成器
D.rand函数的使用需要包含stdlib.h的头文件
答案解析
B:rand函数生成的是伪随机数,是通过某种算法生成的随机数
4.猜数字游戏
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
void menu()
{
printf("********************************\n");
printf("******* 1. play *******\n");
printf("******* 0. exit *******\n");
printf("********************************\n");
}
void game()
{
//RAND_MAX-32767
//1.生成随机数
//讲解rand函数
int ret = rand() % 100 + 1;
int num = 0;
//2.猜数字
while (1)
{
printf("请猜数字:>");
scanf("%d", &num);
if (num == ret)
{
printf("恭喜你,猜对了\n");
break;
}
else if (num > ret)
{
printf("猜大了\n");
}
else
{
printf("猜小了\n");
}
}
}
int main()
{
int input = 0;
//讲解srand函数
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
5.在屏幕上输出9*9乘法口诀表
/*
思路:
两个循环进行控制
外层循环控制打印多少行
内部循环控制每行打印多少个表达式以及表达式内容,
比较简单,具体参考代码
*/
#include <stdio.h>
int main()
{
int i = 0;
//控制行数
for(i=1; i<=9; i++)
{
//打印每一行内容,每行有i个表达式
int j = 0;
for(j=1; j<=i; j++)
{
printf("%d*%d=%2d ", i, j, i*j);
}
printf("\n");
}
return 0;
}
6.求10 个整数中最大值
/*
思路:
1. 采用循环的方式输入一个数组
2. 使用max标记数组中的最大值,采用循环的方式依次获取数组中的每个元素,与max进行比较,如果arr[i]大于 max,更新max标记的最大值,数组遍历结束后,max中保存的即为数组中的最大值。
*/
int main()
{
int arr[10] = {0};
int i = 0;
int max = 0;
for(i=0; i<10; i++)
{
scanf("%d", &arr[i]);
}
//
max = arr[0];
for(i=1; i<10; i++)
{
if(arr[i]>max)
max = arr[i];
}
printf("max = %d\n", max);
return 0;
}
7.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果
/*
思路:
1. 从上述表达式可以分析出
a. 该表达式主要由100项,基数项为正,偶数项为负
2. 设置一个循环从1~100,给出表达式中的每一项:1.0/i, 注意此处不能使用1,否则结果全部为0
然后使用flag标记控制奇偶项,奇数项为正,偶数项为负
然后将所有的项相加即可
*/
#include <stdio.h>
int main()
{
int i = 0;
double sum = 0.0;
int flag = 1;
for(i=1; i<=100; i++)
{
sum += flag*1.0/i;
flag = -flag;
}
printf("%lf\n", sum);
return 0;
}
8.写一个代码:打印100~200之间的素数
/*
思路:
素数:即质数,除了1和自己之外,再没有其他的约数,则该数据为素数,具体方式如下
*/
//方法一:试除法
int main()
{
int i = 0;
int count = 0;
// 外层循环用来获取100~200之间的所有数据,100肯定不是素数,因此i从101开始
for(i=101; i<=200; i++)
{
//判断i是否为素数:用[2, i)之间的每个数据去被i除,只要有一个可以被整除,则不是素数
int j = 0;
for(j=2; j<i; j++)
{
if(i%j == 0)
{
break;
}
}
// 上述循环结束之后,如果j和i相等,说明[2, i)之间的所有数据都不能被i整除,则i为素数
if(j==i)
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
//上述方法的缺陷:超过i一半的数据,肯定不是i的倍数,上述进行了许多没有意义的运算,因此可以采用如下
// 方式进行优化
// 方法二:每拿到一个数据,只需要检测其:[2, i/2]区间内是否有元素可以被2i整除即可,可以说明i不是素数
int main()
{
int i = 0;//
int count = 0;
for(i=101; i<=200; i++)
{
//判断i是否为素数
//2->i-1
int j = 0;
for(j=2; j<=i/2; j++)
{
if(i%j == 0)
{
break;
}
}
//...
if(j>i/2)
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
/*
方法二还是包含了一些重复的数据,再优化:
如果i能够被[2, sqrt(i)]之间的任意数据整除,则i不是素数
原因:如果 m 能被 2 ~ m-1 之间任一整数整除,其二个因子必定有一个小于或等于sqrt(m),另一个大于或等于 sqrt(m)。
*/
int main()
{
int i = 0;
int count = 0;
for(i=101; i<=200; i++)
{
//判断i是否为素数
//2->i-1
int j = 0;
for(j=2; j<=sqrt(i); j++)
{
if(i%j == 0)
{
break;
}
}
//...
if(j>sqrt(i))
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
//方法4
/*
继续对方法三优化,只要i不被[2, sqrt(i)]之间的任何数据整除,则i是素数,但是实际在操作时i不用从101逐渐递增到200,因为出了2和3之外,不会有两个连续相邻的数据同时为素数
*/
int main()
{
int i = 0;
int count = 0;
for(i=101; i<=200; i+=2)
{
//判断i是否为素数
//2->i-1
int j = 0;
for(j=2; j<=sqrt(i); j++)
{
if(i%j == 0)
{
break;
}
}
//...
if(j>sqrt(i))
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
9.打印1000年到2000年之间的闰年
/*
思路:
要求1000年到2000年之间的闰年,只需要知道求解闰年的方法即可。
闰年的条件:如果N能够被4整除,并且不能被100整除,则是闰年
或者:N能被400整除,也是闰年
即:4年一润并且百年不润,每400年再润一次
*/
#include <stdio.h>
int main()
{
int year = 0;
for(year=1000; year<=2000; year++)
{
//判断year是否为闰年
if(year%4==0) // 如果year能够被4整除,year可能为闰年
{
if(year%100!=0) // 如果year不能内100整除,则一定是闰年
{
printf("%d ", year);
}
}
if(year%400 == 0) // 每400年再润一次
{
printf("%d ", year);
}
}
return 0;
}
//
//介绍一下这种的简单写法
//
int main()
{
int year = 0;
for(year=1000; year<=2000; year++)
{
if(((year%4==0)&&(year%100!=0))||(year%400==0))
{
printf("%d ", year);
}
}
return 0;
}
10.给定两个数,求这两个数的最大公约数
/*
最大公约数:即两个数据中公共约数的最大者。
求解的方式比较多,暴力穷举、辗转相除法、更相减损法、Stein算法算法
此处主要介绍:辗转相除法
思路:
例子:18和24的最大公约数
第一次:a = 18 b = 24 c = a%b = 18%24 = 18
循环中:a = 24 b=18
第二次:a = 24 b = 18 c = a%b = 24%18 = 6
循环中:a = 18 b = 6
第三次:a = 18 b = 6 c=a%b = 18%6 = 0
循环结束
此时b中的内容即为两个数中的最大公约数。
*/
int main()
{
int a = 18;
int b = 24;
int c = 0;
while(c=a%b)
{
a = b;
b = c;
}
printf("%d\n", b);
return 0;
}
six
1.关于一维数组描述不正确的是:( )
A.数组的下标是从0开始的
B.数组在内存中是连续存放的
C.数组名表示首元素的地址
D.随着数组下标的由小到大,地址由高到低
答案解析:
A:正确,C语言规定,数组的下标是从0开始的
B:正确,数组的空间是一段连续的内存空间
C:正确,数组名既可以表示数组的地址,也可以表示数组首元素的地址,两个在数值上是一样的,但是含义不一样。
注意:数组名只有在sizeof和&后才代表整个数组,其它都表示首元素的地址
D:错误,这个要是系统而定,一般都是下标由小到大,地址由低到高
因此,选择D
2.关于一维数组初始化,下面哪个定义是错误的?( )
A.int arr[10] = {1,2,3,4,5,6};
B.int arr[] = {1,2,3,4,5,6};
C.int arr[] = (1,2,3,4,5,6);
D.int arr[10] = {0};
答案解析:
A:正确,10个int的一段连续空间,前6个位置被初始化为1,2,3,4,5,6,其他位置为0
B:正确,数组中有6个空间,并被初始化为1,2,3,4,5,6
C:错误,数组的初始化不能使用(),只能使用{}
D:正确,10个int类型的一段连续空间,每个位置都被初始化为0
因此,选择C
3.定义了一维 int 型数组 a[10] 后,下面错误的引用是:( )
A.a[0] = 1;
B.a[0] = 5*2;
C.a[10] = 2;
D.a[1] = a[2] * a[0];
答案解析:
数组是相同类型的一段连续的空间,下标是从0开始的,比如:int array[N]
下标的范围为[0,N),其中N位置不能存储有效元素
A:正确,将0号位置设置为1
B:正确,将0号位置设置为10
C:错误,越界
D:正确,1号位置初始化为a[2]*a[0]之后的结果
因此,选择C
4.以下能对二维数组a进行正确初始化的语句是:( )
A.int a[2][]={{0,1,2},{3,4,5}};
B.int a[][3]={{0,1,2},{3,4,5}};
C.int a[2][4]={{0,1,2},{3,4},{5}};
D.int a[][3]={{0,,2},{},{3,4,5}};
答案解析:
对于二维数组int array[M][N], 说明如下:
1. M和N都必须为常数,
2. M代表数组有M行,N代表每行中有N个元素
3. 其中M可以省略,省略后必须给出初始化表达式,编译器从初始化结果中推断数组有多少行
4. N一定不能省略,因为N省略了就不能确定一行有多少个元素,也不能确定数组有多少行
A:错误,参数上述说明
B:正确,参考上述说明
C:错误,数组有两行,但是初始化给了三行
D:错误,初始化不允许{0,,2}该种情况存在
因此,选择B
5.若定义int a[2][3]={1,2,3,4,5,6};则值为4的数组元素是( )
A.a[0][0]
B.a[1][0]
C.a[1][1]
D.a[2][1]
答案解析:
int a[2][3]表示2行3列的二维数组,根据其初始化知:
第0行即a[0]存储3个元素: 1,2,3
第1行即a[1]存储3个元素: 4,5,6
因此值为4的元素在第1行第0列
因此,选择B
6.
给出以下定义:
char acX[] = "abcdefg";
char acY[] = { 'a','b','c','d','e','f','g'};
以下说法正确的是( )
A.数组acX和数组acY等价
B.数组acX和数组acY的长度相同
C.sizeof(acX)>sizeof (acY)
D.strlen (acX)>strlen (acY)
答案解析:
acX和acY都是字符数组,但是初始化表达式不同,acX和acY的区别如下:
acX:数组中总共有8个元素,分别是:'a','b','c','d','e','f','g','\0'
acY:数组中总共有7个元素,分别是:'a','b','c','d','e','f','g'
sizeof这里求的是数组大小,数组大小等于有效元素个数*每个元素的大小。sizeof(acX) = 8,sizeof(acY) = 7
strlen求的是字符串长度,从首元素开始计算,遇见‘\0’停止,由于acY数组没有'\0‘,所以strlen(acY)的结果是个随机值
因此,选择C
7.下面代码的结果是:( )
#include <stdio.h>
int main()
{
int arr[] = {1,2,(3,4),5};
printf("%d\n", sizeof(arr));
return 0;
}
A.4
B.16
C.20
D.5
答案解析:
对于int arr[] = {1,2,(3,4),5}数组,里面总共有4个元素,(3,4)为逗号表达式,取后者,因此数组中元素分别为:1,2,4,5
而sizeof(arr)求的是整个数组所占空间的大小,即:4*sizeof(int)=4*4=16
因此,选择B
8.下面代码的结果是:( )
#include <stdio.h>
int main()
{
char str[] = "hello bit";
printf("%d %d\n", sizeof(str), strlen(str));
return 0;
}
A.10 9
B.9 9
C.10 10
D.9 10
答案解析:
str字符数组使用"hello bit"初始化,最终也会将'\0'放置到数组中,因此数组中总共有10个元素
sizeof(str):获取数组的总大小,10个元素,每个元素占1个字节,因此总共是10个字节
strlen(str): 获取字符串中有效字符的个数,不算'\0',因此总共9个有效字符
故上述printf会分别打印:10 9
因此,选择A
9.在C语言中,以下哪个选项描述了变长数组(Variable Length Array,VLA)的特点?
A.变长数组的大小在编译时确定,不能改变。
B.变长数组的大小可能在运行时确定,比如使用变量来指定数组大小,一旦确定大小后,它的大小是固定的,无法改变。
C.一旦确定大小后,它的大小是固定的,无法改变
D.变长数组只能用于存储字符类型的数据。
答案解析
变长数组( variable-length array),C语言术语,也简称VLA。是指用 整型变量或表达式声明或定义的数组 ,而不是说数组的长度会随时变化,变长数组在其生存期内的长度同样是固定的 。
代码示例:
int n;
scanf ("%d", &n);
int array[n];
注意上述语法在C99之前是不支持的。
A选项错误:编译时无法确定,编译时候编译器不知道n是什么值,n的值要等到程序运行起来后,用户输入之后n的值确定了,才能确定数组的大小
B选项:说法不严谨,一定是在运行时确定大小的,而不是可能
C选项正确
D选项错误:存储什么类型数据,看定义时候给数组名前放什么类型,比如int a[n]就是存放int类型 short a[n]就是存在short类型
10.空心正方形图案
描述:KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的“空心”正方形图案。
输入描述:多组输入,一个整数(3~20),表示输出的行数,也表示组成正方形边的“*”的数量。
输出描述:针对每行输入,输出用“*”组成的“空心”正方形,每个“*”后面有一个空格。
#include <stdio.h>
int main()
{
int n = 0;
while(scanf("%d", &n) != EOF)
{
int i = 0;
int j = 0;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(i==0 || i==n-1)
printf("* ");
else if(j==0 || j==n-1)
printf("* ");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
11.矩阵转置
描述:KiKi有一个矩阵,他想知道转置后的矩阵(将矩阵的行列互换得到的新矩阵称为转置矩阵),请编程帮他解答。
输入描述:第一行包含两个整数n和m,表示一个矩阵包含n行m列,用空格分隔。 (1≤n≤10,1≤m≤10)
从2到n+1行,每行输入m个整数(范围-231~231-1),用空格分隔,共输入n*m个数,表示第一个矩阵中的元素。
输出描述:输出m行n列,为矩阵转置后的结果。每个数后面有一个空格。
#include <stdio.h>
int main()
{
int n = 0;
int m = 0;
scanf("%d%d", &n, &m);
int a[n][m];
int i = 0;
int j = 0;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
scanf("%d", &a[i][j]);
}
}
//转置
for(i=0; i<m; i++)//3
{
for(j=0; j<n; j++)//2
{
printf("%d ", a[j][i]);
}
printf("\n");
}
return 0;
}
12. 逆序输出
描述:输入10个整数,要求按输入时的逆序把这10个数打印出来。逆序输出,就是按照输入相反的顺序打印这10个数。
输入描述:一行,输入10个整数(范围-231~231-1),用空格分隔。
输出描述:一行,逆序输出输入的10个整数,用空格分隔。
#include <stdio.h>
int main()
{
int arr[10] = {0};
int i= 0 ;
for(i=0; i<10; i++)
{
scanf("%d", &arr[i]);
}
for(i=9; i>=0; i--)
{
printf("%d ", arr[i]);
}
return 0;
}
13. 【一维数组】输入10个整数,求平均值
编写一个程序,从用户输入中读取10个整数并存储在一个数组中。然后,计算并输出这些整数的平均值。
#include <stdio.h>
int main() {
int numbers[10];
int sum = 0;
// 读取用户输入的整数并存储到数组中
for (int i = 0; i < 10; i++) {
scanf("%d", &numbers[i]);
sum += numbers[i];
}
double average = (double)sum / 10;
printf("平均值为:%lf\n", average);
return 0;
}
14. 【一维数组】交换数组
将数组A中的内容和数组B中的内容进行交换。(数组一样大)
/*
思路:题目比较简单,请参考代码以及注释
*/
#include <stdio.h>
int main()
{
int arr1[10] = {0};
int arr2[10] = {0};
int i = 0;
printf("请输入10个数字:>");
for(i=0; i<10; i++)
{
scanf("%d", &arr1[i]);
}
printf("请输入10个数字:>");
for(i=0; i<10; i++)
{
scanf("%d", &arr2[i]);
}
//交换
for(i=0; i<10; i++)
{
int tmp = arr1[i];
arr1[i] = arr2[i];
arr2[i] = tmp;
}
return 0;
}