文章目录
- C/C++笔试练习
- 1.常量指针和指针常量
- (1)常量指针和指针常量的定义
- (2)判别常量指针和指针常量
- (3)常量指针和指针常量的特性
- 2.结构体内存分配
- (4)计算结构体大小
- (5)位段的内存分配计算
- 3.完善程序
- (6)统计输入大写字母的出现次数
- 4.编程题
- (7)排序子序列
- (8)倒置字符串
C/C++笔试练习
1.常量指针和指针常量
(1)常量指针和指针常量的定义
请找出下面程序中有哪些错误()
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
“常量指针”和“指针常量”是两种特殊类型的指针,它们有着各自的特性和用途。
(1)常量指针(Constant Pointer):
常量指针是指向常量的指针。这意味着你不能通过这个指针来改变它所指向的值,但你可以改变这个指针本身所指向的地址。例如:
int a = 5;
int b = 10;
int * const ptr = &a;
*ptr = 10; // 错误,不能修改ptr所指向的值
ptr = &b; // 正确,可以修改ptr所指向的地址
(2)指针常量(Pointer Constant):
指针常量是指常指针,即指针本身是个常量,不能改变它的指向,但它所指向的值可以改变。例如:
int a = 5;
int b = 10;
const int * ptr = &a;
*ptr = 10; // 错误,不能修改ptr所指向的值
ptr = &b; // 错误,不能修改ptr所指向的地址
判别常量指针和指针常量我们可以通过const和*的位置来判断:
int const * p:const 在 *p 前面为常量指针
int * const p:* 在const前面为指针常量
(6)int const *p2 = &i; 这里定义了一个指向 const int 的指针 p2,然后试图修改它指向的值 *p2 = 30;,这是不允许的,因为 *p2 是一个常量,此时const修饰的是p2指向的值,所以不能被修改。
(7)int *const p3 = &i; 这里定义了一个 const 指针 p3,然后试图改变它的指向 p3 = &j;,这是不允许的,因为 p3 是一个常量指针,此时const修饰的是p3,是一个指针,所以不能改变它的指向。
答案选:C
(2)判别常量指针和指针常量
下面3段程序代码的效果一样吗()
int b;
(1)const int *a = &b;
(2)int const *a = &b;
(3)int *const a = &b;
A (2)=(3) B (1)=(3)
C (1)=(2) D 都不一样
通过上面的概念我们可以得到:(1)是常量指针(2)是常量指针(3)是指针常量
答案选:C
(3)常量指针和指针常量的特性
请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变。
A.const int const *x = &y;
B.int * const x = &y;
C.const int *x = &y;
D.int const *x = &y;
E.const int * const x = &y;
结合第(1)(2)对于常量指针和指针常量的介绍
答案选:B
2.结构体内存分配
(4)计算结构体大小
在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是()
struct A
{
int a;
short b;
int c;
char d;
};
struct B
{
int a;
short b;
char c;
int d;
};
A 16,16 B 13,12
C 16,12 D 11,16
结构体内存对齐
答案选:C
(5)位段的内存分配计算
在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
为了放下unsigned类型元素,系统申请了四个字节即32个比特位,此时可以放下a和b总共30比特位,接下来的c占4比特位,前四个字节放不下了,所以再开辟四个新的字节空间放入c,接下来的的d占了29个比特位,第二个字节已经有了4个比特位,29+4=33>32放不下,所以再开辟四个字节。放入上面的5个元素时,struct A一共占13个字节,根据结构体对其规则,结构体的大小必须为最大对齐数的整数倍,所以还要申请3个字节,使其成为4的整数倍。
答案选:C
3.完善程序
(6)统计输入大写字母的出现次数
以下 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’] B ++count[‘A’-a[i]]
‘Z’-i ‘A’+i
count[‘Z’-i] count[i]
C ++count[i] D ++count[‘Z’-a[i]]
i ‘Z’-i
count[i] count[i]
们需要统计给定输入中每个大写字母的出现次数。给定的输入是一个字符数组a,数组长度为n。
首先,我们定义一个长度为26的整型数组count,用来存储每个大写字母出现的次数。数组下标0对应字母’A’,下标1对应字母’B’,以此类推,下标25对应字母’Z’。
接下来,我们遍历输入字符数组a中的每个字符。对于每个字符,我们可以将其与字符’Z’做差,得到对应的数组下标,然后将对应的计数器加1。
最后,我们遍历计数器数组count,输出每个字母和其出现的次数。
答案选:D
4.编程题
(7)排序子序列
排序子序列
解题思路:
(1)应该依次比较整个数组
(2)a[i+1]>a[i] ,则进入非递减序列判断, 直到遍历到下一个值不大于等于为止count++,然后进行下一位置的判断
(3)a[i+1]<a[i],则进入非递增序列判断, 直到遍历到下一个值不小于等于为止count++,然后进行下一位置的判断
(4)a[i+1] == a[i]不进行操作,++i进行下一位置遍历,因为相等既可以属于非递增序列,也可以属于非递减序列。
#include <iostream>
#include<vector>
using namespace std;
int main() {
int n=0;
cin>>n;
vector<int> v(n,0);
for(int i=0;i<n;i++)
{
cin>>v[i];
}
//遍历整个vector
int i=0;
int count=0;
while(i<n)//如果有递增或者递减情况改变,计数器++
{
if(v[i]>v[i+1])//递减序列
{
while(i<n&&v[i]>=v[i+1])
{
i++;//满足递减情况就一直向后移动
}
//不满足了直接退出,count++
count++;
i++;//寻找下一段子序列的情况
}
else if(v[i]<v[i+1])//递增序列
{
while(i<n&&v[i]<+v[i+1])
{
i++;//满足递增情况就一直向后移动
}
count++;
i++;
}
else//相等的元素直接向后走
{
i++;
}
}
cout<<count;
return 0;
}
(8)倒置字符串
倒置字符串
解法一:
先将整个字符串逆置过来,再遍历字符串,找出每个单词,对单词逆置。这里我们使用了stl算法中的reverse,所以这里使用迭代器遍历string。
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
string str;
getline(cin,str);
reverse(str.begin(),str.end());//整体反转
//再进入循环单个反转
string::iterator start=str.begin();
while(start!=str.end())
{
auto end=start;
while(*end!=' '&&end!=str.end())
{
end++;//找单个单词
}
//找到后反转单个单词
reverse(start,end);
//更改start和end的位置,使其指向下一个位置
if(end!=str.end())
{
start=end+1;
}
else
{
start=end;
}
}
cout<<str;
return 0;
}
解法二:
直接利用cin>>s接收输入,遇到空格就结束了,自然就分割开了每个单词,其次将每次接收到的单词拼接到之前串的前面就逆置过来了。
#include <iostream>
#include <string>
using namespace std;
// cin读取string时自动会被空格分隔开,用另一个字符串存储进行逆序输出
int main()
{
string s1, s2;
cin >> s2;
while (cin >> s1)
s2 = s1 + " " + s2;
cout << s2 << endl;
return 0;
}