目录
一、选择题
二、编程题
三、选择题题解
四、编程题题解
一、选择题
1、使用printf函数打印一个double类型的数据,要求:输出为10进制,输出左对齐30个字符,4位精度。以下哪个选项是正确的?
A. %-30.4e
B. %4.30e
C. %-30.4f
D. %-4.30f
2、请找出下面程序中有哪些错误()
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
3、下面叙述错误的是()
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的内容也会被更改
4、在头文件及上下文均正常的情况下,下列代码的运行结果是()
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
5、下列关于C/C++的宏定义,不正确的是()
A. 宏定义不检查参数正确性,会有安全隐患
B. 宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量
C. 宏的嵌套定义过多会影响程序的可读性,而且很容易出错
D. 相对于函数调用,宏定义可以提高程序的运行效率
6、有以下定义:则正确的函数调用形式是()
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);
7、用变量a给出下面的定义:一个有10个指针的数组,该指针指向一个函数,该函数有一个整形参数并返回一个整型数()
A. int *a[10];
B. int (*a)[10];
C. int (*a)(int);
D. int (*a[10])(int);
8、以下 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]
9、在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
10、下面代码会输出()
int main()
{
int a[4]={1,2,3,4};
int *ptr=(int*)(&a+1);
printf("%d",*(ptr-1));
return 0;
}
A. 4
B. 1
C. 2
D. 3
二、编程题
1、排序子序列 题目链接
2、倒置字符串 题目链接
三、选择题题解
1、使用printf函数打印一个double类型的数据,要求:输出为10进制,输出左对齐30个字符,4位精度。以下哪个选项是正确的?
A. %-30.4e
B. %4.30e
C. %-30.4f
D. %-4.30f
正确答案:C
题解:
本题主要考察printf的输出格式,在输出一个浮点数时,我们通常用%f进行格式控制,其中百分号与f之间可以添加参数;%m.nf;其中默认为右对齐,如果在m前加上 - 则会变成左对齐,m代表屏幕输出像素个数,若实际输出像素个数大于m时,则不做任何处理,若小于,则补控制至m,n则代表小数点后保存有效数字个数,这题故选c
2、请找出下面程序中有哪些错误()
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
正确答案:C
题解:
这题考察const修饰指针的各种情况,当const在*前时,修饰的时指针指向的内容,const在*后时,则修饰的时指针变量;分析题目,我们发现p1与p2的const均修饰其指向内容不可改变,而p3的const修饰p3这个指针变量不能改变,故选C
3、下面叙述错误的是()
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的内容也会被更改
正确答案:D
题解:
分析题目,我们发现acX与acY均为字符数组,而唯一不同时acX使用字符串初始化,因此多了一个\0,而szX与szY均为字符指针,指向同一个字符常量,故ABC均正确,而当szX指向改变是,szY不变,故D错误
4、在头文件及上下文均正常的情况下,下列代码的运行结果是()
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
正确答案:C
题解:
此题主要考察指针的理解,根据题目分析,我们知道a是一个整型数组,b是一个指针,指向a数组的起始地址;当执行*b+=2时,数组的第一个元素加等了2,当执行*(b+2)=2时,将数组第三个元素3重新赋值为2,注意此时b指向未改变;当执行b++时,b指向了数组的第二个元素;接下来打印*b即打印第二个元素2,打印*(b+2)则打印第四个元素4;故选C;
5、下列关于C/C++的宏定义,不正确的是()
A. 宏定义不检查参数正确性,会有安全隐患
B. 宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量
C. 宏的嵌套定义过多会影响程序的可读性,而且很容易出错
D. 相对于函数调用,宏定义可以提高程序的运行效率
正确答案:B
题解:
本题考察宏定义相关知识点,宏定义没有类型检查,仅仅只在与编译阶段进行简单的替换,也不方便调试,因此我们尽量使用const常量,而非宏定义常量;
6、有以下定义:则正确的函数调用形式是()
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);
正确答案:D
题解:
首先,我们观察函数声明,第一个参数字符数组,第二个参数为整型数组,也就是第一个参数可以传字符数组名或字符指针,第二个参数可以传整型数组名或整形指针;故选D
7、用变量a给出下面的定义:一个有10个指针的数组,该指针指向一个函数,该函数有一个整形参数并返回一个整型数()
A. int *a[10];
B. int (*a)[10];
C. int (*a)(int);
D. int (*a[10])(int);
正确答案:D
题解:
A选项是一个数组,数组每个元素为int*类型,B选项是一个指针,指向一个有10个整型的数组;C选项是一个函数指针,指向一个返回值是int,并且有一个int参数的函数;D选项符合题目描述;
8、以下 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]
正确答案:D
题解:
本题考察计数排序思想,第一个循环统计大写字符的个数,我们找到大写字符a[i],用Z减去a[i]就得到了其映射的下标,并对下标对应位置的数据++,排除ABC,答案其实已经出来了;接着我们想要打印大写字符则用下标加上字符A即可,出现次数已经记录在count对应位置上了;
9、在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
正确答案:C
题解:
本题主要考察位段与结构体对齐等知识,首先结构体中创建了一个unsigned int变量,需要申请4个字节即32个比特位,而冒号其后为19,a只用19个比特位;还剩13个比特位;而b只需11个比特位,因此还剩2个比特位,而c需要4个比特位,不够,因此有重新开辟四个字节,即32比特位,存储完c后,还剩28个比特位;接着d需要29个比特位,不够,故有开辟4个字节,即32比特位;此时已经申请了12字节了;而接着申请了一个char类型的数据,占一个字节,因此,一共13个字节,而因结构体对其规则,结构体的大小必须为最大对齐数的正数倍,故为4的整数倍,16;选C;
10、下面代码会输出()
int main()
{
int a[4]={1,2,3,4};
int *ptr=(int*)(&a+1);
printf("%d",*(ptr-1));
return 0;
}
A. 4
B. 1
C. 2
D. 3
正确答案:A
题解:
ptr为&a+1,而&a是取整个数组的地址,对其+1,则跳过整个数组,指向数组最后一个元素的下一个元素,即4的下一个元素,而打印时,ptr为int*,对其减1,即指向了4,对其解引用,访问4;故选A;
四、编程题题解
1、排序子序列
首先,我们的理解两个概念;
非递增序列:即序列中下一元素要么小于前一个要么等于前一个元素;
例: 8 7 7 6 5 4 2 1
非递减序列:即序列中下一元素要么大于前一个要么等于前一个元素;
例: 1 3 5 6 6 7 8 9
以上为主要的代码逻辑,实际上还有很多细节;如下
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n = 0;
cin >> n;
vector<int> v;
// 多开一个空间,且置为0,防止后面的越界
v.resize(n + 1, 0);
// 读取数据
for(int i = 0; i < n; i++)
{
cin >> v[i];
}
int i = 0;
int count = 0;
while(i < n)
{
if(v[i] > v[i + 1]) // 非递增序列
{
// 直到进入另一种情况(这里必须防止越界)
while(i < n && v[i] >= v[i + 1])
{
i++;
}
i++;
count++;
}
else if(v[i] < v[i + 1]) // 非递减序列
{
// 直到进入另一种情况(这里必须防止越界)
while(i < n && v[i] <= v[i + 1])
{
i++;
}
i++;
count++;
}
else // 相等序列
{
i++;
}
}
cout << count << endl;
}
多开一个空间并置为0很重要,因为上面代码如果不多开一个空间其中判断 v[i] > v[i + 1] 必定会发生越界访问的问题;而且还可以处理整个序列相等的情况;大家可以自己模拟;
2、倒置字符串
本题可以采用暴力法,但小编想采取一种更巧妙的方法求解;
翻转字符串我们可以自己手写一个,也可以调用算法库中的函数,这里就使用算法库中的函数了;
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string str;
// 这里不用直接用cin流提取,因此str可能存在空格
getline(cin, str);
auto begin = str.begin();
auto end = begin;
while(end != str.end())
{
if(*end == ' ')
{
// 逆置(左闭右开)
reverse(begin, end);
end++;
begin = end;
}
else
{
end++;
}
}
// 最后一个单词的逆置
reverse(begin, end);
// 逆置整个句子
reverse(str.begin(), str.end());
cout << str << endl;
}