葵花宝典之C语言冷知识(一)

news2024/9/20 20:49:51
实用小课堂开课啦!

鸟类天堂:

   🦢一:函数类型的对应

     🦜代码呈现:

    🦢二:浮点数运算

    🦢三:scanf的使用

   🦩 NUM 1:遇见空格,回车符,制表符,结束。

   🦩 NUM 2:达到域宽结束

   🦩 NUM 3:输入非法字符结束

    🦩 NUM 4:结束之后的回车会存储在缓冲区

    🦜代码呈现:

    🦢四:异或操作符的妙用

    🐦 NUM 1:找单身狗问题

    🦜代码呈现:

     🐦 NUM 2:寻找缺失的数字

      🦜代码呈现:

 🦢五:“字符串”部分移动

    🐦倒序字符串

    🦚简易方法一

    🦜代码呈现 :

    🦚简易方法二

    🦜代码呈现 :

   🐦旋转数组:

     🦜代码呈现 :

    🌻欢迎各位伙伴们来到我们以C语言为专题的冷知识课堂,每系列的博客当中都会抽取五个最易错的冷知识和大家分享,快去看看吧! 

   🦢一:函数类型的对应

    🐌(1)在编写代码的时候一定要注意函数的返回类型是否和自己标明的一致,函数并不会检查所有类型不匹配的问题,如整形和浮点型不匹配只会报一个警告,极容易被忽略。之前我定义过一个函数,我定义函数的返回类型应该是int但是却将一个浮点数直接返回了,使得1.78-1.23的时候虽然结果是0.55,但是经过强制类型转换float->int之后就变成了0。导致程序运行出现错误。

    🐌我们需要将函数的类型改为浮点型值后才可以正确计算。 

    🐌如上图的运行结果所示。

     🦜代码呈现:

//#include<stdio.h>
//
减法函数
//int sub(double a, double b)
//{
//	return a - b;
//}
//
//int main()
//{
//	double a = 0.0, b = 0.0;
//	scanf("%lf %lf", &a, &b);
//	double ret=sub(a,b);
//	printf("%.2lf", ret);
//	return 0;
//}

#include<stdio.h>

//减法函数
double sub(double a, double b)
{
	return a - b;
}

int main()
{
	double a = 0.0, b = 0.0;
	scanf("%lf %lf", &a, &b);
	double ret = sub(a, b);
	printf("%.2lf", ret);
	return 0;
}

    🦢二:浮点数运算

    🐌(2)浮点数的比较只可以运用一定的范围进行比较,如果大家去查阅资料的话,官方的比较浮点数的方法肯定都是范围比较。范围比较的含义也就是:想要判断两个浮点数谁大谁小,那么就需要把这两个浮点数相减去和自定义的 “0” 进行比较,也就是我们需要将两数之差和1e-7进行比较(1e-7在浮点数的精确度上等于0)。官方的解释是:浮点数并非真正意义上的数字,只是其在某种范围内的近似。因此也就只能用近似的方法将实数与0进行比较。 这个在超过七位小数运算与0比较上值得大家注意。(7位之后是随机数不一定为0),我们可以利用一个实例来理解这部分的知识。

就像是 上图中我们看到的结果一样,并不是所有的浮点数在内存中储存的都是我们输入的准确值,那么我们上面的浮点数需要进行范围比较的说法就容易理解得多了。浮点数在内存中的存储请参考:http://t.csdn.cn/7MFlV

    🦢三:scanf的使用

    🐌(3)关于 scanf 值得我们注意的是 scanf 的读取结束判定条件,以及结束后的注意事项。

   🦩 NUM 1:遇见空格,回车符,制表符,结束。

    🐌也就是说当你需要输入一个字符串的时候,如果字符串中存在空格,制表符,(可以产生四个空格),回车,对于 scanf 可能无法正常读取,遇到这三种符号会自动判定第一次输入结束。通常我们可以利用 gets 进行替代 scanf 对存在空格等特殊符号的字符串进行输入。

   🦩 NUM 2:达到域宽结束

    🐌虽然很少,但是我们刷题的时候也会看到输入的数字等数据是一行输入且没有空格等分割标志,那么我们就需要限定域宽对输入的两个或多个数据进行限定。如:我想输入12和34,但是输入的却是1234这时候我们就需要将我们 scanf 中的内容改为 sacnf("%2d%2d",&a,&b); 这样我们的scanf 进行数据读取的时候就会读到两位之后自动判定输入为下一个数字。

   🦩 NUM 3:输入非法字符结束

    🐌当我们使用 sacnf 的时候我们一般都会有特定要求的输入格式,比如:输入一个整型就是 %d,那么我们在键盘上输入的只能是连续的数字,否则也会异常结束。就像我们想要输入一个数字1234,但是我们再输入的时候却一不小心打错了,打成了12e4,这个时候我们输入的数字就变成了 12 。读到字符 e 的时候由于 e 不属于整形所以 scanf 判定输入结束。

    🦩 NUM 4:结束之后的回车会存储在缓冲区

    🐌当我们输入数据结束的时候一般都会输入回车来告诉程序,我已经输入完毕了,你可以开始运行了。但是我们需要特别注意的是,这个回车仅仅是告诉程序开始执行后就消失了吗?不,它会停留在缓冲区中。等待下一次被唤醒,就一个简单的例子:当我们需要分两次输入的时候第一次输入一个整数,第二次输入一个字符,那么我们必须对这个回车符进行处理了。我们用一个程序来证明。

    🐌我们可以看出的程序似乎出现了异常,第一次输入一个整型 45 之后原本应该再一次进行输入一个字符的,但是系统却异常结束了,中间还空了一行。这就验证了我们上面所说的,我们在输入第一个整形的时候残留下的一个回车并没有消失,下次读取一个字符并打印的时候会先读取回车。(但是不要担心,假如你想输入的第二个数据不是字符的话,那么不用考虑这个回车符,因为scanf 会自动匹配到第一个符合的数据进行输出。) 如果出现这种情况的话,可以利用 getchar 函数进行读取一个字符,我们将缓冲区的回车拿走之后就不会出现这种情况了。如下图。

    🦜代码呈现:

//scanf不会删除输入的回车符证明:
//#include<stdio.h>
//int main()
//{
//	int n = 0;
//	char ch = 0;
//
//	scanf("%d", &n);
//	printf("%d", n);
//
//	scanf("%c", &ch);
//	printf("%c", ch);
//
//	return 0;
//}

//解决办法:
#include<stdio.h>
int main()
{
	int n = 0;
	char ch = 0;
	scanf("%d", &n);
	printf("%d\n", n);
	getchar();            //拿走回车
	scanf("%c", &ch);
	printf("%c", ch);
	return 0;
}

    🦢四:异或操作符的妙用

    🐌在刷题的过程中你经常会被一些很奇特的思想所震惊到,异或操作符就是其中之一。所谓的异或就是将两个存储在内存中的数据按位进行操作。两个数据依次对其,每一位上的数字相等就为0,不相等就为1。例如:

    🐌但是你看到这里肯定一头雾水:这有什么用呀?别着急,这需要涉及异或操作符的一个特性,连续操作同一个数字时还会变成原来的数。

     🐌那么接下来的内容就有趣了,我们可以利用异或操作符的这个性质做许多事,比如说加密,找到数组中的重复的数字,找落单的数字,对 1—N 无序数列找出缺失的数字等等。我们通过几道题目来体会一下其中的奥秘。

    🐦 NUM 1:找单身狗问题

    🐌这个题目的要求是这样的:有一个数组中的数字总是成对存在,但是有一个数字却只有一个,那么请找出这个数字。要是我们不适用异或的方法会怎么求解呢?循环嵌套之后一个一个匹配?这不免效率太慢了,但是我们要是使用异或操作符进行求解的话只需要进行一遍。就可以得到想要的答案。

    🐌我们经过尝试可以发现0无论异或任何数字得到的结果都会是这个数字,那么我们就可以利用这个性质对数组进行操作。是不是一下子变得很简单?

    

    🦜代码呈现:

    🐌那么我们的问题是不是得到了解决?简单了不少吧?别着急精彩的还在后面!

     🐦 NUM 2:寻找缺失的数字

    🐌这道题的题目要求是这样的:从 1—N一共N个数字乱序存储在一个数组中,但是存储的时候不小心漏掉了一个数字,请找出漏掉的这个数字。看到这个题目的时候别着急取用循环嵌套,看咱们的大标题!异或操作符呀!但是你可能会说这里没有的数字呀?没有枪没有炮我们自己造!我们可以先使用0进行从1—N进行第一遍异或,之后将之后的结果再和数组中的数字异或,这么一来不是又出现落单的数字了吗?我们按照这个思路来执行我们的操作。

    🐌这么一简化,是不是程序变得更加简洁了?编写思路也更加清晰了呢?那么下一次再遇到对数组中的数字进行修改的问题记得优先考虑异或哦!

      🦜代码呈现:

#include<stdio.h>
int main()
{
	//N为20    缺失的数字是 14
	int arr[20] = { 3,2,5,4,7,9,8,1,6,10,13,16,12,15,18,19,17,20,11 };
	int n = 20, i = 0, res = 0;
	for (i = 1; i <= n; i++)
	{
		res ^= i;
		res ^= arr[i-1];
	}
	printf("%d", res);
	return 0;
}

 🦢五:“字符串”部分移动

    🐦倒序字符串

    🐌还记得我们之前说到的我第一次oj考试吗?上面有一道字符串逆序的题目,我当时傻傻的使用 getchar 进行一个字符串一个字符串的读取,导致那道题我到最后时间到了也没有写完,现在想想真的好傻,那我们就利用这道题来给大家讲讲一个更加简单的思想:“字符串”的部分逆序。题目如下:

    🐌拿到这道题的时候是不是觉得思路很简单,但是好复杂?先创建三个数组?将三个单词分别装起来?NO,NO,NO,题目中可没说每次测验只对三个单词进行位置转换。怎么样?一下子被难住了?那么我们接下来看一种奇特的思想:

    🦚简易方法一

   🐌对于这种部分前置的题目我们可以先对部分进行逆序操作,在对整体进行逆序操作。示例如下:

   🐌是不是很神奇?我第一次也是这么觉得的,难以置信!这是怎么想出来的!没办法总有一些大佬能想到好的方法,我们只需要对这种方法进行学习即可。那么在遇到对部分进行不调换顺序前置的情况我们就可以利用这种方式进行操作。记住先部分逆序,再整体逆序。下面我们将上面的思想转化为代码的形式:

    🦜代码呈现 :

#include<stdio.h>
#include<string.h>
int main()
{
	char ch[100] = { 0 };
	gets(ch);            //像静态区中输入字符串包括空格
	int i = 0, left = 0, right = 0;
	char tmp = 0;
	int len = strlen(ch);
	//对部分进行逆序
	for (i = 0; i < len; i++)
	{
		if ((ch[i] == ' ')||(i==(len-1)))
		{
			if (ch[i] == ' ')
			{
				right = i-1;
			}
			else
			{
				right = i;
			}
			//对下标为left到i-1的单词进行逆序
			for (; left<right;)
			{
				tmp = ch[left];
				ch[left] = ch[right];
				ch[right] = tmp;
				left++;
				right--;
			}
			left = i + 1;
			//ret:重置需要逆置单词的第一个字母
		}
	}
	//整体逆序
	left = 0;
	right = len - 1;
	for (;left<right;)
	{
		tmp = ch[left];
		ch[left] = ch[right];
		ch[right] = tmp;
		left++;
		right--;
	}
	printf(ch);
	return 0;
}

    🦚简易方法二

    🐌虽然上面的思路有了,但是是不是感觉还是有点复杂?我第一次编写这个代码的时候调试错误调试了好几个小时,总会忽略一些细节。那么觉得麻烦的话我再来给大家介绍一种方法:部分倒置的时候肯定得有一个标志吧?让字符串从后向前查找,找到这个标志对后面字符串中的内容直接打印。如下:

     🐌这样的话我们就可以将我们的第二次两次逆序操作都省去了,怎么样?这次够简单了吧?

    🐌运行效果和想象的一样。那么接下来就将代码呈现给大家:

    🦜代码呈现 :

#include <stdio.h>
#include <string.h>
int main()
{
    char a[1000];
    int len = 0, i = 0, j = 0;
    gets_s(a);
    len = strlen(a);
    for (i = len - 1; i >= 0; i--)
    {
        if (a[i] == ' ')
        {
            for (j = i + 1; a[j] != '\0' && a[j] != ' '; j++)
            {
                printf("%c", a[j]);
            }
            printf(" ");
        }
    }
    i = 0;
    while (a[i] != ' ')
    {
        i++;
    }
    for (j = 0; j < i; j++)
    {
        printf("%c", a[j]);
    }
    return 0;
}

   🐦旋转数组:

     🐌是不是感觉一道题做起来不过瘾?我们接着看一道类似的题目:旋转数组:给定一个数组arr[7]={1,2,3,4,5,6,7},旋转N次,求旋转之后的数组是什么样的。(旋转指的是将数组中的最后一个数字拿到第一个数字的位置上,其他数字向后移,例:旋转一次:7,1,2,3,4,5,6)你可能没发现这道题和我们前面讲的旋转数组有什么区别,但是仔细解析一下就会恍然大悟,把旋转的次数作为数组的个数,从后向前进行计数,然后直接打印。例如:

    🐌这么一来我们就可以用我们的老方法进行求解这道题了,简单又高效!只不过需要注意的是我们每旋转七次都是一个循环,数组会恢复到原本的样子,因此我们需要对输入的旋转的次数进行取余操作,防止运行出错。我们程序的编写效果如下:

     🦜代码呈现 :

#include<stdio.h>
int main()
{
	int arr[7] = { 1,2,3,4,5,6,7 };
	int n = 0, i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	printf("请输入旋转的次数:");
	scanf("%d", &n);
	n %= 7;
	for (i = 0; i < n; i++)
	{
		printf("%d ", arr[sz-n+i]);
	}
	for (i = 0; i < sz - n; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

   🐌那么本次介绍的五个使用小技巧也就到此为止了,感谢您的观看,祝您天天开心。

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

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

相关文章

(附源码)Springboot北京东奥会志愿者报名系统 毕业设计 150947

Springboot北京北京东奥会志愿者报名系统 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对北…

数据挖掘Java——KNN算法的实现

一、KNN算法的前置知识 k-近邻&#xff08;kNN, k-NearestNeighbor&#xff09;是在训练集中选取离输入的数据点最近的k个邻居&#xff0c;根据这个k个邻居中出现次数最多的类别&#xff08;最大表决规则&#xff09;&#xff0c;作为该数据点的类别。 分类在数据挖掘中是一项…

底层网络知识详解:陌生的数据中心-第18讲-DNS协议:网络世界的地址簿

前面我们讲了平时常见的看新闻、支付、直播、下载等场景,现在网站的数目非常多,常用的网站就有二三十个,如果全部用IP地址进行访问,恐怕很难记住。于是,就需要一个地址簿,根据名称,就可以查看具体的地址。 例如,我要去西湖边的“外婆家”,这就是名称,然后通过地址簿…

Linux运维巡检流程工作总结

文章目录一 执行脚本获取数据二 登陆巡检环境2.1 将数据放在特定目录下2.2 在网页浏览器输入 ip:端口号/linux三 生成报告3.1 点击执行按钮&#xff0c;等待报告3.2 点击生成html文档&#xff0c;等待四 编写巡检文档4.1 提取所有检查的服务器IP、主机名、操作系统4.2 提取某些…

js实现放大镜效果

在我们平时见到很多购物网站都会有放大镜效果的出现&#xff0c;当我们将鼠标放在一个商品图片的上面&#xff0c;就会在旁边出现对应的放大效果。 效果图 实现步骤 实现原理是非常简单的&#xff0c;实际上是两张图片&#xff0c;一张原图和一张更大尺寸的图片。一开始通过c…

如何mount到网络为NAT方式的虚拟机

VMware Workstation我们一般两种虚拟机上网方式&#xff0c;一种bridge,一种NAT。bridge可以获得公网地址需要指定静态IP&#xff0c;而NAT是动态分配的内网地址了。设置bridge方式时往往指定的IP为内网IP&#xff0c;则无法正常上网&#xff1b;而设置NAT方式时共享本地网络可…

计算机毕业设计 HTML+CSS+JavaScript食品餐饮行业网站(10页)

&#x1f4c2;文章目录一、&#x1f468;‍&#x1f393;网站题目二、✍️网站描述三、&#x1f4da;网站介绍四、&#x1f310;网站效果五、&#x1fa93; 代码实现&#x1f9f1;HTML结构代码&#x1f492;CSS样式代码六、&#x1f947; 如何让学习不再盲目七、&#x1f381;更…

【人脸识别】PCA人脸二维码识别(带面板)【含GUI Matlab源码 754期】

⛄一、人脸识别技术简介 0 引言 这个高速发展的时代&#xff0c;一切事物都将与“快”相联系。人脸识别技术的发展成熟保证了人们的信息安全&#xff0c;二维码的飞速发展成为了现如今信息传递的新媒介。“慢”就会被淘汰&#xff0c;因此减少现如今人脸识别过程的 时间仍是目…

数据结构和算法(四)--高级排序

目录 二、高级排序 2.1、希尔排序 2.2、归并排序 2.2.1、递归 2.2.2、归并排序 数据结构和算法(三)--排序 二、高级排序 冒泡排序&#xff0c;选择排序&#xff0c;插入排序&#xff0c;最坏的时间复杂度都是O(N^2)&#xff0c;而平方阶&#xff0c;随着输入规模的增大&…

想掌握日志分析系统的看过来

日志分析系统&#xff08;ELK&#xff09; 什么是ELK ELK是三个开源软件的缩写&#xff0c;分别表示&#xff1a;Elasticsearch , Logstash, Kibana , 它们都是开源软件。新增了一个FileBeat&#xff0c;它是一个轻量级的日志收集处理工具(Agent)&#xff0c;Filebeat占用资源…

day23【代码随想录】翻转二叉树、对称二叉树、完全二叉树的结点个数

文章目录前言一、翻转二叉树&#xff08;力扣226&#xff09;1、递归法1、使用前序遍历2、使用后序遍历2、迭代法1、层序遍历二、对称二叉树&#xff08;力扣101&#xff09;三、完全二叉树的结点个数&#xff08;力扣222&#xff09;前言 1、翻转二叉树 2、对称二叉树 3、完全…

【图像处理】直方图均衡化

直方图均衡化 简介 直方图均衡化(Histogram Equalization)是一种增强图像对比度(Image Contrast)的方法,其主要思想是将一副图像的直方图分布变成近似均匀分布,从而增强图像的对比度。 直方图均衡化是将原图像通过某种变换,得到一幅灰度直方图为均匀分布的新图像的方法。…

RegNet:设计网络设计空间

文章目录摘要1. 介绍2. 相关工作3.设计空间设计3.1. 设计空间设计的工具3.2. AnyNet设计空间3.3. RegNet设计空间3.4. 设计空间概化4. 分析RegNetX设计空间5. 与现有网络的比较5.1. 最先进的比较:移动体系5.2. 标准基线比较:ResNe(X)t5.3. 最先进的比较:整个体系6. 结论附录A:测…

Kafka 核心源码解读【四】--状态机模块

文章目录1 TopicDeletionManager&#xff1a; Topic是怎么被删除的&#xff1f;1.1 课前导读1.2 TopicDeletionManager 概览1.3 DeletionClient 接口及其实现1.4 TopicDeletionManager 定义及初始化1.5 TopicDeletionManager 重要方法1.6 总结2 ReplicaStateMachine&#xff1a…

EEGLAB系列教程5:数据预处理2(ICA去伪迹)

EEGLAB系列教程5&#xff1a;数据预处理2&#xff08;ICA去伪迹&#xff09; 今天介绍EEG数据处理系列教程5&#xff0c;在前面的几期中&#xff0c;已经介绍了数据基本处理过程&#xff0c;可以参见以下链接: EEGLAB系列教程1&#xff1a;安装和启动 EEGLAB EEGLAB系列教程…

Java项目:SSM网上零食超市商城

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;前台普通用户登录&#xff0c;后台管理员登录&#xff1b; 用户角色包含以下功能&#xff1a; 提交订单,支付页面…

Axios异步通信

四.Axios异步通信 1 什么是Axios&#xff1f; Axios是一个类库&#xff0c;基于Promise管理的HTTP 库&#xff0c;是前端通信框架&#xff0c;可以用在浏览器和 node.js 中。axios实现了对ajax的封装&#xff0c;常用于Ajax请求。注解&#xff1a;promise是Java Script的一个…

(附源码)Springboot校园健康检测管理系统 毕业设计 151047

Springboot校园健康检测管理系统的设计 摘 要 亚健康低龄化和高职业压力使高校师生健康问题凸显&#xff0c;不及早进行干预和控制将严重影响师生健康。如何理解和应用健康管理的理论和方法&#xff0c;探索高校师生健康管理工作模式&#xff0c;是目前高校医院的重点工作 校园…

Thymeleaf 预处理表达式__${表达式}__使用案例

目录一. 前期准备1.1 国际化项目获取类1.2 国际化配置文件类1.3 项目配置文件1.4 国际化资源文件二. __${表达式}__预处理表达式2.1 在Thymeleaf中使用Spring的Bean2.2 通过#{}获取国际化资源2.3 预处理表达式__${表达式}__的使用三. 效果四. 表格案例一. 前期准备 1.1 国际化…

图神经网络 # GNN基础(干货版)

注意&#xff1a;本篇文章不是系统性的图神经网络或者图深度学习的入门教程&#xff0c;而是介绍如何入门图神经网络的学习指南以及相关的干货笔记&#xff0c;文中会列出一些视频和文章学习资料&#xff0c;并在本文作一些重点的摘要&#xff0c;读者需要自行前往文本超链接的…