一
答案:9
解析:首先是定义了一个宏MAX_SIZE,被替换为A+B即5
位域是 C 语言中一种特殊的结构体成员,允许按位(bit)分配内存
位域的分配规则:
(1)不跨字节存储,位于必须在同一类型的内存单元内分配,剩余空间不足的时候会从下一个单元存储
(2)对齐过程中编译器会插入填充位以保证对齐
再看结构体,包含四个无符号字符型的成员,unsigned char大小为一个字节,位域中成员会先尝试在一个字节内分配
第一个成员占4位,第二个成员占两位,加起来一共六位,刚好存在第一个字节当中,但是第三个成员未规定大小,就是普通的unsigned char类型,占了一个字节,第四个成员为avail,占第三个字节的1位,所以一共占了三个字节。
此时我们再看空间开辟,在此表达式中宏会被直接替换为A+B,**注意宏定义时直接替换,要关注运算优先级和括号问题,**所以替换后为3*2+3=9.
二

答案:02 29 00 00
解析:
puc是一个char数组,每次跳转一个字节,结构体不是,它只有第一个元素单独享用一字节,其他三个元素一起共用一字节,所以puc被结构体填充后,本身只有两个字节会被写入,后两个字节肯定是0,至此AD排除,然后第一个字节是2就是2了,第二个字节比较麻烦,首先ucData0给了3其实是越界了,1位的数字只能是0或1,所以11截断后只有1,同理ucData1给的4也是越界的,100截断后是00,只有5的101是正常的。填充序列是类似小端的低地址在低位,所以排列顺序是00 101 00 1。也就是0010 1001,即0x29,故选B。
上面涉及到了二进制转换为十六进制的过程:
首先第二个字节中有八个bit位,按照从低位到高位排序,按照上面的二进制赋值后的取的低位

存储到内存中为:
再以每四位为一组,转换为十六进制,1010对应着A,0101对应着5,再加上十六进制的前缀0x,所以是0xA5.
三

答案:B
解析:
选项A:。枚举值必须是整数常量(包括字符常量,因为它们本质上是整数),不能是浮点数。
选项B:枚举类型在C语言中本质上就是整数类型,每个枚举常量对应一个整数值。
选项C:枚举值只能是整型常量,不能是字符串。
选项D:枚举类型可以作为函数参数传递,因为它本质上就是整数类型。
四

答案:C
解析:
首先我们要知道枚举的基本语法
cpp
enum 枚举名 {
标识符1, // 默认值为 0
标识符2, // 默认值为 1
标识符3, // 默认值为 2
...
标识符N // 默认值为 N-1
};
//默认赋值
enum Weekday {
Monday, // 0
Tuesday, // 1
Wednesday, // 2
Thursday, // 3
Friday, // 4
Saturday, // 5
Sunday // 6
};
//指定赋值
enum Color {
Red = 1,
Green = 2,
Blue = 4,
Yellow = 8
};
枚举默认从0开始,所以X1是0,故Y1是1,给了数字后会根据数字向后推,那么Z1是255,A1是256,所以B1是257,故选B。
五

答案:D
解析:
A:正确
B:正确
C:正确
D:枚举是一种类型,有类型检查,但是#define定义的符号没有类型检查,就是简单的替换,使用虽然方便,但是也很容易导致问题,所以更加推荐使用枚举常量。
六

答案:C
首先我们要知道联合体的特性
联合体(Union)的特性
(1)联合体的所有成员共享同一块内存,其大小由最大的成员决定。
(2)对齐方式:联合体的大小可能会受内存对齐(alignment)的影响。
联合体成员中短整型数组的大小为2*7=14个字节,而整形的大小为4个字节,正常下在无内存对齐的系统或者GCC上应该是共用一块最大的内存,大小为14个字节,但是在32位系统下,存在内存对齐的情况时因为int要求是4个字节就要内存对齐到16个字节。
七

答案:A
解析:
联合体a的成员位包含一个短整型k,大小为2个字节和一个字符数组,大小为两个字节,联合体共享一块内存

赋值后i[0]=0x39 i[1]=0x38由于小段字节序地址(低字节存储到低地址,高字节存储在高地址),所以组合起来就是0x3839.
八

答案;D
解析:
申请的内存空间不释放会产生内存泄漏,小型程序可以不关注,但是在中大型程序上影响极其深刻。故选D。AB是函数的基本功能,C选项比较特殊,malloc(0)是允许的,也会返回一个指针,只是没有空间所以不可使用而已。
九

答案:D
解析:
realloc在操作过程中是释放旧空间分配并返回新空间,所以返回的新空间也是需要释放的,故选D。AB是malloc和calloc的区别。C是realloc的基础功能。
十

答案:B
解析:
C++中内存区域分为堆,栈,,全局/静态存储区,常量存储区,代码区
堆:用于存储动态分配内存,特点是主要由程序员手动操作,内存大小灵活,但是分配和释放速度较慢,容易造成内存泄漏
栈:存储局部变量,函数参数和返回地址等,特点是编译器管理,内存分配和释放速度快,但是内存大小有限,容易造成栈溢出。
全局/静态存储区:存储全局变量和静态变量,特点是在程序启动时分配,程序结束时释放,分为已初始化区和未初始化区。
常量存储区:存储字符串常量和其他常量,特点是内容不可修改,生命周期和程序相同。
代码区:存储程序的机器指令,特点是只读,在程序加载时由操作系统分配。
十二:变种水仙花数

思路:
本题主要是要我们实现一个数可以被拆分成两部分的所有可能情况,这些情况的乘积之和等于该数本身。
所以我们要先遍历所有五位数,再对每个数进行拆分求和,判断是否等于原数,是的话就输出
c语言代码
cpp
#include<stdio.h>
int main()
{
int i,j;
for(i=10000;i<99999;i++)
{
int sum=0;
for(j=10;j<=10000;j=10*j)
{
sum+=(i/j)*(i%j);
}
if(sum==i)
printf("%d ",i);
}
return 0;
}
C++语言
cpp
#include <iostream>
using namespace std;
// 判断一个5位数是否是Lily Number
bool isLilyNumber(int num) {
int sum = 0;
// 拆分方式:1×4、2×3、3×2、4×1
sum += (num / 10000) * (num % 10000); // 1×4
sum += (num / 1000) * (num % 1000); // 2×3
sum += (num / 100) * (num % 100); // 3×2
sum += (num / 10) * (num % 10); // 4×1
return sum == num;
}
int main() {
for (int num = 10000; num <= 99999; ++num) {
if (isLilyNumber(num)) {
cout << num << " ";
}
}
return 0;
}
十三:序列中删除指定数字

思路:
首先要读取输入(序列长度,序列存储到数组/列表,删除整数),然后就要将要删除的整数与序列中的数据遍历对比,保留所有不等于该数的元素,最后将过滤后的序列空格分隔输出
C语言
cpp
#include <stdio.h>
int main()
{
int a=0;
scanf("%d",&a);
int arr[50]={0};
for(int j=0;j<a;j++)
{
scanf("%d",&arr[j]);
}
int b=sizeof(arr)/sizeof(arr[0]);
int c=0;
scanf("%d",&c);
for(int i=0;i<b;i++)
{
if(arr[i]!=c&&arr[i]!=0)
{
printf("%d ",arr[i]);
}
}
}
C++
cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
int N;
cin >> N;
vector<int> nums(N);
for (int i = 0; i < N; ++i) {
cin >> nums[i];
}
int target;
cin >> target;
vector<int> result;
for (int num : nums) {
if (num != target) {
result.push_back(num);
}
}
for (int i = 0; i < result.size(); ++i) {
if (i > 0) cout << " ";
cout << result[i];
}
return 0;
}
十四:判断大小端字节序
大端:高位字节存储在低地址
小端:低位字节存储在低地址
思路一:联合体,通过char数组访问int的单个字节,从而访问到低地址的字节
cpp
#include <stdio.h>
int main()
{
union
{
int num;
char bytes[sizeof(int)];
} test;
test.num = 0x12345678;
if (test.bytes[0] == 0x78)
{
printf("小端\n");
} else
{
printf("大端\n");
}
return 0;
}
思路二:直接强制类型转换,通过将int指针强制转换为char指针,访问第一个字节
cpp
#include <stdio.h>
int main()
{
int num = 0x12345678;
char *p = (char *)#
if (*p == 0x78)
{
printf("小端\n");
} else
{
printf("大端\n");
}
return 0;
}
思路三:使用宏
cpp
#include <iostream>
#include <cstdint>
int main()
{
if constexpr (std::endian::native == std::endian::little)
{
std::cout << "小端" << std::endl;
} else
{
std::cout << "大端" << std::endl;
}
return 0;
}