GESP认证C++编程真题解析 | 202603 四级
单选题
第1题
执行下面程序后,输出为( )。
int f(int x = 2){
return x * 3;
}
int main(){
cout << f() << " " << f(4);
}
A. 2 12
B. 6 12
C. 6 4
D. 12 6
【答案】:B
【解析】
函数定义为 int f(intx=2),这是一个带默认参数的函数。
当调用函数不传入参数时,使用默认值x=2;传入参数时,使用传入的值。
函数体为return x * 3,即返回值为传入参数的3倍。
未传入参数,使用默认参数×=2,计算结果:2×3=6
传入参数4,覆盖默认参数,即x=4,计算结果:4×3=12
第2题
执行下面代码后,输出为( )。
int main() {
int a = 5;
int* p = &a;
int** q = &p;
**q += 7;
cout << a << " " << *p;
}
A. 5 5
B. 12 12
C. 12 5
D. 5 12
【答案】:B
【解析】
inta =5:定义变量a,值为5。
int* p=&a:指针p指向变量a的地址,*p 等价于 a。
int** q=&p:二级指针q指向指针p的地址,**q 等价于 *p,也等价于a。
因此 **q += 7:等价于a+=7,即a=5+7=12。
第3题
已知:
int a[3][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
int (*p)[4] = a;
则表达式 *(*(p + 2) + 1) 的值为( )。
A. 6
B. 10
C. 9
D. 11
【答案】:B
【解析】
int(*p)[4]=a:p是一个数组指针,指向包含4个 int 元素的一维数组,初始时指向二维数组a的第0行。
p+2:指针向后移动2行,指向a的第2行(即{9, 10, 11, 12})。
*(p+2):解引用后得到第2行的首地址,等价于a[2]。
列偏移:
*(p+2)+1:在第2行的基础上向后偏移1个 int元素,指向第2行第1列的元素(即10)。
*(*(p+2)+1)的值为a[2][1]=10
第4题
执行下面程序后,输出为( )。
void fun(int a, int &b, int *c){
a += 1;
b += 2;
*c += 3;
}
int main(){
int x = 1, y = 1, z = 1;
fun(x, y, &z);
cout << x << " " << y << " " << z;
}
A. 2 3 4
B. 1 3 4
C. 2 1 4
D. 1 1 1
【答案】:B
【解析】
a为值传递,b为引用传递,c为指针传递,后两者均会改变实参的值,变为3和4。值传递不会改变实参的值。
第5题
执行下面程序后输出为( )。
int x = 3;
void f(int& x){
x += 2;
}
int main(){
int x = 10;
f(x);
cout << x << " " << ::x;
}
A. 12 3
B. 10 5
C. 12 5
D. 10 3
【答案】:A
【解析】
1.变量作用域分析:
- 全全局变量int x=3,作用域覆盖整个程序,可通过 ::x 明确访问。
- main 函数内定义局部变量 int x=10,该局部变量会暂时屏蔽全局变量x。
2.函数调用分析: - 函数 void f(int& x) 采用引用传递,会直接修改传入变量的原始值。
- 调用f(x)时,将main 函数内的局部变量 x 传入,执行x+=2后,局部变量 x 的值更新为10+2=12。
3.输出结果分析: - cout << x 输出当前作用域的局部变量 x,值为12。
- cout << ::x 通过作用域解析符 :: 访问全局变量 x,值为3。
- 最终程序输出为 12 3。
第6题
下列关于结构体初始化的写法,正确的是( )。
A.
struct Point { int x, y; };
Point p = (1,2);
B.
struct Point { int x, y; };
Point p = {1,2};
C.
struct Point { int x, y; };
Point p = new Point(1,2);
D.
struct Point { int x, y; };
Point p = <1,2>;
【答案】:B
【解析】
结构体初始化使用}进行成员的赋值。其中C选项需要完成结构体的解析函数才可执行赋值。
第7题
执行下面代码后输出为( )。
struct S { int a; int b; };
void g(S s){ s.a += 10; }
void h(S& s){ s.b += 10; }
int main(){
S s{1,2};
g(s);
h(s);
cout << s.a << " " << s.b;
}
A. 11 12
B. 1 12
C. 11 2
D. 1 2
【答案】:B
【解析】
g函数为值传递,不会改变实参s.a的值
h函数为引用传递,会改变实参s.b的值
因此输出1 12
第8题
关于递推算法的描述,正确的是( )。
A. 递推表现为函数自己调用自己
B. 递推从已知初值出发,利用递推关系逐步推出后续结果
C. 递推只能用于指数复杂度问题
D. 递推一定需要回溯
【答案】:B
【解析】
A错误:递推是通过已知初始值,利用递推关系逐步计算出后续结果的过程,并不表现为函数自我调用,函数自我调用属于递归的特征。
B正确:递推的核心逻辑就是从已知初值出发,依据递推关系式,一步步计算出后续的中间结果与最终结果,是递推的准确定义。
C错误:递推的应用范围非常广泛,可用于解决多项式复杂度、指数复杂度等多种类型的问题,并非只能用于指数复杂度问题。
D错误:递推不一定需要回溯,递推通常是按固定顺序从前往后推导结果;而回溯是通过试探、回退的方式寻找解,二者是不同的算法思路。
第9题
执行 climb(6) 的返回值为( )。
int climb(int n){
if(n <= 2) return n;
int a = 1, b = 2, c = 0;
for(int i = 3; i <= n; i++){
c = a + b;
a = b;
b = c;
}
return c;
}
A. 8
B. 13
C. 5
D. 10
【答案】:B
【解析】
n=6
初始值:a = 1, b = 2
第3级:c = a + b = 1 + 2 = 3,更新 a = 2,b = 3
第4级:c = a + b = 2 + 3 = 5,更新 a = 3,b = 5
第5级:c = a + b = 3 + 5 = 8,更新 a = 5,b = 8
第6级:c = a + b = 5 + 8 = 13,更新 a = 8,b = 13
最终,当 n = 6时,代码返回 b = 13。
第10题
某排序算法对如下数据排序(按 score 升序),则下面关于该排序算法稳定性的描述中,说法正确的是( )。
初始: (90,'A'), (90,'B'), (80,'C'), (90,'D')
排序后: (80,'C'), (90,'A'), (90,'B'), (90,'D')
A. 不稳定,因为出现了相同分数
B. 稳定,因为相同 score 的相对顺序保持为 A 在 B 前、B 在 D 前
C. 不稳定,因为 C 跑到前面了
D. 无法判断
【答案】:B
【解析】
排序的稳定性指不改变相等元素的相对顺序,因为本题按照 value 排序,排序前按照{90, 'A}、{90, 'B'}、{90, 'D'}的顺序,排序后不变,因此具备稳定性。
第11题
下面代码试图把数组按升序进行“插入排序”,横线处应填写( )。
void ins(int a[], int n){
for(int i = 1; i < n; i++){
int key = a[i];
int j = i-1;
while(j >= 0 && __________){
a[j+1] = a[j];
j--;
}
a[j+1] = key;
}
}
A. a[j] < key
B. a[j] > key
C. a[j+1] > key
D. a[j] == key
【答案】:B
【解析】
插入排序的升序规则是:将当前元素 key 插入到前面已排序的子数组中,需要将所有大于key 的元素向后移动,直到找到key应在的位置。
第12题
下列代码段的时间复杂度为( )。
int cnt=0;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if( (i+j) % 3 == 0) cnt++;
}
}
A. \(O(n)\)
B. \(O(nlogn)\)
C. \(O(n^2)\)
D. \(O(2^n)\)
【答案】:C
【解析】
代码中为双重循环枚举,因此时间复杂度为 \(O(n^2)\)
第13题
下面哪种方式不能实现将字符串 Welcome to 2026! 输出重定向到文件 log.txt ( )。
A.
freopen("log.txt", "w", stdout);
cout << "Welcome to 2026!" << endl;
fclose(stdout);
B.
std::ofstream outFile("log.txt");
cout << "Welcome to 2026!" << endl;
outFile.close()
C.
ofstream log_file("log.txt");
streambuf* org_cout = cout.rdbuf();
cout.rdbuf(log_file.rdbuf());
cout << "Welcome to 2026!" << endl;
cout.rdbuf(org_cout);
D.
std::ofstream outFile("log.txt");
outFile << "Welcome to 2026!" << endl;
outFile.close();
【答案】:B
【解析】
B选项cout会将字符串输出到屏幕上而不是文件中。
第14题
执行下面程序,输出结果是( )。
int divi(int a,int b){
if(b==0) throw 0;
return a/b;
}
int main(){
try{
cout << divi(10,0);
}catch(const char* msg){
cout << "A";
}catch(int){
cout << "B";
}
}
A. A
B. B
C. 程序崩溃
D. 无输出
【答案】:B
【解析】
b=0,抛出异常0,被int类型的catch捕获,输出B
第15题
下列函数实现排行榜中单个元素的位置调整(类似插入排序的相邻搬移)。当某玩家分数增加,需将其向前移动时,while 循环的条件应为( )。
struct Player{ int score; };
void up(Player players[], int n, int idx){
Player cur = players[idx];
int i = idx;
while( ____________________ ){
players[i] = players[i-1];
i--;
}
players[i] = cur;
}
A. i > 0 && cur.score > players[i-1].score
B. i > 0 && cur.score < players[i-1].score
C. i < n-1 && cur.score > players[i+1].score
D. i < n-1 && cur.score < players[i+1].score
【答案】:A
【解析】
当玩家分数增加需要向前移动时,要将当前玩家 cur 与前一个玩家 players[i-1]比较,若cur 分数更高,则将前一个玩家后移,直到找到合适位置。
循环条件拆解:
边界安全:i>0保证不会越界访问数组前一个元素。
移动逻辑:cur.score > players[i-1].score 表示当前玩家分数比前一个玩家高,需要继续向前移动。
选项分析:
A: i>0&& cur.score > players[i-1].score 符合向前移动的逻辑。
B:cur.score < players[i-1].score 会导致分数更低时向前移动,逻辑相反。
C/D:i < n-1 是向后移动的边界判断,与“向前移动”需求不符,逻辑错误。
判断题
第1题
下面代码执行结束时,变量 a 的值变成 15。
void add10(int &x) { x += 10; }
int main() {
int a = 5;
add10(a);
}
A. 正确
B. 错误
【答案】:A
【解析】
引用传递会改变实参的值
第2题
引用一旦绑定某个变量,就不能再绑定其他变量。( )
A. 正确
B. 错误
【答案】:A
【解析】
引用绑定之后不能改变为其他变量
第3题
执行下面代码,输出结果为 5。
int main() {
int a[2][3];
cout << &a[1][2] - &a[0][1] << endl;
return 0;
}
A. 正确
B. 错误
【答案】:B
【解析】
二维数组的元素在内存中是按照行优先连续存放的。从 \(a[0][1]\) 到 \(a[1][2]\) 之间共间隔4个 int 元素(\(a[0][2]\), \(a[1][0]\), \(a[1][1]\),\(a[1][2]\))。
在C++中,指针减法的结果是元素个数差,而非字节数差,因此结果为4
第4题
下面程序可以正常编译并输出 10。
int calc(int x, int y = 10);
int calc(int x) { return x * 2; }
int calc(int x, int y) { return x * y; }
int main() {
cout << calc(5);
}
A. 正确
B. 错误
【答案】:B
【解析】
代码中存在函数重载与默认参数的歧义问题:当调用calc(5)时,编译器无法确定应选择哪种,这种歧义会导致编译失败,程序无法运行,更不可能输出10。
第5题
下面程序执行后输出 2010。
int x = 10;
void f() { int x = 20; cout << x; }
int main() {
f();
cout << x;
}
A. 正确
B. 错误
【答案】:A
【解析】
f函数中输出的是局部变量值为20,主函数中输出全局变量值为10
第6题
在 C++ 中,如果声明了一个指针变量但没有显式初始化,该指针会自动被初始化为 nullptr。
A. 正确
B. 错误
【答案】:B
【解析】
只有全局变量和静态变量会被默认初始化为 nullptr 或0;局部变量不会自动初始化,必须手动赋值(如 int* p = nullptr;),否则就是危险的野指针。
第7题
下面代码没有语法错误。
struct GameCharacter {
string name;
int level;
float position_x;
float position_y;
struct Equipment {
string weapon;
int attack_bonus;
int defense_bonus;
} equipment;
struct Skill {
string name;
int damage;
} skills[8];
int skill_count;
};
A. 正确
B. 错误
【答案】:A
【解析】
代码没有语法错误
第8题
下面程序能够把 Hello 写入 data.txt 文件中。
ofstream fout("data.txt");
cout << "Hello";
fout.close();
A. 正确
B. 错误
【答案】:B
【解析】
cout会将字符串输出到屏幕上而不是文件中。
第9题
由于选择排序和插入排序的时间复杂度均为 \(O(n^2)\),在任何实际场景下两者的性能表现几乎相同,可以互相替代。
A. 正确
B. 错误
【答案】:B
【解析】
对近乎有序的小规模数据,插入排序效率远高于选择排序且若需求是稳定排序,插入排序满足要求,而选择排序不满足
第10题
下面用递推方式计算斐波那契数列第 n 项的程序,时间复杂度是 \(O(2^n)\)。
int fib(int n) {
if (n <= 1) return n;
int f0 = 0, f1 = 1, cur = 0;
for (int i = 2; i <= n; i++) {
cur = f0 + f1;
f0 = f1;
f1 = cur;
}
return cur;
}
A. 正确
B. 错误
【答案】:B
【解析】
该代码时间复杂度为 \(O(n)\)
浙公网安备 33010602011771号