大型网站建设哪个好,校园微网站建设方案,聊城网站制作工作室,中牟高端网站建设C语言练习题 文章目录 C语言练习题题目一题目二题目三题目四题目五题目六题目八 题目一
#include stdio.h
//VS2022,默认对齐数为8字节
union Un
{short s[7];int n;
};int main()
{printf(%zd, sizeof(union Un));return 0;
}代码运行结果: 16 sizeo…C语言练习题 文章目录 C语言练习题题目一题目二题目三题目四题目五题目六题目八 题目一
#include stdio.h
//VS2022,默认对齐数为8字节
union Un
{short s[7];int n;
};int main()
{printf(%zd, sizeof(union Un));return 0;
}代码运行结果: 16 sizeof计算的是联合体的大小联合体的大小并不是联合体成员中最大的那个联合体也是有对齐的 在上述代码中联合体中有两个成员short s[7]占14字节对齐数为1int n和short s[7],共用空间对齐数为414字节并非联合体中最大对齐数4的整数倍所以将对齐至16字节
题目二
#include stdio.h
//VS2022,默认对齐数为8字节
typedef struct {int a;char b;short c;short d;
}AA_t;int main()
{printf(%zd, sizeof(AA_t));
}代码运行结果: 12 上述问题设计结构体内存对齐
结构体第一个成员对齐至偏移量为0的位置其他成员按照取默认对齐数与改成员的大小的较小值对齐且对齐至整数倍结构体的总大小为最大对齐数的整数倍 在上述代码中 a 为结构体第一个成员位于偏移量为0的位置且占4个字节 b 的大小为1字节默认对齐数为8取较小值1取对齐数1的整数倍也就是偏移量为4的位置占1个字节 c 的大小为2字节默认对齐数为8取较小值2取对齐数2的整数倍也就是偏移量为6的位置占2个字节 d 的大小为2字节默认对齐数为8取较小值2取对齐数2的整数倍也就是 偏移量为8的位置占2个字节 总大小为10字节10字节不是最大对齐数4的倍数对齐至12字节
题目三
#include stdio.h
#pragma pack(4)
/*编译选项表示4字节对齐 平台VS2022。语言C语言*/
//假设long 是4个字节
int main(int argc, char* argv[])
{struct tagTest1{short a;char b;long c;long d;};struct tagTest2{long a;short b;char c;long d;};struct tagTest3{short a;long b;char c;long d;};struct tagTest1 stT1;struct tagTest2 stT2;struct tagTest3 stT3;printf(%zd %zd %zd, sizeof(stT1), sizeof(stT2), sizeof(stT3));return 0;
}
#pragma pack()代码运行结果: 12 12 16 #program是用于修改默认对齐数
#program pack(4) //修改默认对齐数
#program pack( ) //取消设置的对齐数还原为默认对齐数stT1
第一个成员a位于偏移量为0的位置 第二个成员b的大小为1字节默认对齐数为4取较小值1对齐至1的整数倍也就是偏移量为3的位置 第三个成员c的大小为4字节默认对齐数为4取较小值4对齐至4的整数倍也就是偏移量为4的位置 第四个成员d的大小为4字节默认对齐数为4取较小值4对齐至4的整数倍也就是偏移量为8的位置 总大小为12字节为最大对齐数4的整数倍所以stT1的大小为12字节
stT2 第一个成员a位于偏移量为0的位置 第二个成员b的大小为2字节默认对齐数为4取较小值2对齐至2的整数倍也就是偏移量为4的位置 第三个成员c的大小为1字节默认对齐数为4取较小值1对齐至1的整数倍也就是偏移量为6的位置 第四个成员d的大小为4字节默认对齐数为4取较小值4对齐至4的整数倍也就是偏移量为8的位置 总大小为12字节为最大对齐数4的整数倍所以stT2的大小为12字节
stT3 第一个成员a位于偏移量为0的位置 第二个成员b的大小为4字节默认对齐数为4取较小值4对齐至4的整数倍也就是偏移量为4的位置 第三个成员c的大小为1字节默认对齐数为4取较小值1对齐至1的整数倍也就是偏移量为8的位置 第四个成员d的大小为4字节默认对齐数为4取较小值4对齐至4的整数倍也就是偏移量为12的位置 总大小为16字节为最大对齐数4的整数倍所以stT2的大小为16字节 结论 相同大小的结构体成员位于不同位置结构体的总大小不一样建议让占⽤空间⼩的成员尽量集中在⼀起 题目四
//VS2022 X64
#define MAX_SIZE AB
struct _Record_Struct
{unsigned char Env_Alarm_ID : 4;unsigned char Para1 : 2;unsigned char state;unsigned char avail : 1;
}*Env_Alarm_Record;
struct _Record_Struct *pointer (struct _Record_Struct*)malloc(sizeof(struct _Record_Struct) * MAX_SIZE);当A2 B3时pointer分配 9 个字节的空间
解释 #define是在C和C中使用的预处理器指令用于创建宏。编译器在执行代码时会将define定义的标识符全都替换成相应的值
先计算位段的大小 冒号后的数字表示bit位在VS2022中位段的内存分配是从右到左的其次遇到不够的时候直接舍去
Env_Alarm_ID 占4个bit位Para1 占2个bit位第一个字节剩1个bit位不够下一个成员舍去这一个bit位 state 占8个bit位第二个字节分配给state使用 avail 占1个bit位第三个字节中的一个bit位给avail 使用 总共占3个字节
sizeof(struct _Record_Struct计算结果为8
题目给出A 2 B 3 sizeof(struct _Record_Struct) * MAX_SIZE 其中的 MAX_SIZE 会被替换为A B 也就是 3 * 2 3 计算结果为9
malloc为动态内存开辟如果开辟成功则返回一个指针开辟失败则返回一个NULL返回的类型为void*
struct _Record_Struct *pointer (struct _Record_Struct*)malloc(sizeof(struct _Record_Struct) * MAX_SIZE);整句代码的意思为给pointer初始化赋值一个指针指针指向的内容为开辟好的9字节的内存空间
题目五
在X86下小端字节序存储
#includestdio.h
int main()
{union{short k;char i[2];}*s, a;s a;s-i[0] 0x39;s-i[1] 0x38;printf(%x\n, a.k);return 0;
}代码运行结果: 3839 解释 short 和 char i [2] 共用空间打印的是16进制的a.k也就是打印两个字节的内容 由于是小端存储在低地址存放的是低位字节高地址存放高位字节的内容也就是倒着存放的举例0x11223344在内存中是 44 33 22 11 所以打印的结果为3839
题目六
enum ENUM_A
{X1,Y1,Z1 255,A1,B1,
};
enum ENUM_A enumA Y1;
enum ENUM_A enumB B1;
printf(%d %d\n, enumA, enumB);代码运行结果: 1 257 枚举成员变量默认为从0开始依次递增1 也就是说 X1 0 Y1 2 Z1 255 A1 256 B1 257 所以打印结果为1 257
题目八
#include stdio.h
int main()
{unsigned char puc[4];struct tagPIM{unsigned char ucPim1;unsigned char ucData0 : 1;unsigned char ucData1 : 2;unsigned char ucData2 : 3;}*pstPimData;pstPimData (struct tagPIM*)puc;memset(puc, 0, 4);pstPimData-ucPim1 2;pstPimData-ucData0 3;pstPimData-ucData1 4;pstPimData-ucData2 5;printf(%02x %02x %02x %02x\n, puc[0], puc[1], puc[2], puc[3]);return 0;
}代码运行结果: 02 29 00 00 位段总共占2个字节的空间其中ucPim1占了1个字节ucData0 占了1个bit位ucData1 占了2个bit位ucData2 占了3个bit位
2 的二进制为 0010 可以全部存入 ucPim1 3 的二进制为 0011 只能存1bit位到 ucData0 4 的二进制为 0100 只能存2bit位到 ucData1 5 的二进制为 0101 只能存3bit位到 ucData2 将值存入puc数组中且数组默认元素为0
所以 第一个字节中的内容为 0000 0010 转为16进制为 0x02 第二个字节中的内容为 0010 1001 转为16进制为 0x29 第三个字节没被修改为0 第四个字节没被修改为0
%02x打印16进制如果小于宽度2则补0 所以打印结果为 02 29 00 00