习题纠错01

发布时间 2023-08-29 21:01:13作者: 优秀还天籁

1、编译某段程序出现错误:"xxx.c:5:2: error: stray ‘\357’ in program",造成此错误最有可能原因
是: //D
A. include头文件时忘了加# //拓展:这个报错显示是:"error: expected identifier or '(' before 'filename'"
B. 没写主函数 //拓展:这个报错的显示是:"undefined reference to main"
C. 第5和3行括号不匹配 //"error: expected ‘)’ before ';' token",表示括号数量不匹配。
D. 第5行代码语句中包含中文字符 //写错原因:不知道符号的意思,
//解决方法:xxx.c:5:2: error: stray ‘\357’ in program",
//表示在xxx.c文件中的第5行第2列,表示存在一个无效字符,
//\357 是一个八进制转义序列,它表示一个特殊的字符。这个错误通常出现在程序中包含了不可见字符或非ASCII字符的情况下

3、一个C程序的执行是: //A
A. 从本程序的main函数开始,到main函数结束
B. 从本程序文件的第一个函数开始,到本程序文件的最后一个函数结束
C. 从本程序的main函数开始,到本程序文件的最后一个函数结束
D.从本程序文件的第一个函数开始,到本程序的main函数结束 //写错原因,不知道。
//解决方法:知道执行顺序是从本程序的main函数开始,到main函数结束。

8、若有以下变量定义,则表达式"a/b"的值为: //A
int b=2;
int a=5;
A.2.5
B.2
C.3
D.5 //这个没有特别需要注意的,需要指出的是在这两个整数的相除时,a/b得到的还是整数,但是并不会将其四舍五入,例如2.4,输出的是2,2.6,输出的还是2.

9、C 语言中 while 和 do-while 循环的主要区别是: //A
A.do-while 的循环体至少无条件执行一次
B.while 的循环控制条件比 do-while 的循环控制条件严格
C.do-while 允许从外部转到循环体内
D.do-while 的循环体不能是复合语句 //这里需要注意的是关于do-while语句的一个知识点,那就是无法不允许从外部转到循环体之内,
//但是内部转内部还是内部转外部是可以的,用continue和break;

11、已知有如下的变量定义,那么第二行的表达式的值是多少: //答案是1
int main(void)
{
int x = 3 , y = 4 , z = 5;
!(x + y) + z-1 && y + z/2;
return 0;
} //这个需要知道的是,!符号只要是非零的(无论正数还是负数),都会转变成0。而如果是0的话,那么便会转变成1.

12、下列代码通过gcc编译输出的内容分别为: //答案是c

include<stdio.h>

int main()
{
int a=10,b,c;
a=++a + a++;
printf("a=%d\n",a);
b=++a + a++;
printf("b=%d\n",b);
c=a+++b;
printf("c=%d\n",c);
return 0;
} //这里需要注意的是贪心算法,对于c=a+++b;这句话,一步一步走,变成a+(++b),这样是合法的,那么往后走,(a++)+b,这样是合法的。
//所以取消前面的,采用最新的这个,即a++(+b),继续往后走,(a+++)b,这样是不合法的,所以,最终采用(a++)+b。这便是贪心算法。

A.22 45 69
B.22 45 70
C.23 48 73
D.23 47 74

16、C语言中,设a=3,b=4,执行语句“printf("%d,%d",(a,b),(b,a));”的输出结果是: //答案是c
A.3,4
B.(3,4),(4,3)
C.4,3
D.不确定 //这个需要知道的是在C语言中,逗号运算符会依次求解它的两个操作数,并返回最后一个操作数的值作为整个表达式的结果。
//所以(a,b)会先计算a的值,然后计算b的值,返回b的值。同样地,(b,a)会先计算b的值,然后计算a的值,返回a的值

18、以下不能对二维数组a进行正确初始化的语句是: //答案是c
A.int a [2] [3] = { 0 };
B.int a [] [3] = { { 0,1 }, { 0 } };
C.int a [2] [3] = {{ 0 , 1 }, { 2 ,3} , { 3 , 4 }};
D.int a [] [3] = { 0, 1, 2, 3, 4, 5 }; //这里需要注意的是c中,给到的a[2][3],中表示有2行,但是在后续的初始化中
//有三行,所以不能正确初始化。

19、下列程序段的输出结果为: //答案是B
float k=0.8567;
printf("%06.1f%%",k*100);
A.0085.6%%
B.0085.7%
C.0085.6%
D..857 //这里需要知道的是“%06.1%%”的意思。%06.1f:这是格式控制字符串,用于指定输出的格式。
//其中,%f表示输出浮点数,.1表示保留一位小数,06表示输出的宽度为6,并在左侧用0进行填充(如果需要)。
//%%:这是用来输出一个百分号的转义序列。在C语言中,%字符需要使用两个连续的%来表示输出一个%符号。
//上述的还有个需要注意的点就是,如果将’0‘改‘1’的话就会变成“%16.1%%”,表示表示输出的宽度为16。如果输出的字符数不足16位,则在左侧用空格进行填充。
//还有一点就是,如果原本的浮点数小数位数大于按格式要求显示的,那么便会四舍五入(数字>=5就会入)例如上面的0.8567,这里会被四舍五入为0085.7.

//拓展:例子: int num =10;printf("%05d",num);这个表示右对齐,左边不足补0,而printf("%-5d",num);表示左对齐,右边补空格。

20、假设有说明 int a=0; double x=5.16;,则在以下语句中,属于编译错误的是: //答案是c
A.x=a/x;
B.x=x/a;
C.a=a%x;
D.x=a*x; //c错误的原因是‘%’C语言中,取模运算(%)只能用于整数类型之间的操作,不能用于浮点数类型,会造成编译错误。
//这里需要注意也就是,B选项的x/0,这个在编译时是可以成功的,但是在访问运行时得出的值是无法使用的,在macos中,打印出来的是‘inf’。
//在Linux中,打印出来的是一个不断在变化的数值。

21、以下对选择语句描述错误的是: //答案是A
A.根据某一条件重复执行一部分代码直到满足终止条件为止
B.可以根据条件控制程序流程,改变程序执行的顺序
C.选择语句可以嵌套使用
D.当条件满足时就会执行相应的语句 //这里需要注意的是选择语句和循环语句的概念,A描述的是循环语句, 选择语句用于根据条件选择性地执行不同的代码块。

23、已知 int x=1,y=2,z=3; 以下表达式的值是: //答案是c
z+=x>y?++x:++y;
A.2
B.3
C.6
D.5//这里需要注意的是z+=x>y里面,‘+=’这个是复合赋值运算符,那么赋值运算符的优先级最低,所以,优先判断x>y,答案是fslse,所以执行++y,y变成了3。
最后式子便是z+=3;最后的结果是6.

24、以下程序的输出是: //答案是c
void main(void){
double x=28;
int r;
r= x%5;
printf ("\n r=%d", r);
}
A.r = 3
B.运行错误
C.编译错误
D.都不是 //该题需要注意的是double类型不能直接进行取模运算,需要将其转换为int类型后再进行取模运算,可以进行强转 也就是r=(int)x%5;

25、int a=4,则对于表达式++(a++)的结果说法正确的是: //答案是D
A.结果为5
B.结果为6
C.结果为7
D.以上不都是 //这里需要注意的是,表达式++(a++)是无效的,因为它括号中的a++中变成了常量,也就是右值,()运算符里,不能放常量。—
//在C语言中,后缀递增运算符会增加变量的值,但返回的值是递增前的值。因此,将两个后缀递增运算符应用于同一个变量会导致未定义的行为

26、假设在程序中 a、b、c 均被定义成整型,所赋的值都大于1,则下列能正确表示如图所示代数式的
表达式是: //答案是D
A. 1.0 / a * b * c
B. 1 / (a * b*c)
C.1 / a / b / (float)c
D. 1.0 / a / b / c //这里需要注意的是,关于不同类型之间的算术计算。整数和整数加减乘除,得到的还是整数,也就是说如果有小数点也是直接丢弃
//而浮点数与整数之间的加减乘除操作的话,是会将整型进行隐式转换成浮点数,并输出的,很明显A,B,C选项都是输出的都是整型,也就是说会将小数给丢弃,返回的是0,无意义。

27、若有说明语句:char c=’\72’;则变量c: //答案是A
A.包含1个字符
B.包含2个字符
C.包含3个字符
D.说明不合法,c的值不确定 //这里需要注意的是,在C语言中,以反斜杠(\)开头的字符常量表示一个八进制转义序列,其中的72,是一个八进制数,转换成对应的二进制ASCII值
//然后使用%c格式输出的话,便是一个字符。
//拓展:"\72"、'\72'、\72的区别:"\72"表示字符串中的八进制转义序列;'\72'表示使用单引号(')将转义序列括起来的形式 '\72' 是字符常量的表示方式,表示一个字符
//\72单单表示的是八进制转义序列。特别注意,要是想实现ASCII码表里的字符答应出,首先需要吧对应的十进制,转换为八进制才行,例如:想表示'a',那么就必须吧97变成八进制的141然后,在用转义序列'\141'。
//还有一点,上面的char c='\72',还可以表示成char str[]="\72"。

28、C 语言规定,在一个源程序中,main函数的位置: //答案是C
A.必须在最开始
B.必须在系统调用的库函数的后面
C.可以任意
D.必须在最后 //这里需要注意的是显示声明和隐式声明的问题,隐式声明带来的问题有,编译器会假设函数返回 int 类型,并且可以接受任意数量和类型的参数。

30、C语言源程序的最小单位是: //答案是D
A.程序行
B.语句
C.函数
D.字符 //这里需要注意的是,源程序的最小单位和c语言最小的可执行代码单元的概念,前者是字符,后者是函数

32、对if语句中表达式的类型,下面正确的描述是: //答案是D
A.必须是关系表达式
B.必须是关系表达式或逻辑表达式
C.必须是关系表达式或算术表达式
D.可以是任意表达式 //这里需要注意是,c语言中到底有什么表达式。
//(1)算术表达式:a+b;(2)逻辑表达式:a > b;(3)关系表达式:a == b;(4)赋值表达式:x = 5;(5)条件表达式:x > y ? x : y;(6)位运算表达式:a & b
//(7)函数调用表达式:printf("Hello, world!")。

35、以下不属于Linux阵营的Unix操作系统是: //答案是B;
A. Ubuntu
B. Android
C. AIX
D. redhat //这里需要注意的是,Ubuntu 是一种基于 Debian 的 Linux 发行版,广泛用于桌面和服务器环境。
//AIX 是 IBM 开发的 Unix 操作系统,主要用于 IBM 的服务器和工作站。
//Red Hat 是一家知名的 Linux 发行版提供商,提供企业级的 Linux 操作系统和解决方案。
//这些操作系统都属于 Linux 阵营,并且在 Unix 系统中具有广泛的应用和认可
//虽然 Android 基于 Linux 内核,但它在用户空间和应用层面上有自己的体系结构和 API。

34、有以下定义语句 double a,b; int w; long c; 若各变量已正确赋值,则下列选项中不正确的表达式
是: //答案是A
A.a=a+b=b++;
B.w%(int)a+b;
C.(c+w)%(int)a;
D.w=a==b; //这里需要注意的是,A中的a=a+b=b++;前面的a=a+b是合法的,但是后面的a+b=b++是不合法的,因为赋值操作符的左侧必须是一个可以修改的左值
//但是a+b不是可以改变值的左值。

36、 如果某系统15 * 4 = 112成立,则系统采用的是 ___ 进制://答案是A
A.6
B.7
C.8
D.9//这里的方法是:首先假设,该系统是n进制的,那么最后就变成了(n+5)*4=n^2+n+2,最后计算出两个答案,去掉一个负值,那么便是6进制。

39、下面选项中关于编译预处理的叙述正确的是: //答案B
A.预处理命令行必须使用分号结尾
B.凡是以#号开头的行,都被称为编译预处理命令行
C.预处理命令行不能出现在程序的最后一行
D.预处理命令行的作用域是到最近的函数结束处 //这里需要注意是,预处理命令行不需要使用分号结尾,它们通常以换行符结束。
//预处理指令可以在程序的任何位置,也就是可以在程序的最后一行
//它的作用域在于整个源文件,不单单在函数上。

4、由多个源文件组成的C程序,经过编辑、预处理、编译、链接等阶段会生成最终的目标文件。//这句话是错的,目标文件是以.o结尾的二进制文件,而目标文件在编译那段便已经生成。

5、C语言中除数为0一定会导致编译错误,并提示“浮点数例外(核心已转储)?/这句话是错的,会导致的是运行错误,而不是编译错误,会触发异常,一般叫做的是“除零异常”

6、只有相同类型的数据才能运算,不同类型的数据必须转换成相同的类型才能进行计算。//这句话是对的,这里需要注意的是编译器会根据一定的规则进行自动类型转换。这种自动类型转换称为"隐式类型转换"。
//同时,必须需要用到显式类型转换的情况有:1、不兼容类型,之间没有没有定义隐式转换规则,例如:不能将指针类型变成整数类型;2、精度丢失:就比如将double类型变成float类型
//3、数据范围的超出,,将一个超过int类型范围的整数转换为int类型时,可能会发生溢出;4、枚举类型之间的转换,枚举类型之间不能进行隐式类型转换,但可以通过强制类型转换来实现。如果需要在不同的枚举类型之间进行转换,可以使用强制类型转换操作符。

8、变长数组就是定义数组时使用变量作为数组的长度,当程序运行到数组的定义语句时它的长度才能确定下来,可以随着变量变化长度可变长。//这句话是错的
//这里需要注意,不能变的原因,因为变长数组在栈上分配内存,栈是按照"先进后出"的原则进行管理,无法在运行时动态地调整已分配的内存块的大小;变长数组例子:int arr[length];
// 拓展:静态数组:int arr[10];静态数组不管是显示初始化还是未显式初始化(未初始化)它都是存储在data段;
//自动数组:void 函数名(size){int arr[size];}自动数组是在函数内部定义的数组,它的大小可以是常量、变量或表达式,存储在栈上;
//自动数组和变长数组的也是有点区别:变长数组允许在运行时通过用户输入的方式确定数组的大小;对于自动数组,它的大小在编译时确定,并且不能通过用户输入的方式进行动态调整。
//动态数组:int* dynamicArray = (int*)malloc(30 * sizeof(int)); 他是存储在堆上的。

4、下面的程序执行结果是: //答案是B
int main()
{
static int num;
printf("%d\n",100/num);
}
A.100
B.段错误
C.不确定
D.浮点数例外//这里需要注意的是这里的num这个变量是静态局部变量,并且没有初始化,所以存储在bss段,而100/num时,编译是可以通过的,但是这里printf是对其进行访问了,所以会出现段错误。