1、C语言中break和continue语句说法正确的是()。
A、break语句只应用于循环体中
B、continue语句只应用于循环体中
C、break是无条件跳转语句,continue不是
D、break和continue的跳转范围不够明确,容易产生问题
答案:B
解析:break除应用于循环体中,还可以用于switch语句中结束一个case,故选项A错误。continue语句只应用于循环体中,选项B正确。无条件跳转语句有return、break、continue、goto,故选项C错误。break在switch语句中用于跳出该语句,break在循环语句中用于跳出本层整个循环。continue用于结束本次循环,接着进行下次循环是否开始的条件判定。
2、运行时的C程序,下列哪些变量在内存中的stack区域的有()|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 |int
a = 0;
char
*p1;
int
main(``void``) {
``int
b;
``char
s[] = ``"abc"``;
``char
*p2;
``char
*p3 = ``"123456"``;
``static
int
c =0;
``p1 = (``char
*)``malloc``(10);
``free``(p1);
``return
0;
}
|A、a
B、b
C、c
D、s
E、p1
答案:BD
解析:stack区域即栈区。
在C语言中内存分为下面几个区域:
1、栈区:由计算机自动开辟,也由计算机自动释放。存放局部变量。
2、堆区:用户自己开辟的空间,需要用户手动释放。由malloc、new等开辟的空间在堆区。
3、静态区:存放全局变量和static修饰的数据。
4、常量区:存放字符串常量。
5、代码区:存放符号、语法语句等(二进制代码)。
本题给出的代码中,b、s、p2、p3是在函数内部定义的局部变量,应该在栈区。p1和a是在函数外部定义的全局变量,c被static修饰,应该在静态区。字符串常量"123456"在常量区,malloc申请的空间在堆区。本题需要注意的是虽然指针p1指向了堆区的空间,但自身仍然是在静态区。综上,选择选项BD。
3、 执行如下代码后输出结果为()|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 |int
main() {
``int
a[5] = {1, 2, 3, 4, 5};
``int
*ptr = (``int``*)(&a + 1);
``printf``(``"%d, %d"``, *(a + 1), *(ptr - 1));
``return
0;
}
|A、1,1
B、1,3
C、3,3
D、2,5
答案:D
解析:*(a+1)等价于a[1],所以第一个输出为2。从指针偏移的角度来看,a相当于一个指向数组首地址的int *类型指针,a+1偏移一个int类型的地址,所以加*取到的是2。现在让我们分析一下(int *)(&a+1),上面我们说过a相当于指向数组首地址的指针,那么&a相当于将指针提升一个维度,&a此时是指向整个数组的指针(即行指针),&a+1偏移一行的空间,所以此时&a+1代表的地址应该是&a[4]的下一个地址。地址强转后赋给int *类型的指针,此时-1偏移一个int类型的地址,所以加*后取到的是a[4](即5)。
4、 32位机器上,以下结构的sizeof(P)为()|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 |struct
A {
``int
a;
``char
b;
``int
c;
``char
d;
};
struct
P {
``struct
A w[2];
``short
b;
``struct
A* p;
}
|A、26
B、38
C、40
D、30
答案:C
解析:首先确定以几字节进行对齐,32位中默认以四字节对齐,并且成员最大数据类型也达到了四字节,故以四字节进行对齐。在结构体A中,每个成员都占了四个字节,所以结构体A的大小为16。在结构体P中,成员w[2]是struct A类型的结构体数组,其大小为32,成员b根据对齐规则也要占四个字节,成员p是一个指针类型,不管是指向什么类型的指针,在32位机器中都占四个字节。综上,sizeof(P) = 32+4+4 = 40,选择选项C。
5、 如下程序用于输出"Welcome to Huawei Test",请指出其中潜在风险的位置()|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 |char
* GetWelcome(``void``){
``char
* pcWelcome;
``char
* pcNewWelcome;
``pcWelcome = ``"Welcome to Huawei Test"``;
``pcNewWelcome = (``char
*)malloc(strlen(pcWelcome)); ``//1
``if``(NULL == pcNewWelcome){
``return
NULL; ``//2
``}
``strcpy(pcNewWelcome, pcWelcome); ``//3
``return
pcNewWelcome; ``//4
}
printf(``"%s\n"``, GetWelcome());
|A、1
B、2
C、3
D、4
答案:AC
解析:观察位置1,strlen求得的是字符串的有效长度(不包括\0),在后面拷贝中将整个字符串(包括\0)都拷贝过来了,所以这里申请的空间是不足的。观察位置2,如果申请失败的情况下,返回一个空地址,这是合理的。观察位置3,此时申请的空间不足以拷贝全整个字符串,少了一个重要的'\0',会有潜在风险。观察位置4,这里比较容易选错,在函数中返回的并不是局部变量的地址,而是malloc动态申请的空间,这块空间在用户手动释放之前都是有效的。
6、以下程序的运行结果是:|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 |#include <iostream>
using
namespace
std;
int
main(``void``) {
``int
m = 5;
``if
(m++ > 5)
``cout << m << endl;
``else
``cout << --m;
``return
0;
}
|A、4
B、5
C、7
D、6
答案:B
解析:这道题很容易,重要的是细心,做题不要只图快。m++ > 5为假进入else分支,但是既然进行了判断,那么判断后m++还是会执行的,所以最后输出的值为5。
7、 在下列表达式选项中,正确的是()A、++(a++)
B、a++b
C、a+++b
D、a++++b
答案:C
解析:首先让我们了解一下左值和右值的概念,方便后续理解这个题目。
左值指的是具有明确存储位置的实体,通常是一个变量。左值表示一块内存单元的地址,可以通过该地址来读取或写入数据。换句话说,左值就是可以被赋值的地方。左值表达式不仅具有空间实体,还具有读写访问权。对于左值我们可以获取它的地址和对它赋值,被const修饰的左值虽然不能进行赋值,但是仍然能够获取其地址。
右值指的是一个具体的、确定的数值或表达式的结果。右值表示一个具体的、不可改变的数据。右值可以是字面常量、表达式的结果等。右值不能够出现在赋值符号的左边且不能取地址。某些情况下,左值可以转化为右值,但右值不能转化为左值。
对于选项A,++(a++)首先a会将自增前的值返回,但是这个返回值是一个临时值(右值),没有对应的存储空间,不能接收赋值。选项A错误。
要理解后面三个选项,就要理解C词法分析的"贪心法"。
在C语言中,符号分为单字符符号(如:=、+)和多字符符号(如:==、++),这就出现了一个问题:编译器到底是要将字符分开识别,还是和合在一起识别呢?编译器的处理策略为"贪心法",这个方法的过程是,编译器从左到右依次读入字符,每次读入后判断现在读入的所有字符是否能组成一个有意义的符号,如果当前读入的字符串是一个有效的符号,就继续读入。重复该过程,直到读入的字符串不可能是一个有意义的符号,识别这个无意义符号前的最长字符串为一个有效符号。识别完一个有效符号后,会重复进行整个过程,直到处理完所有的输入字符。
选项B中a++b缺少运算符,选项B错误。
选项C中a+++++b等价于(a++)+(++b),选项C正确。
选项D中a++++b的前面会被识别为(a++)++,a返回自增前的值去进行++,这里返回的值是一个右值,不能被赋值,这个问题在左值右值部分提到过。选项D错误。
综上,选择选项C。
8、关于内存管理,以下有误的是()A、malloc在分配内存空间大小的时候是以字节为单位。
B、如果原有空间地址后面还有足够的空闲空间用来分配,则将先前空间释放,然后以先前地址为开始地址按newSize大小重新分配
C、如果原有空间地址后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存,并把先前内存空间中的数据复制 到新的的newSize大小的空间中,然后将之前空间释放
D、free函数的作用是释放内存,内存释放是标记删除,会修改当前空间的所属状态,并且会清除空间内容
答案:D
解析:free函数不会清除空间内容。
9、 当宏定义需要定义多行代码时,会使用下列哪个符号()A、|
B、/
C、\
D、-
答案:C
解析:当宏定义需要定义多行代码时,会使用反斜杠(\)作为续行符。这个符号告诉预处理器,宏定义在下一行继续,而不是在此结束。要注意的是,当前行的反斜杠后不要有任何字符(包括空格和注释),当多行宏定义书写完成后,最后一行不需要加上反斜杠
10、 以下对C语言函数的有关描述中,正确的有()A、在C程序中,函数调用不能出现在表达式语句中
B、在C语言中,一个函数一般由两个部分组成,它们是函数首部和函数体
C、函数的实参和形参可以是相同的名字
D、在main()中定义的变量都可以在其它被调函数中直接使用
E、外部类型的变量只能定义一次,但可在不同地方声明多次
答案:BCE
解析:函数调用可以出现在表达式语句中,例如在主函数中定义一个变量来接收函数的返回值,选项A错误。在函数内部定义的变量属于局部变量,不可以直接被其它被调函数直接使用,可以通过一些方式让该变量在被调函数中使用,但题目中描述为都可以,选项D错误。外部变量即全局变量,一个文件中只能够定义一次,并且可以在多个地方通过extern关键字进行声明。
刷c语言练习题11(牛客网)
拒绝头秃从我做起2024-10-23 15:57
相关推荐
陌小呆^O^1 分钟前
Cmakelist.txt之win-c-udp-clientI_Am_Me_17 分钟前
【JavaEE进阶】 JavaScript重生之我是数学王子27 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现Ai 编码助手29 分钟前
使用php和Xunsearch提升音乐网站的歌曲搜索效果学习前端的小z33 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制神仙别闹40 分钟前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统XINGTECODE41 分钟前
海盗王集成网关和商城服务端功能golang版zwjapple1 小时前
typescript里面正则的使用小五Five1 小时前
TypeScript项目中Axios的封装前端每日三省1 小时前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?