一、选择题
1.
1. 使用printf函数打印一个double类型的数据,要求:输出为10进制,输出左对齐30个字符,4位精度。以
下哪个选项是正确的?
A %-30.4e
B %4.30e
C %-30.4f
D %-4.30f
C
%m.ne表示以至数形式输出
%m.nf: m表示对齐数,n表示宽度,左对齐是%-x
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* :常量指针(指向常量的指针例如const int 表示常量整形,const int* p1表示指向常量整形的指针,被指向的内容不能被修改)
- 该指针 指向的 内存空间 不能被修改 。
- 指针可以被修改 。
- 不能通过指针解引用修改指针所指空间的值。
*const: 指针常量(int* const p3,int*表示指向整形的指针,int* const:表示该指针是常量指针)
- 该指针 指向的 内存空间 可以被修改 。
- 指针 不能 被修改 。
- 可以通过指针解引用改变指针所指空间的值。
1,2是常量指针并且2进行初始化,3是改变了指针的指向,所以是对的,6是错的。
4是指针常量,可以改变所指空间的值所以,5对,指针常量的指向不能被修改7错
综上6,7错
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是字符数组但是他们的初始化不同。并且都是在栈上开辟的能被修改,A正确
szX,szY是指针并且都指向同一个常量字符串,所以两者指向的都是这个常量字符串的地址。
所以B正确
C选项,acX占4个字符空间(有一个\0), acY指针3和字符空间。正确
szX的内容修改代表szX指针的指向改变了,而常量字符串abc并没有被修改,所以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
int*b =a代表指针b指向数组a的首元素地址
*b+=2----> *的优先级高于+=,所以先进行解引用操作,然后再加2并且赋值给首元素,所以数组a[]={3,2,3,4}。
*(b+2)=2------> b指向的地址先向右偏移2个位置,然后解引用,赋值为2,此时a[]={3,2,2,4}
b++----->此时指针指向数组第二个元素----2
*(b+2)---指向数组第四个元素---4。所以答案是(2,4)
5.
下列关于C/C++的宏定义,不正确的是()
A 宏定义不检查参数正确性,会有安全隐患
B 宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量
C 宏的嵌套定义过多会影响程序的可读性,而且很容易出错
D 相对于函数调用,宏定义可以提高程序的运行效率
B
宏是没有安全检测的,并且在预处理阶段进行宏替换,所以是无法进行调试的,所以要尽量使用const常量,所以B答案错误。
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
函数声明中的类型是char,int
所以先b后a
7.
7. 用变量a给出下面的定义:一个有10个指针的数组,该指针指向一个函数,该函数有一个整形参数并返回一个整
型数()
A int *a[10];
B int (*a)[10];
C int (*a)(int);
D int (*a[10])(int);
D
A选项: *的优先级低于[],所以a先和[]结合。a[10]表示数组,int* 表示这个数组中存的是int型的指针,是指针数组。不符合题意
B选项:(*a)表示指针,该指针指向int[10]数组,是数组指针,不符合题意
C是一个指针函数,这个函数有一个int参数,返回值类型是int,不符合题意
D是函数指针数组,有一个整形参数并返回一个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]
D
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
内存对齐问题: 4字节(32)19+11
4字节(32) 4 还剩28,存不下29个字节,再开辟4字节
4字节(32) 29
1字节(8)
总共是十三个字节,但是按照内存对齐规则,要是4的倍数,所以最小开辟16个。
10.
下面代码会输出()
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
A
(&a+1)先取变量a的地址,并根据a的地址获得下一个与a同类型的相邻地值。a+1=a+sizeof(int),所以指针ptr此时指向的是4的下一个位置。所以*(ptr-1)指向4。
二、编程题
1.排序子序列
时间限制:1秒 | 内存限制:32768K牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一 个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列.如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出 2。输入描述:输入的第一行为一个正整数n(1 ≤ n ≤ 10^5)第二行包括n个整数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。输出描述:输出一个整数表示牛牛可以将A最少划分为多少段排序子序列示例1:输入61 2 3 2 2 1输出2
解题思路:1. 本题依次比较整个数组2. a[i+1]>a[i] ,则进入非递减序列判断,直到遍历到下一个值不大于等于为止 count++ ,然后进行下一位置的判断3. a[i+1]<a[i] ,则进入非递增序列判断,直到遍历到下一个值不小于等于为止 count++ ,然后进行下一位置的判断4. a[i+1] == a[i] 不进行操作, ++i 进行下一位置遍历,因为相等既可以属于非递增序列,也可以属于非递减 序列。本题注意点:本题开始比较a[i+1]与a[i]进行比较,为了避免越界,数组定义为n+1个,同时给a[n] = 0;a[n] = 0带来的影响,我们分为三种情况讨论:
- 1. 若到a[n-1] 的最后一组是非递减序列,当i==n-1,a[i] >a[i+1],因为前面的数都是大于0的,这个输入 条件已经说明了(去看看题目输入条件描述),里面的循环结束,i++count++,i==n,外面的循环结 束。
- 2. 若到a[n-1] 的最后一组是非递增序列,当i==n-1,a[i] >a[i+1],因为前面的数都是大于0的,这个输入 条件已经说明了(去看看题目输入条件描述),循环再走一次,i++, i== n,面的循环结束,i++, count++,i==n+1,外面的循环结束。
- 3. 第三种情况 1 2 1 2 1最后一个数是单独的情况,后面补个0,序列变成1 2 1 2 1 0,当走完全面的序列 i==n-1时,a[i] > a[i+1],进入判断出一个非递增序列,count++,i++,循环结束。
- 4. 也就是说数组最后一个位置多增加一个0,不会影响第1、2情况的判断,主要是帮助第3情况的正确判断。
#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;
}
2.倒置字符串
|时间限制:1秒 | 内存限制:32768K将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I输入描述:每个测试输入包含1个测试用例:I like beijing. 输入用例长度不超过100输出描述:依次输出倒置之后的字符串, 以空格分割示例1:输入I like beijing.输出beijing. like I
- 这题的解题思路很简单,先对整体来一个倒置,此时的所有单词拼写都是倒置的,然后我们再以空格为界将每一个字符再进行倒置即可。
#include <iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string s;
getline(cin, s);
reverse(s.begin(),s.end());
//逆置每一个单词
auto left=s.begin();
while(left!=s.end())
{
auto right=left;
while(right!=s.end()&&*right!=' ') //注意一定要解引用
{
right++;
}
reverse(left,right);
if(right!=s.end())
{
left=right+1; //跳到下一个字符继续
}
else
left=right; // 此时right和s.end相遇,直接让left也相遇即可。
}
cout<<s<<endl;
}
注意reverse的头文件#include<algorithm>这个也叫算法头文件。