当前位置: 首页 > news >正文

编程之路,从0开始:补充篇

        Hello大家好!很高兴和大家又见面啦!给生活添点passion,开始今天的编程之路!

1702d5cef00940d18a9d6d4da33b31ba.gif

我的博客:<但凡.

我的专栏:《编程之路》、《题海拾贝》、《数据结构与算法之美》

欢迎点赞,关注!

        这篇文章拖了很久,甚至是在编程之路这个系列完结之后才发出来,主要是想把之前遇到的有意思的小问题一次性给大家说清楚,并做一些拓展。

目录

1、scanf和gets

1.1输入带有空格的字符串

1.2scanf的返回值

2、取模问题

2.1负数取模

2.2取模运算的应用

3、assert断言

4、进制转化

4.1其他进制转十进制

4.2十进制转其他进制

4.3、其他进制转其他进制

5、随机数生成技巧 

6、C/C++程序内存区域划分


1、scanf和gets

我们先尝试运行以下代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{char p[10] = "";scanf("%s",p);printf("%s", p);gets(p);printf("%s", p);return 0;
}

        我们输入asd fgh,输出asd fgh。

         之所以讨论一下scanf和gets,是因为他们有一定的区别。不知道大家在写代码的时候发现没有,用scanf输入字符串时如果字符串中有空格,他打印的时候不会打印空格及以后的内容。但gets是可以打印出有空格的字符串的。

        知道这个特点后,我们分析一下上面的代码。首先我们输入asd fgh,scanf只能接收到asd,剩下的空格和fgh以及我们输入的\n(回车)他都放入了缓冲区。然后执行gets时我们不用输入,gets直接从缓冲区读取这些内容,然后打印出来。

1.1输入带有空格的字符串

        我们可以用gets函数输入字符串:

#include<stdio.h>
int main()
{char p[100] = "";gets(p);printf("%s",p);return 0;
}

        那么我们如何让scanf也能输出含有空格的字符串呢?我们可以这样写:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{char p[100] = "";scanf("%[^\n]",p);printf("%s",p);return 0;
}

输出结果:

59c9c3681ed14904848719c8378269fd.png

        这样我们可以让scanf读取到\n之后再停止。另外如果在vs中使用scanf的话需要写上#define _CRT_SECURE_NO_WARNINGS (如上代码),不然的话需要写scanf_s。

        我们还可以使用fgets来输入字符串。但是要将文件指针换成stdin(标准输入流):

#include<stdio.h>
int main()
{char p[100] = "";fgets(p, 100, stdin);printf("%s",p);return 0;
}

输出结果:

05f4d4b8fe3c4738a89db3778c183b29.png

        此外,输入字符串的方式还可以使用getchar和循环一个一个的输入,只是这样麻烦一些。其实在c++中,我们还可以使用cin来输入字符串,而且在c++中我们更常使用string字符串。当然了很久以后我们还会分享c++的知识,这里只是简单提一下。

1.2scanf的返回值

在vs中使用scanf时经常会出现这个警告:

251435501d8c4a5fa5d5621074163734.png

我们去cplusplus上看一下scanf这个函数的原型:

57faa23f6fb644dc891193ec2218736a.png

        我们发现,其实scanf是有返回值的,而它的返回值就是输入数据的个数。当然了,我们在使用它的时候用到的概率不大。

2、取模问题

2.1负数取模

        不知道大家想过没有,一个负数取模结果是正数还是负数呢?

#include<stdio.h>
int main()
{int a = -10;printf("%d",a%3);return 0;
}

输出结果:

c7ff74f853cc47bd809a14ca5b72c06e.png

        很明显,负数取模结果是负数。那么问题又来了,如果我让10%(-3)呢?

输出结果:

fff1c6f822724bf398a3dc26d1bd9d17.png         经过我们实验可以知道,负数也是支持取模的,但是负数求模结果的正负号由第⼀个运算数(操作数)的正负号决定。

2.2取模运算的应用

我们可以写一个程序,判断一个数是奇数还是偶数:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{int a = 0;scanf("%d", &a);if (a % 2 == 1){printf("奇数\n");}elseprintf("偶数\n");return 0;
}

        这个程序对于正数判断奇数偶数没有问题,但是它不能判断负数是奇数还是偶数。

        这个时候我们就可以使用奇数二进制末尾都是1这个特性,进行&运算:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{int a = 0;scanf("%d", &a);if (a & 1 == 1){printf("奇数\n");}elseprintf("偶数\n");return 0;
}

        因为&运算是当这个二进制位都为1时,他才为1。那么我们让一个数&1不就能保证其他位都是0,我们只判断最后一个位是不是1了呢?

3、assert断言

        这个东西我之前用到过,但是忘了说。

  assert 是一个,用于在运行时检查一个条件是否为真,如果条件不满足,则运行时将终止程序的执行并输出一条错误信息。

在使用时,我们需要包含头文件:

#include<assert.h>

它常用于判断一个地址为不为空或一个数是不是0。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
int main()
{int* p = NULL;assert(p);return 0;
}

结果:

187a1c9344114a028e5bc40ae86801b0.png

4、进制转化

         常见的进制有二进制,八进制,十进制,十六进制...,那么这些进制之间如何转化呢?

4.1其他进制转十进制

·       其实我们数字的每一位都有自己的权重。比方说十进制123,就等一1*(10^2)+2*(10^1)+1*(10^0)。

我们可以利用这个方法将二进制转化为十进制:

比如101转化为十进制就是1*(2^2)+0*(2^1)+1*(2^0)=5。

        同样的道理我们也可以把八进制和十六进制转化为十进制。

        现在我们来写一个程序将x进制转化为十进制:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<math.h>//使用pow
int main()
{int x = 0;printf("请输入想要转化的数的进制:");scanf("%d", &x);if (x > 36){printf("输入错误\n");return 0;}char s[100] = "";//因为有可能含有大写字符,所以定义为char类型数组printf("请输入被转化数:");scanf("%s", &s);int len = strlen(s);int ret = 0;int j = 0;while(len--)//每次进入循环len自减1{if(s[len]<'9'){ret=ret+(s[len] - '0')* pow(x,j);//当操作数为数字时j++;}else{ret=ret+ (s[len] - 'A'+10) * pow(x, j);//当操作数为字母时j++;}}printf("%d", ret);return 0;
}

输出结果:

60315ee22e524c18a59be43182b5fe12.png

82b59ca3c4304c6bb7df6cfcd99fa254.png

        当大于十进制时,被转化的数中就会含有ABC这样的大写字母,所以我们在进行计算时要分情况讨论。另外当进制大于36时输入错误,因为最大就10加二十六个字母,也就是说最大进制就是36(除非他用其他的字符继续表示)。

        在c++中,我们可以对stoi函数进行改造,使他支持进制转换。当然这里只是拓展一下,想了解的朋友自行了解哈~

4.2十进制转其他进制

        我们这里那十进制转二进制举例:

a4eabd364c734214a623379439581995.png

注:画的很丑请见谅~

         其实就是让这个十进制数除以想要转化的进制,记录余数,然后再那除完的结果继续去除......但需要注意的是,这些余数我们需要从下往上写(对应上图)。

所以我们就可以用递归的思想实现这个代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
char s[38] = "012345678910ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void itox(int n,int x)
{if(n>=x){itox(n / x, x);//递归}printf("%c", s[n % x]);
}
int main()
{int n = 0;printf("请输入被转化数:");scanf("%d", &n);int x = 0;printf("请输入想要转化成的进制:");scanf("%d", &x);itox(n,x);return 0;
}

        还是由于可能会出现大写字母,所以我们定义一个全局的字符数组,存入一到九和A到Z。

以后我们就可以把这串代码当作一个模板,进制转化的时候直接套用就好了。

4.3、其他进制转其他进制

        这个我们就可以把上面的两个代码改造一下,自己输入两个进制数,先将数转化成十进制数,再将十进制数转化为其他进制数:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<math.h>//不要忘记
char s[38] = "012345678910ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int  ntoi(int n, char a[100])
{int len = strlen(a);int ret = 0;int j = 0;while (len--){if (a[len] < '9'){ret = ret + (a[len] - '0') * pow(n, j);j++;}else{ret = ret + (a[len] - 'A' + 10) * pow(n, j);j++;}}return ret;
}
void itox(int a,int x)
{if(a>=x){itox(a / x, x);//递归}printf("%c", s[a % x]);
}
int main()
{int n = 0;printf("请输入被转化数的进制:");scanf("%d", &n);char a[100] = "";printf("请输入被转化数:");scanf("%s",a);int x = 0;printf("请输入想要转化成的进制:");scanf("%d", &x);int ret=ntoi(n,a);//将a转化为十进制itox(ret,x);//将十进制的a转化为x进制return 0;
}

测试:

f9eb2408a1894d00b59a174d96a83440.png

2a2fa6edb4a242d5b7edafcf62e37ab6.png

5、随机数生成技巧 

        现在我们用C语言实现随机数:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>//使用srand
int main()
{srand((unsigned int)time(NULL));printf("%d", rand()%10);return 0;
}

        其实这个随机数理应是初学C语言时接触的,但是我给忘了哈哈,所以在这里再说一下,而且现在我们再看这个随机数生成操作其实是更好理解的。

首先先看srand:

ef0742f102f44f638024cbf3b65a73a8.png

        我们应该把种子传入这个函数,但是如果种子不变的话数也是不变的啊!那有没有什么东西是一直改变的呢?没错,就是时间戳。

        时间戳,是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数(不考虑闰秒),用于表示一个时间点。然而,这种格式对于人类阅读并不友好,因此需要转换成可读的日期和时间格式。 

        我们只需知道,时间戳是随着时间一直快速变化的,所以我们把它作为种子传入srand。又由于他的参数需要是unsigned int 类型的,所以我们强制转化一下。

        接着调用rand(),我们想他有一个范围,就%这个范围的最大值可以了,比如如上代码是生成0~9范围的随机数。我们写成rand()%10+1就是1~10范围的随机数。

6、C/C++程序内存区域划分

cf001efc9da64e3883a6cbe608ea3f61.png

        C/C++程序内存分配的几个区域:

        1. 栈区(stack):在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内 存容量有限。栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。 

        2. 堆区(heap):⼀般由程序员分配释放,若程序员不释放,程序结束时可能由OS(操作系统) 回收。分配⽅式类似于链表。

        3. 数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。

        4. 代码段:存放函数体(类成员函数和全局函数)的⼆进制代码。

好了,今天的内容就分享到这,我们下期再见!

相关文章:

编程之路,从0开始:补充篇

Hello大家好&#xff01;很高兴和大家又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《题海拾贝》、《数据结构与算法之美》 欢迎点赞&#xff0c;关注&#xff01; 这篇…...

使用缓存提升Web应用性能:从新手到高手的实践指南

引言 在现代Web开发中&#xff0c;性能优化是确保用户体验和系统稳定性的关键。使用缓存是提升网站性能的有效手段之一&#xff0c;可以显著减少数据库访问和计算开销。根据“网站优化第一定律”&#xff0c;缓存可以提升网站的响应速度&#xff0c;减少延迟&#xff0c;从而改…...

【数字电路与逻辑设计】实验一 序列检测器

文章总览&#xff1a;YuanDaiMa2048博客文章总览 【数字电路与逻辑设计】实验一 序列检测器 一、实验内容二、设计过程&#xff08;一&#xff09;作出状态图或状态表&#xff08;二&#xff09;状态化简&#xff08;三&#xff09;状态编码 三、源代码&#xff08;一&#xff…...

运动模糊效果

1、运动模糊效果 运动模糊效果&#xff0c;是一种用于 模拟真实世界中快速移动物体产生的模糊现象 的图像处理技术&#xff0c;当一个物体以较高速度移动时&#xff0c;由于人眼或摄像机的曝光时间过长&#xff0c;该物体会在图像中留下模糊的运动轨迹。这种效果游戏、动画、电…...

养老护理员培训考试题库;免费题库;大风车题库

下载链接&#xff1a;大风车题库-文件 大风车题库网站&#xff1a;大风车题库 大风车excel&#xff08;试题转excel&#xff09;&#xff1a;大风车excel...

Python-配置模块configparser使用指南

configparser 是 Python 标准库中的模块&#xff0c;用于处理配置文件&#xff08;如 .ini 文件&#xff09;。它适合管理程序的配置信息&#xff0c;比如数据库连接参数、应用程序设置等。 1. 配置文件的基本结构 配置文件通常是 .ini 格式&#xff0c;由 节&#xff08;Sec…...

C++的HDF5库将h5图像转为tif格式:szip压缩的图像也可转换

本文介绍基于C 语言的hdf5库与gdal库&#xff0c;将.h5格式的多波段HDF5图像批量转换为.tif格式的方法&#xff1b;其中&#xff0c;本方法支持对szip压缩的HDF5图像&#xff08;例如高分一号卫星遥感影像&#xff09;加以转换。 将HDF5图像批量转换为.tif格式&#xff0c;在部…...

【JAVA】Java第十三节:String类(String相关方法,以及StrinBuftrer , StringBulder相关方法)

本文详细介绍了String类以及常用的String相关方法&#xff0c;以及StrinBuftrer , StringBulder相关方法的使用&#xff0c;建议有印象即可&#xff0c;不需要都记住&#xff0c;使用时去查取即可 一、创建一个String类型的变量 我们平时创建String类型的变量一般是第一种形式…...

WordPress安装或访问时出现数据库连接错误的处理方式

一、在安装时出现数据库连接错误 1、如果数据库名称、用户名或密码错误&#xff0c;或者主机设置不正确&#xff08;如数据库服务器不是在本地localhost&#xff0c;而是在远程服务器&#xff0c;需要正确填写远程服务器的 IP 地址或域名&#xff09;&#xff0c;就会导致连接错…...

JAVA-面向对象基础

文章目录 概要封装多态抽象类接口内部类为什么需要内部类 概要 面向对象是一种编程范式或设计哲学&#xff0c;它将软件系统设计为由多个对象组成&#xff0c;这些对象通过特定的方式相互作用 封装 将数据和操作数据的方法封装在一个类中&#xff0c;并通过访问修饰符控制对…...

[Java]项目入门

这篇简单介绍一些入门的有关项目和行业的知识&#xff0c;并带着实现一个小项目。便于已经编程入门的各位准备进阶到下一个阶段。 先大致地介绍&#xff0c;一个完整的项目(不看客户端、服务端的分类)基本可以划分为三部分&#xff1a; 1.前端。比如你现在看到的CSDN页面就是一…...

opencv Mat To Heif

高效率图像文件格式&#xff08;英语&#xff1a;High Efficiency Image File Format, HEIF&#xff1b;也称高效图像文件格式&#xff09;是一个用于单张图像或图像序列的文件格式。它由运动图像专家组&#xff08;MPEG&#xff09;开发&#xff0c;并在MPEG-H Part 12&#x…...

二刷代码随想录第24天

93. 复原 IP 地址 确定函数is_ip的实现细节&#xff0c;start不能超过end&#xff0c;没有0开头的非0数字&#xff0c;每个字符都在0-9之间,每段字符小于255在原字符串s上做操作会更简单一些 class Solution { public:vector<string> result;vector<string> rest…...

Java设计模式之状态模式架构高扩展的订单状态管理

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s…...

Yagmail邮件发送库:如何用Python实现自动化邮件营销?

目录 一、Yagmail简介 二、安装Yagmail 三、基本使用示例 1. 发送简单文本邮件 2. 发送HTML邮件 3. 发送带有附件的邮件 4. 多收件人处理 5. 自定义邮件头 四、高级功能 1. SMTP配置 2. 邮件模板 3. OAuth2认证 五、自动化邮件营销案例 六、错误处理和调试 七、…...

李宏毅深度学习-Pytorch Tutorial2

什么是张量&#xff1f; 张量&#xff08;Tensor&#xff09;是深度学习和机器学习中一个非常基础且重要的概念。在数学上&#xff0c;张量可以被看作是向量和矩阵的泛化。简单来说&#xff0c;张量是一种多维数组&#xff0c;它可以表示标量&#xff08;0维&#xff09;、向量…...

SaaS财务软件:赋能企业数字化转型

在数字化浪潮的推动下&#xff0c;企业财务管理正逐步迈向智能化、高效化的新阶段。在这个过程中&#xff0c;SaaS财务软件应运而生&#xff0c;成为许多企业的首选。以易舟云财务软件为例&#xff0c;这款软件不仅集成了众多先进的财务管理功能&#xff0c;而且在用户体验上做…...

FPGA实战篇(按键控制LDE实验)

1.按键简介 按键开关是一种电子开关&#xff0c;属于电子元器件类。我们的开发板上有两种按键开关&#xff1a;第一种是本实验所使用的轻触式按键开关&#xff0c;简称轻触开关。使用时以向开关的操作方向施加压力使内部电路闭合接通&#xff0c;当撤销压力时开关断开&#xff…...

在Ubuntu-22.04 [WSL2]中配置Docker

文章目录 0. 进入Ubuntu-22.041. 更新系统软件包2. 安装Docker相关依赖包3. 添加Docker官方GPG密钥4. 添加Docker软件源5. 安装Docker Engine5.1 更新软件包列表5.2 安装Docker相关软件包 6. 验证Docker安装是否成功6.1 查看Docker版本信息6.2 启动Docker6.3 配置镜像加速器6.4…...

ACM:均分纸牌

主要思路 整体思路概述&#xff1a; 本题旨在解决给定N堆纸牌&#xff08;纸牌总数是N的倍数&#xff09;&#xff0c;通过按照特定移牌规则移动纸牌&#xff0c;找出用最少移动次数使每堆纸牌数量相等的方法。程序采用了一种逐步调整的思路&#xff0c;先计算出每堆纸牌应有的…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...