【C语言进阶】题目练习

目录

1.箭形图案

思路: 

代码:

2. 公务员面试

分析:

代码 :

3. 判断结构体大小(1)

答案:

分析:

4.判断结构体大小(2)

答案:

分析:

5.宏定义+计算位段大小的选择题

分析: 

答案:

6.位段与指针

分析:

答案:

7. 结构体大小判别

分析: 

答案:

8.联合体的大小

分析:

答案:

9.大小端字节序

分析:

答案:

10.枚举选择题

答案:

11. 编程题:找出只出现一次的数字

分析1:

代码1:

思路2:

代码2:

12.atoi的实现

13.文件读写的选择题(1)

14.看代码说功能

15. 文件读写的选择题(2)

16.预处理的选择题

17.预处理的分析题

18.feof函数的选择题

19.宏替换的选择题(1)

20.宏替换的选择题(2)

21.写一个宏将一个整数的二进制位的奇数和偶数进行交换

思路:


1.箭形图案

KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的箭形图案。

输入描述:

本题多组输入,每行一个整数(2~20)。

输出描述:

针对每行输入,输出用“*”组成的箭形。

输入

2

输出

    ***
******

思路: 

        可以把图形分为上下两部分,如果输入n上面就是n行,下面就是n+1行;

上半部分:n行

空格:第一行有四个空格,第二行有两个空格,我们可以把2个空格当做一组,第一行打印两组,第二行打印一组;每一行需要递减,所以内部循环减去外面的行数。

*:和行数有关,第一行是一个,第二行是两个。

下半部分:n+1行

空格:两个空格为一组,第一行是0组空格,第二行是1组空格,第三行是2组空格,就是行数-1。

*:第一行是3个*,第二行是2个*,第3行是1个*,每次从n+1开始,需要再减去行数。

代码:

#include<stdio.h>int main() 
{int n = 0;while(scanf("%d",&n)){
// 上半部分for (int i = 0; i < n; i++){for (int j = 0; j < n - i; j++){printf("  "); // 先打印空格,两个为一组}for (int k = 0; k <= i; k++) // 第一行一个*,第二行两个*,跟行号有关{printf("*");}printf("\n");}// 下半部分for (int i = 0; i < n + 1; i++){// 空格for (int j = 0; j < i; j++){printf("  ");}for (int k = 0; k < n + 1 - i; k++){printf("*");}printf("\n");}}return 0;
}

2. 公务员面试

描述

公务员面试现场打分。有7位考官,从键盘输入若干组成绩,每组7个分数(百分制),去掉一个最高分和一个最低分,输出每组的平均成绩。

(注:本题有多组输入)

输入描述:

一行,输入7个整数(0~100),代表7个成绩,用空格分隔。

输出描述:

一行,输出去掉最高分和最低分的平均成绩,小数点后保留2位,每行输出后换行。

示例1

输入:

99 45 78 67 72 88 60

输出:

73.00

分析:

        本身的逻辑不难,难的是如何oj,我们之前是每次读取一个数字,我们这道题可以一次读取一个数字,也能读取一个数字。

        若读取一个数字,我们需要一个变量n来记录读取数字的个数,每次读取n需要++;

        定义最大最小值并设立处置,每次读取一个数字就需要判断是否是最大或者最小值,以此保证最小最大值保持更新,一旦n ==7,说明数字够了,就开始计算平均值,需要将这些变量进行重新初始化以待下一次实例的调用。

代码 :

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>int main() {int score = 0;int max = 0;int min = 100; int n = 0;int ret = 0;while (scanf("%d", &score) == 1) {n++;if(score > max){max = score;}if (score < min ) {min = score;}ret += score;if (n == 7) {printf("%.2lf\n",(ret - min - max)/5.0);n = 0;ret = 0;max = 0;min = 100;}}return 0;
}

3. 判断结构体大小(1)

判断以下两个结构体的大小:

#include<stdio.h>struct A 
{int a;short b;int c;char d;
};struct B 
{int a;short b;char c;int d;
};int main() 
{struct A a = { 0 };struct B b = { 0 };printf("%d\n",sizeof(a)); // 16printf("%d\n",sizeof(b)); // 12return 0;
}

答案:

16,12

分析:

A:a占4个字节偏移量0-3;b占2个字节,对齐数是2,偏移量是4-5;c占4个字节,偏移量是4,6不是4的倍数,所以偏移量是8-11;最后一个d是占1个字节,所以偏移量是12;总共占用13个字节,13不是最大对齐数(4)的倍数,那么最近的倍数是16;

B: a占4个字节偏移量0-3;b占2个字节,对齐数是2,偏移量是4-5;c占1个字节,偏移量是6;d占4个字节,最小对齐数是4,7不是4的倍数,所以偏移量是8,占用8-11;总共占用12个字节,12是最大对齐数的倍数,所以答案是12;

4.判断结构体大小(2)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#pragma pack(4) // 4字节对齐
struct S1
{short a; // 0-2char d; // 3long b; // 4-7 long c;// 8-11 
};struct S2
{long b;// 0-3short c;// 4-5char d;// 6long a;// 8-11 
};
struct S3
{short c;// 0-1long b;// 4-7char d;// 8long a;// 12-15
};
int main() 
{printf("%d\n", sizeof(struct S1));printf("%d\n", sizeof(struct S2));printf("%d\n", sizeof(struct S3));}

答案:

12 12 16

分析:

见注释,这里需要注意的是32位系统重long占4个字节。

5.宏定义+计算位段大小的选择题

分析: 

①首先需要判断位段占用的bit位数,首先第一个成员变量开辟一个字节的空间,8bit,第一个成员+第二个成员用了6bit,剩余2bit,此时第三个成员变量需要1个字节,需要单独开辟,第四个成员变量虽然只需要1bit,但仍然要开辟1字节,总共3字节。

②注意宏定义:3* 2 + 3 = 9

答案:

D

6.位段与指针

分析:

        首先定义一个char类型的数组,有四个元素;定义一个位段指针指向这个数组;将数组全部初始化为0,;

        位段的第一个成员是占用1个字节,剩下三个成员占用一个字节,所以这个位段整体占用两个字节。

        需要给成员赋值,第一个成员赋值为2,8bit足以存下;

第二个成员只有1bit需要存3,所以只能取低1位bit位;

第三个成员只有2bit需要存4,所以只能取低2位bit位;

第四个成员只有3bit需要存5,刚好可以存下。

此时内存分布如下图所示:

此时按照16进制打印两位来输出每一个字节那么就是:

答案:

0000  0010 -》 02

0010 1001 -》  29

0000 0000 -》  00

0000 0000 -》  00 

7. 结构体大小判别

分析: 

总大小是10B,最大对齐数是4,所以必须是4的倍数12B。

答案:

12字节 

8.联合体的大小

union Un
{short s[7];int n;
};

分析:

        联合体的奥义是成员公用内存,所以s占用14个字节,n占用4个字节,此时14个字节够用了,最后需要考虑最大对齐数是4,所以最终应该是4的倍数,16字节。

答案:

16

9.大小端字节序

注:32位cpu平台

分析:

 首先联合体是2B,这里分别访问数组的第一个元素和第二个元素,这里其实就是给两个字节填充数据;这里需要打印k变量,由于是两个字节,这里就存在字节序大小端的问题,在vs编译器中是采用小端存储,即低字节存在低地址高字节存在高地址(倒着存)那么输出就是0x3839(还原数据,先打印高地址再打印低地址)

 

答案:

3839 

10.枚举选择题

答案:

枚举从0开始,依次递增1,中途可以修改,再依次递增1;

11. 编程题:找出只出现一次的数字

一个数组中有两个数字出现一次其余数字出现了两次,找到这两个只出现了一次的数字。

力扣原题

分析1:

暴力求解,每个元素都要对n个元素进行比较,如果标记到两个元素相等cnt++,如果cnt是1,那么说明只和自己相等,那就是单独的数字了。

代码1:

#include<stdio.h>void find_dog(int arr[], int sz)
{for (int i = 0; i < sz; i++){int cnt = 0;for (int j = 0; j < sz; j++){if (arr[i] == arr[j]){cnt++;}}// cnt = 1的时候需要记录下来if (cnt == 1) {printf("%d是单独的数字!\n",arr[i]);}}
}int main()
{int arr[10] = { 1,2,3,4,5,1,2,3,4,6 };int sz = sizeof(arr) / sizeof(arr[0]);find_dog(arr, sz);return 0;
}

思路2:

        可以利用异或的特性,两个数字异或如果相同结果就是0,相异结果就是1,所以将这所有的数字全部异或,最后的结果一定不为0,我们假定最后异或出来的结果的最后一位是1,那么相当于最后一位是相异的,那么我们可以按照最后一位是0或者1将所有数字分成两组,这两组分别进行异或,就能得到最终相异的数字。

①所有数字异或得到不为0的结果。

②从结果中找到二进制的某一位是1。

③旨在按照此位进行分组,组内进行异或,最后的结果就是其中一个单独的数字。

核心思想:按照根据异或的原理将两个单独的数字分别分为两组,组内进行异或(其余数字都是成对,异或就是0),最终每组只剩下那个单独的数字。

代码2:

/*** Note: The returned array must be malloced, assume caller calls free().*/
int* singleNumber(int* nums, int numsSize, int* returnSize) 
{int sum = 0;int* ret = malloc(2 * sizeof(int));int pos = 0;int dog1 = 0;int dog2 = 0;for(int i = 0;i < numsSize;i++){// 1.全部异或得到一个数字sum ^= nums[i];}// 2. 根据这个数字的第n位为1进行分组// 3.计算第n位为1for(int i = 0;i < 32;i ++){if(((sum >> i)&1) == 1){pos = i;break;} }//4. 按照第pos位进行分组,组内进行异或for(int i = 0;i < numsSize;i++){if((nums[i] >> pos)&1 == 1){dog1 ^= nums[i];}else{dog2 ^= nums[i];}}ret[0] = dog1;ret[1] = dog2;*returnSize = 2;return ret;
}

12.atoi的实现

        即字符串转换成整数,例如“123456” -》 123456、“-123456” -》 -123456,遇到非数字的时候停止转化,“-123abc456” -》 -123;

        需要考虑以下几点:

①空指针。assert判断。

②空字符串。字符串只有\0,如果返回0,那就会和“0”产生歧义。

③空格。使用isspace判断是否是空格,是空格那么str++跳过空格。

④+-号。定义一个正负号的变量,如果遇到+变量置为1,遇到-变量置为-1,最后返回只需要结果*flag即可。

⑤非数字字符。若字符串为123ABC,应该输出123

正常处理:需要将每一位的数字转换成整型,存入变量,接下来变量只需要*10 + 新这一位的数字即可。

⑥越界问题:当字符串内的数字非常大,此时就可能发生越界,此时我们需要判断是正数越界还是负数越界

做到这里,我们可以将简易版的代码写出:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<ctype.h>
#include <limits.h>
// 判断这个字符串是否合法
enum STATUS
{VALID,INVALID
}status = INVALID;int my_atoi(const char* str)
{// 正负标记int flag = 1;long long ret = 0;assert(str);// 空字符串,返回非法0if (*str == '\0'){return 0;}// 判断空白字符,跳过while (isspace(*str)){str++;}// 遇到+-号if (*str == '+'){flag = 1;str++;}else if (*str == '-'){flag = -1;str++;}// 正常处理数字字符串while (*str != '\0'){if (isdigit(*str)) {ret = ret * 10 + flag * (*str - '0');// *str是字符,需要-字符'0'转换成对应的数字// 判断是否越界if (ret > INT_MAX || ret < INT_MIN) {status = INVALID;return 0;}}else{// 不是数字字符status = INVALID;return str;}str++;}// 没有提前返回说明是正常处理完毕if(*str == '\0'){status = VALID;}return ret;
}int main()
{char arr[100] = "123456";int ret = my_atoi(arr);if (status == INVALID){printf("数字不合法!:%d\n", ret);}else if (status == VALID){printf("数字为:%d\n", ret);}return 0;
}

测试:

含非数字字符:

 

负数: 

溢出:

 

13.文件读写的选择题(1)

B:getchar适用于标准输入流。

14.看代码说功能

统计文件的字符个数 

15. 文件读写的选择题(2)

 

D:sprintf是把格式化的数据写入字符串中。

16.预处理的选择题

 C:链接阶段会查找符号表,看这个函数是否存在。

17.预处理的分析题

判断变量的类型

#define INT_PTR int*
typedef int* int_ptrINT_PTR a,b;
int_ptr c,d;

替换完毕后是:int *a,b,那么a是int*类型,b是int类型;

下面不一样,把int*当做一个整体的类型,c,d都是int*类型。

18.feof函数的选择题

A:错误,解析详见B选项。

19.宏替换的选择题(1)

答案:70

直接替换计算: 2*(4 + Y(5+1)),Y(5+1)是31。

20.宏替换的选择题(2)

答案:B 

21.写一个宏将一个整数的二进制位的奇数和偶数进行交换

思路:

        假如红色位置是偶数位,绿色位置是奇数位;将奇数位的数字全部拿出来,向右移动一位;同理将偶数位的数字都拿出来,向左移动一位,最后相加即可。 

        怎么拿?以偶数位举例,与一个偶数位都是1,奇数位都是0的32位数字即可。

 

#define SWAP_BIT(n) (((n&0x55555555)<<1) + ((n&0xaaaaaaaa)>>1))int main() 
{int n = 10;printf("%d\n", SWAP_BIT(n));return 0;
}

 这里用10进行测试,1010 -> 0101(5)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/916753.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/916753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Blender入门笔记——建模篇(二)

前言 在数字建模的世界中&#xff0c;快捷键和高效的操作是提高工作效率的关键。本手册为您提供了常用的建模快捷键及操作技巧&#xff0c;帮助您在各种建模软件中更加得心应手。无论是进行点、线、面操作&#xff0c;还是调整视图、切换模式&#xff0c;这些快捷方式都将成为…

sqlite3学习---基础知识、增删改查和排序和限制、打开执行关闭函数

目录 一、数据库基础知识 1.分类 2.名词 3.嵌入式数据库 4.特点 5.sqlite3的安装 5.1在线安装 5.2编译 5.3验证是否安装成功 5.4sqlite3的使用 6.创建一个数据库 7.系统维护命令 二、数据库的创建和删除 1.创建一个表 1.1用法 1.2代码示例 2.删除一个表 2.1用…

Class24AlexNet

Class24AlexNet AlexNet AlexNet于2012年ImageNet 图像识别挑战赛&#xff08;ILSVRC-2012&#xff09;中以 top-5 错误率15.3%获得冠军&#xff0c;远远领先第二名。它首次在大型图像数据集上证明了深层卷积神经网络的强大能力。 AlexNet 的总体结构 AlexNet 总共有 8 层具有学…

枚举中间位置高级篇

参考资料来源灵神在力扣所发的题单&#xff0c;仅供分享学习笔记和记录&#xff0c;无商业用途。 核心思路&#xff1a;参考枚举中间位置基础篇-CSDN博客 力扣题单练习(灵神题单中摘取题目) 447. 回旋镖的数量 核心思路&#xff1a; 因给出的点都不相同&#xff0c;所以不会…

主数据管理系统能代替数据中台吗?

目录 一、主数据管理系统≠数据中台 1. 主数据管理系统&#xff1a;管的是 “不变的核心数据” 2. 数据中台&#xff1a;管的是 “流动中的价值” 二、为什么企业更该先建 MDM&#xff1f; 1. 数据中台解决不了数据本身问题 2. MDM 可以解决常见的基础问题 3. 数字化转型…

Nmap 终极教程:安装、常用命令及法律法规指南

Nmap 终极教程&#xff1a;安装、常用命令及法律法规指南 Nmap&#xff08;Network Mapper&#xff09;是一款强大的 网络扫描和安全审计工具&#xff0c;广泛用于渗透测试、网络探测和系统管理。本教程涵盖 安装方法、常用命令详解、输出解析 以及 法律法规注意事项&#xff…

开源嵌入式数组引擎TileDB的简单使用

TileDB 是C编写的存储和访问通用多维数组引擎&#xff0c;它的官方Github网站https://github.1git.de/TileDB-Inc/TileDB 1.下载源代码和二进制库 源代码https://github.1git.de/TileDB-Inc/TileDB/archive/refs/tags/2.28.1.tar.gz 选择符合你的机器CPU架构和操作系统的库 二进…

AI对服务器行业的冲击与启示:从挑战走向重构

更多云服务器知识&#xff0c;尽在hostol.comAI&#xff08;人工智能&#xff09;技术的迅猛发展&#xff0c;已深刻影响了多个行业&#xff0c;服务器行业亦不例外。在过去&#xff0c;服务器的主要任务是简单地提供存储、计算和传输数据的服务。然而&#xff0c;随着AI的崛起…

基于三台主机搭建 Web 服务环境:Nginx、NFS 与 DNS 配置全流程

基于三台主机搭建 Web 服务环境&#xff1a;Nginx、NFS 与 DNS 配置全流程 一、引言 在当今数字化的时代&#xff0c;搭建一个稳定、高效的 Web 服务环境是许多开发者和运维人员的常见需求。本文将详细介绍如何利用三台主机搭建一个包含 Nginx、NFS 和 DNS 服务的 Web 环境&…

MySQL——MVCC

1.为什么需要MVCC在并发场景下&#xff0c;读写操作会面临严重的冲突问题&#xff1a;1.读操作如果遇到写操作&#xff0c;要么“读到未提交的脏数据”&#xff0c;要么“被写操作阻塞&#xff08;等待锁释放&#xff09;”&#xff1b;2.写操作如果遇到读操作&#xff0c;要么…

数据结构第2问:什么是算法?

算法 算法是一组用于解决具体问题的、明确的、有序的步骤或规则&#xff0c;能够在有限的时间内通过这些步骤得到问题的答案。 算法的5个重要特性&#xff1a; 有穷性&#xff1a;算法必须在有限的步骤内结束&#xff0c;不能无限循环&#xff0c;保证最终能够得到结果。确定性…

12-大语言模型—Transformer 打地基,下游任务盖出百样房,指标来验收|下游任务白话指南

目录 1、核心逻辑&#xff1a;Transformer 的 “语言处理闭环” 2、转导与感知 → 模型咋 “理解语言”&#xff1f; 2.1、 人类 vs 机器的 “语言理解逻辑” 2.2、 自注意力机制&#xff1a;模型 “理解语言” 的数学核心 2.2.1、通俗拆解 2.2.1.1、是什么&#xff1f; …

深入探索爬虫与自动化脚本:释放效率的利器

在当今信息爆炸的时代&#xff0c;高效获取和处理数据已成为核心竞争力。爬虫与自动化脚本正是解决这一痛点的关键技术——它们如同数字世界的勤劳助手&#xff0c;帮我们自动完成繁琐重复的任务。下面我们来系统了解这两项技术的核心要点、应用场景和最佳实践。一、爬虫与自动…

React函数组件的“生活管家“——useEffect Hook详解

&#x1f3af; React函数组件的"生活管家"——useEffect Hook详解 1. &#x1f31f; 开篇&#xff1a;从生活中的"副作用"说起 嘿&#xff0c;各位掘友们&#xff01;今天咱们来聊聊React函数组件里的一个“大管家”——useEffect Hook。你可能会问&#x…

python基础:request请求Cookie保持登录状态、重定向与历史请求、SSL证书校验、超时和重试失败、自动生成request请求代码和案例实践

Cookie保持登录状态cookie session鉴权机制 cookie是由web服务器保存在用户浏览器&#xff08;客户端&#xff09;上的小文本文件&#xff0c;他可以包含有关用户的信息。无论何时用户访问到服务器&#xff0c;都会带上该服务器的cookie信息&#xff0c;一般cookie都是有有效期…

Vulkan入门教程 | 第二部分:创建实例

前言&#xff1a;本教程为笔者依据教程https://docs.vulkan.net.cn/spec/latest/index.html#_about进行Vulkan学习并结合自己的理解整理的笔记&#xff0c;供大家学习和参考。 &#xff08;注意&#xff1a;代码仅为片段&#xff0c;非完整程序&#xff09; 学习前提&#xff1…

PHP云原生架构:容器化、Kubernetes与Serverless实践

引言 随着云计算的普及,PHP应用也在向云原生架构演进。本文将深入探讨PHP在云原生环境中的最佳实践,包括容器化部署、Kubernetes编排、Serverless架构以及云原生监控与日志方案,帮助开发者构建现代化、可扩展的PHP应用。 容器化PHP应用 基础Dockerfile优化 # 多阶段构建…

【华为机试】5. 最长回文子串

文章目录5. 最长回文子串描述示例 1示例 2示例 3示例 4提示解题思路方法一&#xff1a;中心扩展法&#xff08;推荐&#xff09;方法二&#xff1a;动态规划方法三&#xff1a;Manacher算法方法四&#xff1a;暴力解法代码实现复杂度分析测试用例完整题解代码5. 最长回文子串 …

【图像处理基石】如何对遥感图像进行实例分割?

遥感图像实例分割是指在遥感影像中&#xff0c;不仅要识别出不同类别的目标&#xff08;如建筑物、车辆、道路等&#xff09;&#xff0c;还要区分同一类别中的不同个体&#xff08;如建筑物1、建筑物2&#xff09;&#xff0c;并为每个实例生成精确的像素级掩码。 一、遥感图…

电子电气架构 --- 软件bug的管理模式

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…