C语言与操作符相关的经典例题

目录

一道变态的面试题:不能创建临时变量(第三个变量),实现两个数的交换。

编写代码实现:求一个整数存储在内存中的二进制中1的个数。  

 二进制位置0或者置1


如果以下的知识点不是很清楚的可以去看这篇文章:操作符详解(上)-CSDN博客

一道变态的面试题:不能创建临时变量(第三个变量),实现两个数的交换。

这个题如果没有那个限制条件,我们一般都是创建第三个变量来处理。

法一:

//创建临时变量
#include <stdio.h>
int main()
{int a = 0;int b = 0;printf("请输入交换前的变量a与b:");scanf("%d%d", &a, &b);int c = 0;c = a;a = b;b = c;printf("交换后a=%d,b=%d\n", a, b);return 0;
}

第二种方法可能也是比较容易想到的,通过计算和来减去对应的。

法二:


//加减法
#include <stdio.h>
int main()
{int a = 0;int b = 0;printf("请输入交换前的变量a与b:");scanf("%d%d", &a, &b);a = a + b;b = a - b;//a+b-ba = a - b;//a+b-aprintf("交换后a=%d,b=%d\n", a, b);return 0;
}

这个法二其实严格来说,是有错误的。当a和b的值接近一个整形能存储的最大值是,它们两的和就会超出这个整形的最大值,从而导致溢出的问题。 

第三种方法应该只有那些大佬才能够想到。 

 法三:

#include <stdio.h>
int main()
{int a = 0;int b = 0;printf("请输入交换前的变量a与b:");scanf("%d%d", &a, &b);a = a ^ b;b = a ^ b;//a^b^b=aa = a ^ b;//a^b^a=bprintf("交换后a=%d,b=%d\n", a, b);return 0;
}

这个方法涉及了一个知识点:0^a=a,a^a=0。

这个也用画图来解释一下吧: 

编写代码实现:求一个整数存储在内存中的二进制中1的个数。  

如果拿到这个题目的时候没思路的话,就可以先想一想十进制,求一个十进制数中1的个数,那么这个也就比较简单了,我们可以先%10,看看最后一位是否等于1,再/10赋给这个数更新一下,再%10拿到倒数第二位看看是否等于1,就这样一直%10,/10,知道最后这个/10的商为0,就可以停止了。同理,这个二进制我们也可以通过%2,/2的方法来计算。

#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int count = 0;while (n){if (n % 2 == 1){count++;}n /= 2;}printf("%d\n", count);return 0;
}

但是很遗憾的是这个代码只能求正整数,而对于负整数就不行了。

例如:当我们输入-1时,输出的却是0。我们知道-1的补码全是1,正确输出的话应该要是32。

代码演示:

其实这个问题还是比较好解决的,既然负数不行,那我们就把它变成无符号数,而-1的补码是32个1,那么对应的无符号数就是一个非常大的数字了。

#include <stdio.h>
int main()
{unsigned int n = 0;scanf("%d", &n);int count = 0;while (n){if (n % 2 == 1){count++;}n /= 2;}printf("%d\n", count);return 0;
}

但是如果题目要求我们用的是有符号整数,那么我们应该怎么办呢? 其实这里就可以用到那个按位与(&)操作符。这里我们就按照那个思路来想一想,当给出了一个二进制数字,我们按位与(&)上一个1,那么我们就只要看第32个比特位了(因为两个数按位与(&)的规则是对应的二进制位同为1,才是1,否则为0。而1的二进制补码,只有第32个比特位才是1,其余的都是0,那么无论什么数按位与(&)1,最终的结果是前面的第31个都是0了,只有第32个比特位还不确定。),如果那个数第32个比特位为1,那么最终的结果就是1,如果那个数第32个比特位是0,那么最终的结果就是0了。这是第32位的计算结果,如果要想知道前面的结果,就只能通过移位符来来把前面的比特位移至最后一位,再来比较。这里可能有小伙伴会有疑问,为什么不移1呢?把1一位移位的移去前面来比较。其实这个移1,也不是不可以但是比起移那个数,还是要难一些。我们移1之后就表示判断结果等于1了,而是等不等于0,如果等于0,那么就没有1,如果不等于0,那么就有1。原因我就用图来表述了:

以上就是全部的思路,接下来就用代码演示:

移输入数的位

#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int count = 0;int i = 0;for (i = 1; i <= 32; i++){if (n & 1 == 1){count++;}n >>= 1;//注意这里千万不能是移i位,因为i的数字是不断增加的,而不是定值。}printf("%d\n", count);return 0;
}
#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int count = 0;int i = 0;for (i = 0; i < 32; i++){if ((n >> i) & 1 == 1){count++;}}printf("%d\n", count);return 0;
}

 上面这两种写法都是可以的。

移 1 的位 

#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int count = 0;int i = 0;for (i = 0; i < 32; i++){if ((n & (1 << i)) != 0){count++;}}printf("%d\n", count);return 0;
}

上面这个题目其实还能优化(属于大佬能想到的)

我就先把代码演示一下:

#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int count = 0;while (n){n = n & (n - 1);count++;}printf("%d\n", count);return 0;
}

这个代码最难理解的就是那个 n = n & (n-1)。这个表达式可以把从右往左把最左边的1给去掉。

画图演示: 

这个代码其实算法的体现是比较明显了 ,一般不容易想到。

 二进制位置0或者置1

 编写代码将n的二进制序列的第5位(从右往左的第5位)(假设第5位是0)修改为1,然后再改回0。

这个题目应该是相较前面的难度要少一点。其实我们只要在第5位异或(^)一个1,就可以了。利用异或的规则:相异为1。至于这个第5位的1是怎么来实现呢?我们只需要讲1向移4位就够了。第二部,就在第5位按位异或(^)上一个1,就可以了。因为我们前面改了第5位的数变成了1,异或相同为0。

代码实现:

#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);n ^= (1 << 4);printf("%d\n", n);n ^= (1 << 4);printf("%d\n", n);return 0;
}

代码演示: 

我们上面就举了个最简单的例子0,任何一位都没有1,第5位改了之后就变成了2的4次方,等于16,第二次我们又改回来了,变成了0。

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

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

相关文章

【机器学习】一文读懂统计学与机器学习的区别。

统计学与机器学习的区别 1、机器学习2、统计学3、统计学与机器学习异同性3.1 差异性3.2 相似性 4、总结 1、机器学习 关于机器学习&#xff0c;我想大家都很熟悉&#xff0c;这里我再简单唠叨一些 机器学习是人工智能的一个子领域&#xff0c;主要关注如何通过算法使计算机系统…

喝酒筛子小游戏集合源码微信小程序喝酒骰子程序带流量主版本源码酒桌玩筛子源码

2023新版酒桌小游戏喝酒小程序源码-&#xff08;流量主版本&#xff09; 修改增加了广告位 根据文档直接替换&#xff0c;原版本没有广告位 直接上传源码到开发者端即可 通过后改广告代码&#xff0c;然后关闭广告展示提交&#xff0c;通过后打开即可 无广告引流 流量主版…

LeetCode---122双周赛

题目列表 3010. 将数组分成最小总代价的子数组 I 3011. 判断一个数组是否可以变为有序 3012. 通过操作使数组长度最小 3013. 将数组分成最小总代价的子数组 II 一、将数组分成最小总代价的子数组I 这道题纯纯阅读理解题&#xff0c;关键在于理解题意。注意&#xff1a;第一…

数据结构-顺序表的实现 [王道]

本博客记录个人寒假学习内容。此篇博客内容为 顺序表的定义。 博客中截图来自王道数据结构公开课 目录 顺序表的定义 顺序表的特点 顺序表的实现--静态分配 顺序表的实现--动态分配 顺序表的定义--知识结构框架 顺序表的定义 >线性表是具有相同(每个数据元素所占的空间…

C#读取一个百万条数据的文件,同时批量一次性导入sqlitedb,需要花费多长时间

读取的代码&#xff1a; public void CSV2DataTableTest(string fileName){FileStream fs new FileStream(fileName, FileMode.Open, FileAccess.Read);StreamReader sr new StreamReader(fs, new UnicodeEncoding());//记录每次读取的一行记录string strLine "";…

大创项目推荐 题目:基于卷积神经网络的手写字符识别 - 深度学习

文章目录 0 前言1 简介2 LeNet-5 模型的介绍2.1 结构解析2.2 C1层2.3 S2层S2层和C3层连接 2.4 F6与C5层 3 写数字识别算法模型的构建3.1 输入层设计3.2 激活函数的选取3.3 卷积层设计3.4 降采样层3.5 输出层设计 4 网络模型的总体结构5 部分实现代码6 在线手写识别7 最后 0 前言…

Java基于 SpringBoot+Vue 的高校心理教育辅导系统的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

后端学习:数据库MySQL学习

数据库简介 数据库&#xff1a;英文为 DataBase&#xff0c;简称DB&#xff0c;它是存储和管理数据的仓库。   接下来&#xff0c;我们来学习Mysql的数据模型&#xff0c;数据库是如何来存储和管理数据的。在介绍 Mysql的数据模型之前&#xff0c;需要先了解一个概念&#xf…

线性代数----------学习记录

线性代数发展历程 &#xff08;1&#xff09;线性方程组&#xff1a;例如二元一次方程组&#xff1b; &#xff08;2&#xff09;行列式&#xff1a;determinant,克莱默&#xff0c;莱布尼兹&#xff1b; &#xff08;3&#xff09;矩阵&#xff1a;方程个数与未知数的个数可…

CMake简明教程 笔记

推荐B站视频&#xff1a;1.1 Cmake构建项目的流程_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1xa4y1R7vT?p1&vd_sourcea934d7fc6f47698a29dac90a922ba5a3 >>目录 1&#xff09;CMake初体验 CMake构建流程Windows下使用CMake构建项目Linux下使用CMake构…

Django实战

一、开发登录表单 def login_form(request):html = <html><body><form method="post">用户名:<input name = "username" type="text"></input></br>密码:<input name = "password" type = &q…

蓝牙----蓝牙GAP层

蓝牙协议栈----GAP GAP的角色连接过程连接参数 GAP&#xff1a;通用访问配置协议层 gap的角色发现的模式与过程连接模式与过程安全模式与过程 CC2640R2F的GAP层抽象 GAP的角色 Broadcaster 广播电台 -不可连接的广播者。Observer 观察者 -扫描广播者但无法启动连接。Periphe…