【C++笔试强训】第二天 川长思鸟来 2024-04-20 06:06 96阅读 0赞 > **?C++笔试强训** > > -------------------- > > * **博客主页:**[一起去看日落吗][Link 1] > * **分享博主的C++刷题日常,大家一起学习** > * **`博主的能力有限,出现错误希望大家不吝赐教`** > * **分享给大家一句我很喜欢的话:夜色难免微凉,前方必有曙光** ?。 > > -------------------- > > ![在这里插入图片描述][047d8ad26e314dc7bc7aa19a6ce9ccb0.jpeg_pic_center] ?? -------------------- ## 选择题 ## ### ?第一题 ### 使用printf函数打印一个double类型的数据,要求:输出为10进制,输出左对齐30个字符,4位精度。以下哪个选项是正确的? A %-30.4e B %4.30e C %-30.4f D %-4.30f 做题的时候我们先把重点找出来,`double,十进制,左对齐,4精度` 因为是十进制输出,所以肯定不是%e,%e是以指数形式输出,因为是左对齐,所以是-m.n% m:表示对齐数 n:精度 > **所以这道题的答案是`%-30.4f ,选C`** -------------------- ### ?第二题 ### 请找出下面程序中有哪些错误() int main(){ int i = 10; int j = 1; const int *p1;//(1) int const *p2 = &i; //(2) p2 = &j;//(3) int *const p3 = &i;//(4) *p3 = 20;//(5) *p2 = 30;//(6) p3 = &j;//(7) return 0; } A 1,2,3,4,5,6,7 B 1,3,5,6 C 6,7 D 3,5 这里有const,我们来了解两个概念: * 常量指针:指针所指空间的值不能发生改变,不能通过指针解引用修改指针所指空间的值,但是指针的指向可以发生改变。 * 指针常量:指针本身是一个常量,指针的指向不能发生改变,但是指针所指空间的值可以发生改变,可以通过指针解引用改变指针所指空间的值。 区分:const \*的相对位置 * const 在 \* 的左边,常量指针 * const 在 \* 的右边,指针常量 1 2 是常量指针,区别是2进行了初始化 因为是常量指针,所以指针指向可以改变,所以3是对的,但不能通过解引用改变所指空间的值,所以6是错的 4是指针常量,所以可以改变所指空间的值,所以5是对的,但不能改变指针的指向,所以7是错的 > **`所以这道题的答案是C`** -------------------- ### ?第三题 ### 下面叙述错误的是() char acX[]="abc"; char acY[]={ 'a','b','c'}; char *szX="abc"; char *szY="abc"; A acX与acY的内容可以修改 B szX与szY指向同一个地址 C acX占用的内存空间比acY占用的大 D szX的内容修改后,szY的内容也会被更改 这道题acX和acY都是字符数组,只不过初始化的方式不同,szX和szY都是指针,指向同一个常量字符串,B正确 字符数组定义的内容实在栈上开辟的,是可以修改的,A正确 acX是字符串初始化,acY是数组初始化,字符串最后有个\\0,所以C正确 szX的内容改变指的是szX的指向发生了改变,并不是字符数组发生了改变,所以szY不会发生改变,所以D错误 > **`这道题的答案选D`** -------------------- ### ?第四题 ### 在头文件及上下文均正常的情况下,下列代码的运行结果是() int a[] = { 1, 2, 3, 4}; int *b = a; *b += 2; *(b + 2) = 2; b++; printf("%d,%d\n", *b, *(b + 2)); A 1,3 B 1,2 C 2,4 D 3,2 我们一条语句一条语句分析,int \*b = a,定义了一个指针b指向数组首元素 \*b += 2 *的优先级高于+=,所以*b先解引用得到1,再1+2=3,所以数组首元素的值变为3 \*(b+2)= 2,由于括号的优先级高,先向右偏移两个位置,再将所指向的元素改变为2; b++ 从数组首元素偏移到下一位 所以现在数组的元素是 3 2 2 4 ,b指向第二个元素 > **所以这道题的答案是`2 4,选C`** -------------------- ### ?第五题 ### 下列关于C/C++的宏定义,不正确的是() A 宏定义不检查参数正确性,会有安全隐患 B 宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量 C 宏的嵌套定义过多会影响程序的可读性,而且很容易出错 D 相对于函数调用,宏定义可以提高程序的运行效率 这道题主要是考验对宏的理解,宏是没有安全检测的,所以A正确 B选项恰好说反了,宏是没有安全检测的,并且在预处理阶段进行宏替换,所以是无法进行调试的,所以要尽量使用const常量 宏定义很容易导致优先级出错,所以C正确 宏定义相对于函数调用来说,没有创建函数栈帧,没有函数压栈的开销,是可以提高程序的运行效率,所以D是正确的 > **`这道题的答案是B`** -------------------- ### ?第六题 ### 有以下定义: int a[10]; char b[80]; 函数声明为: void sss(char[],int[]); 则正确的函数调用形式是() A sss(a,b); B sss(char b\[\],int a\[\]); C sss(b\[\],a\[\]); D sss(b,a); 函数在调用的时候传入的参数如果是数组类型,调用的时候我们只需要传入数组名,即数组的地址 A的类型写反了,B传入的参数写了数据类型,这是不需要的的,C不应该加\[\] > **`这道题的答案是D`** -------------------- ### ?第七题 ### 用变量a给出下面的定义:一个有10个指针的数组,该指针指向一个函数,该函数有一个整形参数并返回一个整型数() A int \*a\[10\]; B int (\*a)\[10\]; C int (\*a)(int); D int (\*a\[10\])(int); A选项\[\]的优先级高于\*,所以表面这是一个数组,数组里面存放的是int类型的指针,是一个指针数组 B是一个数组指针,指向int类型的数组,大小为10 C是一个指针函数,这个函数有一个int参数,返回值类型是int D是函数指针数组,有一个整形参数并返回一个int类型的值,满足题意 > **`这道题的答案是D`** -------------------- ### ?第八题 ### 以下 C++ 函数的功能是统计给定输入中每个大写字母的出现次数(不需要检查输入合法性,所有字母都为大写),则应在横线处填入的代码为() void AlphabetCounting(char a[], int n) { int count[26] = { }, i, kind = 10; for (i = 0; i < n; ++i) _________________; for (i = 0; i < 26; ++i) { printf("%c=%d", _____, _____); } } A ++count\[a\[i\]-‘Z’\] ‘Z’-i count\[‘Z’-i\] B ++count\[‘A’-a\[i\]\] ‘A’+i count\[i\] C ++count\[i\] i count\[i\] D ++count\[‘Z’-a\[i\]\] ‘Z’-i count\[I\] 先看A选项,a\[i\] - ‘Z’ 的ASCII值是小于0的,但是数组下标不能小于0,所以A是错误的 B选项和A同理,‘A’ - a\[i\]的ASCII值也是小于0 C选项用i做下标,但是i的值是取决于n的,所以这个字符数组有可能是比count记录的大的,所以不满足题意,会出现越界,所以c是错的 D选项就是每一个下标对应一个字母,所以可以用来统计字数,‘Z’ - i ,是对应的每个字母,count\[i\]存储的是每个字母出现的次数,所以D是对的 > **`所以这道题的答案是D`** -------------------- ### ?第九题 ### 在32位cpu上选择缺省对齐的情况下,有如下结构体定义: struct A{ unsigned a : 19; unsigned b : 11; unsigned c : 4; unsigned d : 29; char index; }; 则sizeof(struct A)的值为() A 9 B 12 C 16 D 20 这道题的:数字表示位断,假设开辟4个字节,32个比特位,a占19个字节,如果b的位置够的话还是会放在这四个字节里面,不需要重新开辟空间。 ![请添加图片描述][090ecbc77586431c92519579890c1139.png] 根据内存对齐原则,所以得到这个结构体的长度为16字节 > **`所以这道题的答案是16,选C`** -------------------- ### ?第十题 ### 下面代码会输出() int main() { int a[4]={ 1,2,3,4}; int *ptr=(int*)(&a+1); printf("%d",*(ptr-1)); } A 4 B 1 C 2 D 3 这道题给了一个整形数组,定义了一个指针ptr,利用数组给他赋值,&a + 1 会偏移数组类型个大小,即从数组首元素偏移4位,指向最后一个数据的下一个位置,所以\*(ptr-1)指向的是数组的最后一个位置 > **所以这道题的`答案是4,选A`** -------------------- ## 编程题 ## ### ?第一题 ### 链接:[排序子序列][Link 2] 牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列. 如样例所示,牛牛可以把数组A划分为\[1,2,3\]和\[2,2,1\]两个排序子序列,至少需要划分为2个排序子序列,所以输出2 ![请添加图片描述][f1d6c11858644d12b1b43087d2ce3100.png] * 解题思路; 首先子序列是非递增或是非递减的: 递增:1 2 3 4 5 6 递减:6 5 4 3 2 1 非递增:6 5 5 4 3 (前后两数可能相等) 非递减:1 2 2 3 4 (前后两数可能相等) 对数组a而言,就可以分为一下三种情况: if (a\[i\] > a\[i+1\]) //即将进入非递增序列 if (a\[i\] == a\[i+1\] //相等时 if (a\[i\] < a\[i+1\]) //即将进入非递减序列 输入数组之后,开始遍历数组,如果数组满足非递增或者非递减,就进入对应的条件判断,然后此时如果i+1的元素依然满足对应的非递增或非递减,就直接i++,然后跳出之后进行count++,这就是一个排序子序列,如果相等的话就直接i++,这样执行下去,直到遍历结束,输出此时的count。 * 代码演示: #include <iostream> #include <vector> using namespace std; int main() { int n; int count = 0; cin >> n; vector<int> a; a.resize(n+1); a[n] = 0; for(int i = 0; i < n; i++) { cin >> a[i]; } //数组当中已经存在数字 int i = 0; while( i < n) { //进入非递减序列 if(a[i] < a[i+1]) { //注意i的值不可以一直加 while(i < n && a[i] <= a[i+1]) { i++; } count++;//完成一组 i++; } else if(a[i] == a[i+1]) { i++; } else { while(i < n && a[i] >= a[i+1]) { i++; } count++;//完成一组 i++; } } cout << count << endl; } -------------------- ### ?第二题 ### 链接:[字符串倒置][Link 3] ![请添加图片描述][3ea7c59eef304d00995dc4250cde1050.png] * 解题思路 先将整个字符串逆置过来,再遍历字符串,找出每个单词,对单词逆置。这里我们使用了stl算法中的reverse,所以这里使用迭代器遍历string * 代码演示 #include <iostream> #include <string> #include <algorithm> using namespace std; int main() { string s; getline(cin,s); //1.进行整体逆置 reverse(s.begin(),s.end()); auto start = s.begin(); //2.进行单词逆置 while(start != s.end()) { auto end = start; while (end != s.end() && *end != ' ') { end++; } reverse(start,end); if( end != s.end()) { start = end+1; } else { start = end; } } cout << s << endl; } * 取巧思路 直接利用cin>>s接收输入,遇到空格就结束了,自然就分割开了每个单词,其次将每次接收到的单词拼接到之前串的前面就逆置过来了 #include <iostream> #include <string> using namespace std; // cin读取string时自动会被空格分隔开,用另一个字符串存储进行逆序输出 int main() { string s1, s2; cin >> s2; while (cin >> s1) s2 = s1 + " " + s2; cout << s2 << endl; return 0; } -------------------- [Link 1]: https://blog.csdn.net/m0_60338933?type=blog [047d8ad26e314dc7bc7aa19a6ce9ccb0.jpeg_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/74ef53ca581f467b8a47c7973116bce2.jpeg [090ecbc77586431c92519579890c1139.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/f1415a654f5644f9afeaed7b18840d22.png [Link 2]: https://www.nowcoder.com/questionTerminal/2d3f6ddd82da445d804c95db22dcc471?orderByHotValue=1&page=1&onlyReference=false [f1d6c11858644d12b1b43087d2ce3100.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/00691497ff384799aedb9cd20e04cedb.png [Link 3]: https://www.nowcoder.com/practice/ee5de2e7c45a46a090c1ced2fdc62355?tpId=85&&tqId=29867&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking [3ea7c59eef304d00995dc4250cde1050.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/cca57f6dec81427d91d2638d3d82fafa.png
还没有评论,来说两句吧...