马上c语言考试了,写一篇博客根据考试范围对应了一下之前微信里老师发过的习题(考试会有很多原题),把题目整理一下,也帮助一下身边的小伙伴。欢迎评论交流。(补充后两章完整版)
一、考试范围
二、各章微信习题整理
第一章习题与知识点
1.一个c语言的执行总是从main函数开始,也从main函数结束。✔
2.c语言本身没有输入输出语句。✔
(c语言的输出输出是调用库函数中提供的函数,例如printf和scanf两个函数.)
3.在c程序中,注释说明只能位于一条语句的后面。✖
(c语言中注释可以随处)
第二章习题与知识点
1.合法标识符*:
①由字母、数字和下划线组成的字符序列,其中第一个字符不能是数字。
②自定义标识符不能用关键字(如:int,char,if…)和预定义标识符(如:scanf,printf,define…),且区分大小写。
2.c语言中,不能表示整数常量的数制是二进制。
(在C语言中,只支持8进制,10进制,16进制。除了这三种外,其它进制均是不支持的)
3.表达式1/2的值是0;表达式1.0/2的值是0.5
前者是整数除法,后者是浮点数除法)
4.c语言的基本数据类型有字符型,整型,实型(浮点型)。并没有数组类型。
5.正确定义和赋值练习:
(1)写出代码为n1赋值10,为n2也赋值10
int n1=10,n2=10;(看清逗号和分号的位置,不能连等)
(2)给定代码段: int a,b=0;则a的初始值是0?✖
只是将b的初始值设置为0,a的值不能确定。
(3)有语句scanf(“a=%d,b=%d”,&a,&b),从键盘输入数据的正确形式应该是什么?
答:a=1,b=2 scanf语句引号内除了要输入的变量,其他要原样输出。
6.现有以下语句
#include<stdio.h>
int main()
{
int a,b;
scanf(“%d %d”,a,b);
return 0;
}
1
2
3
4
5
6
7
用户从键盘输入3 5后,程序的结果是_____。
答:程序将崩溃。
(因为scanf语句中忘记了写入取地址符&,会导致程序崩溃)
第三章习题与知识点
1.写出程序运行结果
#include<stdio.h>
int main()
{
int a,b,s;
scanf(“%2d%2d”,&a,&b);
s=a/b;
printf(“s=%d”,s);
return 0;
}
1
2
3
4
5
6
7
8
9
10
运行:
运行结果为s=1。这是因为%2d限制了a和b只读取了两位数,即输入54321后a的值为54,而b的值为32,s=54/32,由于是整数除法,结果为1。
2写出程序的运行结果
#include<stdio.h>
int main()
{
int a=1234;
printf(“%2d\n”,a);
return 0;
}
1
2
3
4
5
6
7
8
运行:
运行结果为输出1234。为什么1234没有被截断为12呢?
这是因为如果数据的实际位宽<域宽修饰符的位宽输出就会被添上空格填满域宽区域,这些数值是右对齐的。
如果数据的实际位宽>=域宽修饰符的位宽输出就忽略宽度修饰符,如实地输出a。
3.写出程序的运行结果
#include<stdio.h>
int main()
{
char c1=‘a’,c2=‘b’,c3=‘c’;
printf(“a%cb%cc%cabc\n”,c1,c2,c3);
return 0;
}
1
2
3
4
5
6
7
8
运行:
运行结果为:aabbccabc。
三个%c依次被写入c1→%c,c2→%c,c3→%c。printf语句内除了三个%c外的其他字符原样输出为a_b_c_abc。三个_上依次为c1,c2,c3。
4.写出程序的运行结果
#include<stdio.h>
int main()
{
int a=2,c=5;
printf(“a=%%d,b=%%d\n”,a,c);
return 0;
}
1
2
3
4
5
6
7
8
运行:
运行结果为:a=%d,b=%d
在此说明一下c语言中%%d的含义:%%d 在c语言中会被拆成两部分看待,“%%”就是输出一个“%”,而是“d”就是一个普通字符,所以当“%%d”在一起时,其含义就是输出“%d”这两个字符。
第四章习题与知识点
1.以下语句是否可以通过编译:if(i<=n<=10);
答:不能。
编程语句不能连写。if(1<=n<=10)执行过程是这样的:先判断 1<=n ,判断结果为0或1,然后再判断(1<=n)的整体值(0或1)是否小于等于10,结果为1。这并不能表示n介于1到10之间的判断。如果要执行n介于1到10之间的判断,应表示为:if( n>=1 && n<=10 ) ;。
2.判断:if语句中,if后面的表达式可以是关系表达式与逻辑表达式,而不能是算术表达式。✖
if语句中,if语句后的表达式不限于逻辑或关系表达式,可以是任意的数值类型。即可以使任意的算术表达式。
3.写出程序的运行结果
#include<stdio.h>
int main()
{
int i,j,k;
i=5,j=10;k=1;
printf(“%d”,k>i<j);
return 0;
}
1
2
3
4
5
6
7
8
9
运行:
运行结果为:1。
printf(“%d”,k>i<j);的执行过程是这样的:相当于printf(“%d”,1>5<10),对于1>5<10中,先计算1>5,结果为false(0),再计算0<10,结果为ture(1)。所以式子1>5<10的值为1。
4.写出程序的运行结果
#include<stdio.h>
int main()
{
int i,j,k;
i=2;j=3;
k=i*j==6;
printf(“%d\n”,k);
return 0;
}
1
2
3
4
5
6
7
8
9
10
运行:
运行结果为:1。
k=ij==6;的执行过程是这样的:赋值运算符的优先级低于比较运算符,所以首先计算ij==6,结果为ture(1),再进行赋值运算k=1。因此最终输出k的值为1。
5.写出程序的运行结果:
#include<stdio.h>
int main()
{
int a=56;
if(a>50) printf(“A”);
if(a>40) printf(“B”);
if(a>30) printf(“C”);
return 0;
}
1
2
3
4
5
6
7
8
9
10
运行:
运行结果为:ABC。
很显然,56>50,56>40,56>30都成立。所以三个结果都输出。
6.写出表达式判断ch是大写或者小写英文字母
ch>='A' && ch<='Z' || ch>='a' && ch<='z'
1
7.下列符合语句能否实现两数交换
{
a=b;
b=a;
}
1
2
3
4
5
答:不能,这样的赋值运算会使得a和b的最终值都为b。
第五章习题与知识点
1.switch语句后的括号内表达式为___类型。
答:整型,字符型或枚举型。
2.判断:同一个switch语句中各个常量表达式的值必须互不相等,且只能是常量。✔
switch()语句的括号内的表达式要与case 里的值相呼应,因而各个常量表达式的值必须互不相等。
3.写出程序的运行结果
#include<stdio.h>
int main()
{
int i=1;
switch(i%3)
{
case 0:printf(“zero”);
case 1:printf(“one”);
case 2:printf(“two”);
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
运行:
运行结果为:onetwo。
首先计算i%3的值为1,接下来运行对应的case 1,输出one,由于没有break,所以会依次运行case 2,输出two。
第六章习题与知识点
1.以下四条循环中哪一条与其它三条不等价(假设循环体都是一样的)
A.for(i=0;i<10;i++){…}
B.for(i=0;i<10;++i){…}
C.for(i=0;i++<10;){…}
D.for(i=0;i<=9;i++){…}
1
2
3
4
答:B。其它三条语句的循环次数都为9,而B中++i表明计数是从0+1开始,到9结束,循环次数为8。
2.判断:while循环的条件满足时循环继续,而do-while的条件满足时循环就结束了。✖
后半句话不对,do-while语句构成的循环只有在while后的表达式为零时结束循环。
3.写出程序的运行结果:
#include<stdio.h>
int main()
{
int i=10;
while(i>0)
{
i/=2;
}
printf(“%d”,i);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
运行:
运行结果为:0。
while循环体的执行过程是这样的:10/2=5,5/2=2,2/2=1,1/2=0。最终结果为0,(所有计算都为整数除法)
4.写出程序运行结果:
#include<stdio.h>
int main()
{
int i;
for(i=10;i>1;i/=2)
{
printf(“%d”,i++);
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
运行:
运行结果为:10532。
for循环的执行过程是这样的:10>1,输出10。(10+1)/2值为5,5>1,输出5。(5+1)/2值为6,6>1,输出3。(3+1)/2值为2,2>1,输出2。所以依次连起来就是10532。
5.写出程序运行结果:
#include<stdio.h>
int main()
{
int sum=0;
int i=0;
for(i=0;i<10;i++)
{
if(i%2) continue;
sum+=i;
}
printf(“%d\n”,sum);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
运行:
运行结果为:20。
语句if(i%2) continue;的意思是当if后括号内的表达式值为ture(非0),则continue(跳过)该次for循环,强制进行下一次循环。也就是说当表达式的值非0时,全部跳过。
则for循环的10次执行是这样的:
0%2=0 ✔
1%2=1 continue
2%2=0 ✔
3%2=1 continue
4%2=0 ✔
5%2=1 continue
6%2=0 ✔
7%2=1 continue
8%2=0 ✔
9%2=1 continue
所有执行的语句后打✔,则相应的i值为0,2,4,6,8。总和sum的值为0+2+4+6+8,等于20。
三、编程题整理
1.分段函数
代码如下:
#include<stdio.h>//s所有结果都保留了两位小数
int main()
{
double x;//由于结果有小数,这里用double类型
scanf(“%lf”,&x);
if(x<0)//x<0
printf(“f(x)=%.2lf”,2x-1);
else if(x>=0 && x<3)//0<=x<3
printf(“f(x)=%.2lf”,3x+5);
else if(x>=3 && x<10)//3<=x<10
printf(“f(x)=%.2lf”,5x-3);
else if(x>=10)//x>=100
printf(“f(x)=%.2lf”,7x+2);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2.循环编程计算i*(i+1)*(i+2)的值
代码如下:
#include<stdio.h>
int main()
{
int i=1,sum=1,p;
scanf(“%d”,&i);//输入i的值
p=i+2;
while(i<=p)//循环三次
{
sum*=i;
i++;
}
printf(“%d”,sum);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
输入1,计算1乘2乘3的值,输出结果为:6
3.函数编程画三角形(此处假设为直角三角形且直角在左下角)
代码如下:
#include<stdio.h>
void f(int n);
int main()
{
int n;
scanf(“%d”,&n);
f(n);
return 0;
}
void f(int n)
{
int i,j;
for(i=1; i<=n; i++)
{
for(j=1; j<=i; j++)
{
printf(“* “);
}
printf( “\n” );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
输入3,输出边长为3的直角三角形:
4.数组编程统计操行分
代码如下
#include<stdio.h>
#define N 51//班级50人,定义N为50+1
int main()
{
int i=1,a[N]={0},fen;
do{
printf(“请输入学号和操行分:”);
scanf(“%d %d”,&i,&fen);
a[i]+=fen;//将学号为i的分数累加到对应的a[i]中
}while(i>0&&i<=50);// 循环继续条件为0<i<=50
printf(“学号 操行总分\n”);
for(i=1;i<51;i++)
{
printf(” %d %d\n”,i,a[i]);
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
输出结果:
5.据说是c语言院考最后一道编程题。
定义函数根据输入的字符输出对应的文字,如下所示
A.安全
D.约会
M.美丽
G.歌剧
代码如下:
#include<stdio.h>
void f(char c)
{
if(c=='A') printf("安全\n");
if(c=='D') printf("约会\n");
if(c=='M') printf("美丽\n");
if(c=='G') printf("歌剧\n");
}
int main()
{
char c;
while(scanf("%s",&c)!=EOF)
f(c);
return 0;
}
第七章习题与知识点
1 一些字符无法从键盘输入为解决此问题c语言中提供了一种特殊的字符表示法———转移序列。
;
2 字符数据的输入问题
读入单个字符有
ch=getchar();
scanf(”%c”,&ch);
问题:scanf(),和getchar()都会把空格读入到对应的空格中;
两种常用的解决方法
法一:在其中插入getchar();将缓冲区的回车符读入;
法二:为了使scanf()函数在读入字符时跳过空白符,需要在格式串中的%c之前加上一个空格例如:
scanf(“%d”,&n);
scanf(” %c”,ch);
3, <ctype.h>头文件中的部分函数(了解一下,可能选择题考)
函数名称 返回值
isalnum() 如果参数是字母数字,即字母或数字,该函数返回true
isalpha() 如果参数是字母,该函数返回真
isblank() 如果参数是空格或水平制表符,该函数返回true
iscntrl() 如果参数是控制字符,该函数返回true
isdigit() 如果参数是数字(0~9),该函数返回true
isgraph() 如果参数是除空格之外的打印字符,该函数返回true
islower() 如果参数是小写字母,该函数返回true
isprint() 如果参数是打印字符(包括空格),该函数返回true
ispunct() 如果参数是标点符号,该函数返回true
isspace()
如果参数是标准空白字符,如空格、进纸、换行符、回车 、水平制表符或者垂直制表符,该函数返回true
isupper() 如果参数是大写字母,该函数返回true
isxdigit() 如果参数是十六进制的数字,即0~9、af、AF,该函数返回true
tolower() 如果参数是大写字符,则返回其小写,否则返回该参数
toupper() 如果参数是小写字母,则返回其大写,否则返回该参数
4,字符串的输入/输出两种常用格式
1
char ch[100];
scanf("%s",&ch);
printf("%s",ch);
2
char ch[100];
gets(ch);
puts(ch);
5 例题:统计单词个数。从键盘上输入一个字符串,以回车键结束,统计其中的单词个数。
#include<stdio.h>
#include<string.h>
int main()
{
char ch[100];
int len,m,i;
printf("请输入一串字符:");
gets(ch);
len=strlen(ch);
i=0;
m=0;
while(ch[i]!='\0')
{
if(ch[i]!=' '&&ch[i+1]==' ')
m++;
i++;
}
if(ch[len-1]!=' ')
m++;
printf("单词数:%d\n",m);
return 0;
}
6,常用字符串函数
下面介绍的字符串处理函数都是在string.h头文件中声明的,使用前要包含这个头文件。
1.strlen函数
- 这个函数可以用来测量字符串的字符个数,不包括\0
2.strcpy函数
1 char s[10];
2 strcpy(s, “lmj”);
strcpy函数会将右边的”lmj”字符串拷贝到字符数组s中。从s的首地址开始,逐个字符拷贝,直到拷贝到\0为止。当然,在s的尾部肯定会保留一个\0。
- 假设右边的字符串中有好几个\0,strcpy函数只会拷贝第1个\0之前的内容,后面的内容不拷贝
1 char s[10];
2 char c[] = {‘m’, ‘j’, ‘\0’, ‘l’, ‘m’, ‘j’, ‘\0’};
3 strcpy(s, c);
最后字符串s中的内容为:mj
3.strcat函数
char s1[30] = “LOVE”;
strcat(s1, “OC”);
strcat函数会将右边的”OC”字符串拼接到s1的尾部,最后s1的内容就变成了”LOVEOC”
strcat函数会从s1的第1个\0字符开始连接字符串*,s1的第1个\0字符会被右边的字符串覆盖,连接完毕后在s1的尾部保留一个\0
- 注意下面的情况
1 char s1[30] = {‘L’, ‘m’, ‘j’, ‘\0’, ‘L’, ‘o’, ‘v’, ‘e’, ‘\0’};
2 strcat(s1, “OC”);
3 printf(“%s”, s1);
第1行初始化的s1有2个\0,经过第2行的strcat函数后,输出结果:
4.strcmp函数
-
这个函数可以用来比较2个字符串的大小
-
调用形式为:strcmp(字符串1, 字符串2)
-
两个字符串从左至右逐个字符比较(按照字符的ASCII码值的大小),直到字符不相同或者遇见’\0’为止。如果全部字符都相同,则返回值为0。如果不相同,则返回两个字符串中第一个不相同的字符ASCII码值的差。即字符串1大于字符串2时函数返回值为正,否则为负。
第八章 指针的重要知识点
这一章考的知识较少知道几个例题应该就能过。
例一 通过变量的指针实现一个整型数据的输入与输出。
**
#include<stdio.h>
main()
{
int x,*p; // 定义指向整型变量x的指针变量p
p=&x; // 指针变量 p获取x的地址
printf("x=");
scanf("%d",p); // 通过指针变量p接收x的值
printf("x=%d\n",*p); // 通过指针变量p打印x的值
}
**
【例2】通过指针变量交换两个整型变量的值。
#include<stdio.h>
main()
{
int x,y,t,*p1,*p2; // 定义指针变量p1、p2
p1=&x;p2=&y; // 指针变量p1、p2分别指向x、y
printf("x,y=");
scanf("%d,%d",p1,p2);
t=*p1;*p1=*p2;*p2=t; // 通过指针变量p1、p2交换变量x、y的值
printf("x=%d,y=%d\n",*p1,*p2); // 通过指针变量p1、p2输出变量x、y的值
}
【
(后面的了解一下就好,加油!)
1.1指针简介
指针是一种数据类型,自身占用内存空间(win32平台,所有指针占用4字节内存空间),指针存储的 值 是内存地址的编号。
指针变量指向谁,就把谁的地址赋值给指针变量。指针通过 * 解引用,操作的是指针变量指向的内存空间,可以实现 取值 和 间接赋值 。
1.2指针的声明和使用
在指针声明时,* 号表示所声明的变量为指针。
在指针使用时,* 号表示操作指针所指向的内存空间。
易错点: * 只能用来操作指针。
用一级指针接收二级指针的值,并不能实现二次解引用。
用二级指针接收一级指针的值,同样不能实现二次解引用。
示例1:一级指针接收并操作二级指针的值
int main() {
int a = 10;
int *p1 = &a;
int *p2 = &p1; //q2为一级指针
int **p3 = &p1; //q3为二级指针
//p2和p3保存的值相等,但是p2未一级指针,只能解引用一次
printf("%d\n", **p3);//此处正常输出10
printf("%d\n", **p2);//err "*"的操作数必须是指针(vs2015报错提示)
return 0;
}
调试查看内存截图如下:
注:上图中十六进制数 0x007df982 等于 十进制数 8255784
示例2:一级指针接收并操作二级指针的值
int main() {
int a = 10;
int *p1 = &a;
int **p2 = p1;
printf("%d\n", *p2); //此处正常输出为10
printf("%d\n", *(*p2));
//此代码编译时不报错,运行时异常退出(本质上为操作野指针)
system("pause");
}
1.3野指针,万能指针,空指针
1.3.1野指针
野指针指针操纵的内存空间必须是我们已经向操作系统申请的合法空间,如果指针指向了我们不具备操作权限的区域,即为野指针。出现野指针不会直接引发错误,操作野指针指向的内存区域才会出问题,并不一定是程序直接挂掉。
野指针出现的四种情况:
指针变量未初始化
指针释放后未置空
指针操作超越变量作用域
int * test() {
int a = 10;
int *p = &a;
return p;
}
int main() {
#if 0
// 1.指针变量未初始化
int *p;
printf(“%d\n”, *p);
//操作指针p会报C4700错误(使用了未初始化的局部变量”p”)
//这种错误,编译器会直接报错,很容易避免
#endif
#if 0
// 2. 指针释放后未置空
int *p = malloc(16);
free§;
printf(“%d\n”, *p);
//指针释放后,可以理解为操作系统已经收回这段内存空间的使用权限
//此时指针指向的就是“垃圾”内存,程序会固定输出-572662307
//有兴趣的同学可以深入探讨一下这段数字的含义
#endif
#if 0
// 3.指针操作超越变量作用域
int *p = test();
printf(“%d\n”, *p);
//此处输出10,即为test函数中的a值
//编译器做了一层优化,虽然输出值正常,但是不能这样使用。
#endif
system("pause");
return 0;
}
总结:避免野指针的最好方法就是初始化置空,和释放后置空。
1.3.2 空指针
空指针并不是NULL,而是把指向NULL的指针称为空指针,这个操作称为将指针置空。其实置空就是用NULL覆盖了原先指针存储的地址空间,严格意义上讲,置空后的指针仍然是一个野指针,同样不能对其进行操作。
野指针可能引发很多奇怪的问题,我们一定要尽量避免操作野指针,但是如果代码量级很大,我们操作一个 “陌生” 指针之前可以知道其是否是野指针吗?
所以说指针使用过后(野指针)置空即为判断一个指针是否合法的前置条件,置空后我们可以使用if语句测试该指针是否为NULL,有效排除操作野指针对我们程序的影响。
我们写代码时,要注意指针置空的妙用,养成良好的变成习惯。
1.3.3万能指针
void *指针即为万能指针,可以指向任意变量的内存空间,可以接收任意类型变量的值,这样做的意义大家会慢慢发觉。但是现阶段我们需要注意,不能对万能指针解引用。
int main() {
int *a = 10;
void *p = &a;
printf(“%d\n”, *p);//编译报错,不允许使用不完整类型
system(“pause”);
return 0;
}
1.14指针常量
在编辑程序时,指针作为函数参数,如果不想修改指针对应内存空间的值,需要使用const修饰指针数据类型
int main() {
int a = 100;
int b = 200;
//指向常量的指针
//修饰*,指针指向内存区域不能修改
//等价于const int * p1 = &a;
int const *p1 = &a;
//*p1 = 111; //err(表达式必须是可修改的左值)
p1 = &b; //指针指向可以变
//指针常量
//修饰p1,指针指向不能变指针指向的内存可以修改
int * const p2 = &a;
//p2 = &b; //err(表达式必须是可修改的左值)
*p2 = 222; //指针指向的内存可以修改
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114928.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...