【基础强训】day2

一、选择题

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表示指向常量整形的指针,被指向的内容不能被修改)

  1. 该指针 指向的 内存空间 不能被修改 。
  2. 指针可以被修改 。
  3. 不能通过指针解引用修改指针所指空间的值。

*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

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);

函数声明中的类型是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]

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+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:
输入
6
1 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-1a[i] >a[i+1],因为前面的数都是大于0的,这个输入 条件已经说明了(去看看题目输入条件描述),里面的循环结束,i++count++i==n,外面的循环结 束。
  • 2. 若到a[n-1] 的最后一组是非递增序列,当i==n-1a[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,不会影响第12情况的判断,主要是帮助第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>这个也叫算法头文件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值