目录
一、选择题
二、编程题
三、选择题题解
四、编程题题解
一、选择题
1、在上下文和头文件均正常情况下,以下程序的输出结果是()
int x = 1;
do
{
printf("%2d\n",x++);
}while(x--);
A. 1
B. 无任何输出
C. 2
D. 陷入死循环
2、定义char dog[]="wang\0miao";那么sizeof(dog)与strlen(dog)分别是多少()
A. 10,4
B. 4,4
C. 9,9
D. 9,4
3、下列程序的打印结果是()
char p1[15] = "abcd", *p2 = "ABCD", str[50] = "xyz";
strcpy(str + 2, strcat(p1 + 2, p2 + 1));
printf("%s", str);
A. xyabcAB
B. abcABz
C. ABabcz
D. xycdBCD
4、下面程序的输出结果是()
#include<iosteam.h>
void main()
{
int n[][3] = {10,20,30,40,50,60};
int (*p)[3];
p=n;
cout<<p[0][0]<<","<<*(p[0]+1)<<","<<(*p)[2]<<endl;
return 0;
}
A. 10,30,50
B. 10,20,30
C. 20,40,60
D. 10,30,60
5、以下说法中正确的是( )。
A. C++程序中的main()函数必须放在程序的开始部分
B. C++程序的入口函数是main函数
C. 在C++程序中,要调用的函数必须在main()函数中
6、有以下程序运行结果为()
#include <iostream>
using namespace std;
char fun(char x, char y)
{
if (x < y)
return x;
return y;
}
int main()
{
int a = '1', b = '1', c = '2';
cout << fun(fun(a, b), fun(b, c));
return 0;
}
A. 运行出错
B. 2
C. 3
D. 1
7、对于int* pa[5];的描述,以下哪个选项是正确的()
A. pa是一个具有5个元素的指针数组,每个元素是一个int类型的指针;
B. pa是一个指向数组的指针,所指向的数组是5个int类型的元素;
C. pa[5]表示某个数的第5个元素的值;
D. pa是一个指向某个数组中第5个元素的指针,该元素是int类型的变量
8、下面两个结构体,在#pragma pack(4)和#pragma pack(8)的情况下,结构体的大小分别是
struct One
{
double d;
char c;
int i;
}
struct Two
{
char c;
double d;
int i;
}
A. 16 24,16 24
B. 16 20,16 20
C. 16 16,16 24
D. 16 16,24 24
9、下面哪个指针表达式可以用来引用数组元素a[i][j][k][l]()
A. (((a+i)+j)+k)+l)
B. *(*(*(*(a+i)+j)+k)+l)
C. (((a+i)+j)+k+l)
D. ((a+i)+j+k+l)
10、由多个源文件组成的C程序,经过编辑、预处理、编译、链接等阶段会生成最终的可执行程序。下面哪个阶段可以发现被调用的函数未定义()
A. 预处理
B. 编译
C. 链接
D. 执行
二、编程题
1、统计回文 题目链接
2、连续最大和 题目链接
三、选择题题解
1、在上下文和头文件均正常情况下,以下程序的输出结果是()
int x = 1;
do
{
printf("%2d\n",x++);
}while(x--);
A. 1
B. 无任何输出
C. 2
D. 陷入死循环
正确答案:D
题解:
本题考察循环语句的掌握,do while循环是先执行函数体,在进行判断,x初始值为为1,printf语句对x进行了后置++,因此
2、定义char dog[]="wang\0miao";那么sizeof(dog)与strlen(dog)分别是多少()
A. 10,4
B. 4,4
C. 9,9
D. 9,4
正确答案:A
题解:
对于上述,首先我们用弄清sizeof(数组名)与strlen(数组名)分别代表什么意义,首先sizeof(数组名)是计算整个数组占了多少字节,我们可以看到题目是拿一个字符串给数组赋值,也就是将字符串中的每个字符放进数组中,准确来说是拷贝一份,包括字符串的结尾\0,因此为10个字节,而strlen的计算规则是遇到\0位置,计算\0前的字符个数,因此为4,答案选A;
3、下列程序的打印结果是()
char p1[15] = "abcd", *p2 = "ABCD", str[50] = "xyz";
strcpy(str + 2, strcat(p1 + 2, p2 + 1));
printf("%s", str);
A. xyabcAB
B. abcABz
C. ABabcz
D. xycdBCD
正确答案:D
题解:
我们需要清楚strcat与strcpy的功能,首先strcat是追加功能,返回值为第一个参数,即即使地址,我们追加后返回打印的结果应该是cdBCD,我们在将这个拷贝到str+2的位置,打印结果额就是xycdBCD;
4、下面程序的输出结果是()
#include<iosteam.h>
void main()
{
int n[][3] = {10,20,30,40,50,60};
int (*p)[3];
p=n;
cout<<p[0][0]<<","<<*(p[0]+1)<<","<<(*p)[2]<<endl;
return 0;
}
A. 10,30,50
B. 10,20,30
C. 20,40,60
D. 10,30,60
正确答案:B
题解:
关于数组的访问,我们通常写成arr[i],其实也可以写成*(arr+i),对于二维数组,比如arr[i][j],我们同样也可以写成*(*(arr + i) + j);看题目,p[0][0]即数组第一行第一列,故为10,*(p[0] + 1)为数组第一行,第二列,故为20;(*p)[2]可以写成*(p+ 0)[2],为第一行第三列;故为30;
5、以下说法中正确的是( )。
A. C++程序中的main()函数必须放在程序的开始部分
B. C++程序的入口函数是main函数
C. 在C++程序中,要调用的函数必须在main()函数中
正确答案:B
题解:
main函数不一定要放在程序的开始部分,可以放在程序的任意位置;main函数是C++程序的入口;C++程序中,函数的的调用不一定要在main函数中,也可以在main函数外;
6、有以下程序运行结果为()
#include <iostream>
using namespace std;
char fun(char x, char y)
{
if (x < y)
return x;
return y;
}
int main()
{
int a = '1', b = '1', c = '2';
cout << fun(fun(a, b), fun(b, c));
return 0;
}
A. 运行出错
B. 2
C. 3
D. 1
正确答案:D
题解:
首先,我们需要将fun函数中的两个参数计算出来,其两个参数为fun函数的返回值,计算结果分别为1,2,然后带入得,结果为1;
7、对于int* pa[5];的描述,以下哪个选项是正确的()
A. pa是一个具有5个元素的指针数组,每个元素是一个int类型的指针;
B. pa是一个指向数组的指针,所指向的数组是5个int类型的元素;
C. pa[5]表示某个数的第5个元素的值;
D. pa是一个指向某个数组中第5个元素的指针,该元素是int类型的变量
正确答案:A
题解:
首先标识符pa首先跟[]结合,因此pa肯定是一个数组,该数组有五个元素,每个元素类型都为int*,故选A;
8、下面两个结构体,在#pragma pack(4)和#pragma pack(8)的情况下,结构体的大小分别是
struct One
{
double d;
char c;
int i;
}
struct Two
{
char c;
double d;
int i;
}
A. 16 24,16 24
B. 16 20,16 20
C. 16 16,16 24
D. 16 16,24 24
正确答案:C
题解:
本题主要考察结构体对齐规则,首先回忆一下结构对齐规则;如下所示;
题目中的 #pragma pack(4)和#pragma pack(8) 分别设置b中的默认对齐数,其中一个设置为4时,d占用0~7字节,c对齐到自己的大小1字节与默认对齐数4的最小值的整数倍处,即占用编号8的字节位置,i对齐到自己的大小4字节与默认对齐数4的最小值的整数倍处,即编号12~15;结构体整体的大小为最大对齐数的整数倍,#pragma pack(8) 则是将默认对齐数设置为8,同理按照规则最后计算出C选项;
9、下面哪个指针表达式可以用来引用数组元素a[i][j][k][l]()
A. (((a+i)+j)+k)+l)
B. *(*(*(*(a+i)+j)+k)+l)
C. (((a+i)+j)+k+l)
D. ((a+i)+j+k+l)
正确答案:B
题解:
选择题第四题已有讲解;此处略
10、由多个源文件组成的C程序,经过编辑、预处理、编译、链接等阶段会生成最终的可执行程序。下面哪个阶段可以发现被调用的函数未定义()
A. 预处理
B. 编译
C. 链接
D. 执行
正确答案:C
题解:
首先我们要明确每个阶段编译器做的事情,预编译阶段,编译器主要进行宏替换,去注释,条件编译,头文件的展开。编译阶段,编译器主要会将我们的代码转换成汇编代码,此时我们的函数会生成地址,并进行符号汇总等工作;接着是汇编阶段,主要将我们的汇编代码转换成二进制机器代码;最后是链接,将我们所有的目标文件结合起来,进行符号表汇总;在汇总符号时,发现函数仍然没有地址;此时便会报错,没有发现函数定义;
四、编程题题解
1、统计回文
本题主要的思路是将字符串2尝试分别插入到字符串1的每个位置,然后判断是否为回文字符串即可;
#include <iostream>
#include <string>
using namespace std;
// 检查是否回文
bool isPalindrome(const string& str)
{
int begin = 0;
int end = str.size() - 1;
while(begin < end)
{
if(str[begin] != str[end])
return false;
begin++;
end--;
}
return true;
}
int main()
{
string str1, str2;
cin >> str1 >> str2;
// 统计有几种插入方法
int count = 0;
// 注意这里是小于等于,因为可以插入到最后的位置
for(int i = 0; i <= str1.size(); i++)
{
// 拷贝str1
string tmp = str1;
tmp.insert(i, str2);
if(isPalindrome(tmp))
{
count++;
}
}
cout << count << endl;
return 0;
}
2、连续最大和
题解一:暴力法。循环遍历数组,找出最大连续区间和,伪代码下面已写出;不推荐;
题解二:动态规划法;我们想求出整个区间最大连续区间和,我们可以将问题转换为求以下标 i 结尾的最大连续区间和,即dp[ i ];而以 i+1 结尾的最大连续区间和为
dp[i + 1] = max(dp[ i ] + arr[i + 1], arr[i + 1]),这个公式便是我们推出的动态转移方程;
我们将dp数组求出,然后遍历dp数组,即可求出最大的连续区间和;这里我们还可以进行优化,无需创建dp数组,直接保存当前最大的dp数组值即可;代码如下
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n = 0;
cin >> n;
vector v(n, 0);
// 将数组存入vector中
for(int i = 0; i < n; i++)
{
cin >> v[i];
}
// 记录dp数组最大值
int max_sum = v[0];
// 记录当前下标的最大连续和
int sum = v[0];
for(int i = 1; i < v.size(); i++)
{
// 求当前下标下dp数组值
sum = max(sum + v[i], v[i]);
if(sum > max_sum)
{
// 更新dp最大值
max_sum = sum;
}
}
cout <<max_sum << endl;
return 0;
}