C语言学习笔记:16_位运算

/*
 * 16_位运算.c
 *
 *  Created on: 2015年7月6日
 *      Author: zhong
 */
#include <stdio.h>
#include <stdlib.h>

/* 位运算:
 * 所谓的位运算是指以二进制位为对象的运算。
 * c语言中位运算符有:
 *  & 按位与
 *  | 按位或
 *  ^ 按位异或
 *  ~ 按位取反
 *  << 左移
 *  >> 右移
 *
 *	除了 ~ 按位取反运算符以外,均为二目运算符。 两边的运算对象只能是整型或者字符 型数据
 *----------------------------------------------------------------------------------------
 * 一:& 按位与 : 两个相应的二进制位都为1,则这位的结果值为1,否则为0; 0&0=0, 0&1=0; 1&0=0, 1&1=1
 *	例:
 *		00000111 (7)
 *	&	00000101 (5)
 *	——————————————————
 *		00000101 (5)
 *	因此:7&5=5。如果参加&运算的是负数,则以袚形式表示 为二进制数,然后按位进行‘与’操作
 *	注意: &&与&的区别, &&是逻辑与运算符,7&&5值为1,因为非0数为真,真真得真=1;
 *
 *	按位与‘&’的用途:
 *	 1:将一个数‘清零’
 *		只要找一个二进制数,原来的数中为1的位,新数中相应的位为0进行&运算,即可达到清零目的。
 *		任何数与0 按位与操作,者为0; 因为两个二进制位,只要有一个是0,其为0;
 *	 2:取一个数中某些指定位:
 *	 		如:  取300四个字节中的最低一个字节
 *	 		00000000 00000000 00000001 00101100 (300)
 *	 		00000000 00000000 00000000 11111111 (255)
 *	 		————————————————————————————————————————————————————————
 *			00000000 00000000 00000000 00101100  (44)
 *------------------------------------------------------------------------------------------
 * 二:| 按位或 : 两个相应的二进制位只要一个为1,则这位的结果值为1;只有两个为0时,才为0; 0&0=0, 0&1=1; 1&0=1, 1&1=1
 *		00000111 (7)
 *	|	00000101 (5)
 *	——————————————————
 *		00000111 (7)
 *--------------------------------------------------------------------------------------------
 * 三: '^' 异或运算符: 参加运算的两个 二进制位异号,则两位相同时为假(0),不同是为真(1)  即  0^0=0; 0^1=1, 1^0=1, 1^1=0
 *		  异或的意思是判断两个相应 的位值是否0 ‘异’,为‘异’就取真(1),否则为假(0)
 *		00000111 (7)
 *	^	00000101 (5)
 *	——————————————————
 *		00000010 (2)
 *	应用 :
 * 1、将二进制各位'取反'
 *		00111010
 *	^	11111111
 *	————————————————
 *	    11000101
 * 2、与0相^,保留原直
 *
 * 3、交换两个值,不用临时变量
 *   a=a^b; b=b^a; a=a^b; 这样就可以交换两个变量的值了
 *		a=7,b=5;
 *		00000111 (7)
 *	^	00000101 (5)
 *	——————————————————
 *		00000010 (2)  a=a^b=2
 *	^	00000101 (5)
 *	——————————————————
 *		00000111 (7)  b=a^b=7;(和b=b^a意思一样的)
 *	^	00000010 (2)
 *  ——————————————————
 *  	00000101 (5)  a=b^a=5;(和a=a^b意思是一样的)
 * 4、一个数和自己异或,结果为0
 * 5、两个数异或顺序可以互换的,结果一样。 如9^5^9= 9^9^5 =0^5 =5;
 *
 *----------------------------------------------------------------------------------------
 * 四:~ 是一个单目运算符,用来对一个二进制数按位取反,即0变1,1变0
 * 	~	00000111 (7)
 * 	——————————————————
 * 		11111000 (248)  ~7=248
 *
 *----------------------------------------------------------------------------------------
 * 五:左移运算:<< 用来将一个数的各二进制位全部左移若干位,高位左移溢出时,舍去。右边补0
 * 例如  a=15  将a左移2位 a=a<<2  =60;
 *
 *   <<2    00 00 11 11  (15)
 * 	———————————————————————
 *     (00) 00 11 11(00) (60)
 *     溢出舍去                        右补0
 *
 *   左移运算的特点: 一个数左移1位相当于这个数乘以2,左移2位相当于这个数乘以2^2=4。(前提条件是,高位溢出的位不能是1,只能是0)
 *   			左移比乘法运算快,所以编译程序自动将乘2的运算左移一位为实现,将乘以2^n为左移n位。
 *
 *	面试题:用最有效率的方法算出2乘以8等於几
 *			2<<3; 相当于2*2^3=2*8
 *
 *----------------------------------------------------------------------------------------
 * 六:右移运算 >>表示将二进制位右移n位,移到右端的低位被舍弃,对无符号数,高位补0。
 *   例如:a=017; a=a>>2;
 *  >>2 	00 00 11 11                (17)
 *  ———————————————————
 *  	  (00) 00 00 11 (11) (3)
 *  	      左补0           此2位舍弃
 *	右移运算的特点: 和左移刚好相反啦。一个数右移1位相当于这个数除以2,右移n位相当于除以2^n次方法。
 *	在右移时,要注意符号位的问题。对无符号数,右移左边高位补0;对于有符号数据,如果原来符号位为0(正数),则左边补0。
 *						如果符号位原来为1(负数) ,则左移补0还是1,要取决于所用的计算机系统。有的补0,有的补1。
 *							补0的称为"逻辑右移"不考虑符号问题。补1的称为"算术右移"保持原来符号
 *----------------------------------------------------------------------------------------
 *七:位运算赋值运算符:即位运算与赋值运算符组合 :&= ;|= ;>>= ;<<=  ;^=
 *
 *	作用和 *= ,+=是一样的。 比如 a&=b,相当于a=a&b;
 *
 *
 *若两个不同长度的数据进行位运算,系统会将二者按右端对齐,右侧补0;
 *
 *----------------------------------------------------------------------------------------
 */
//位运算 & ‘与’
void bit_arith_and() {
	int a = 7, b = 5;
	printf("7&5=%d\n", a & b); //output:5
	a = 300, b = 255;
	printf("300&255=%d\n", a & b); //output:44
}
//位运算 | ‘或’
void bit_arith_or() {
	int a = 7, b = 5;
	printf("7|5=%d\n", a | b); //output:7
	a = 300, b = 255;
	printf("300|255=%d\n", a | b); //output:511
}
//位运算 ^ ‘异或’
void bit_arith_and_or() {
	int a = 7, b = 5;
	printf("7^5=%d\n", a ^ b); //output:2
}
//4:使用^(异或)算法,交换两个变量的值
void use_or_swap_number() {
	int a = 10, b = 11;
	a = a ^ b; //1
	b = b ^ a; //11-1=10
//	b=a^b; //和上面哪句一样的
	a = a ^ b; // 1+10=11
	printf("使用^(异或)算法交换两个数:a=%d,b=%d\n", a, b);
}
//左移
void left_shift() {
	printf("%d", 2 << 2); //2*2^2=8
}
//右移
void right_shift() {
	printf("%d", 8 >> 2); //8/2^2=2;
}

//用按位与&判断一个数是奇数还是偶数
void exercise_1() {
	/**
	 *奇数与偶数的特征:
	 * 1111 (15)
	 * 1001 (9)
	 *
	 * 1110 (14)
	 * 1010 (10)
	 *
	 * 根据上面可发现:右数的最后一位都是1,偶数最后一位都是0;
	 * 解题思路: 只要用这个数&1 就可以取出 最后一位,如果是1,就是奇数。是0就是偶数
	 * 1111
	 * 0001 (&1)
	 * ————
	 * 0001 这样就取出了最后一位
	 *
	 */

	int a = 15;
	int b = 20;
	a & 1 == 1 ? printf("%d是奇数\n", a) : printf("%d是偶数\n", a); //使用三目运算符
	b & 1 == 1 ? printf("%d是奇数\n", b) : printf("%d是偶数\n", b); //使用三目运算符

}

//用位运算输出一个十进制数的二进制形式
void printf_bin(int number) {
//	int count = sizeof(number)*8-1; //获得这个数的位数
	int count = (sizeof(number)<<3)-1; //获得这个数的位数  左移n位相当于*2的n次方。   <<3==*8; 由于算术运算符优先级高于位运算符,所以 要加()

	while (count >= 0) {
		int n_ = number >> count & 1; //第一次左移31位&1取得这一位数。。。。。。
		printf("%d", n_);
		if (count % 4 == 0) { //四位空一格:0000 0000 0000 0000 0000 0000 0000 1111
			printf(" ");
		}
		count--;
	}
	printf("\n");
}

int main() {
//	bit_arith_and();
//	bit_arith_or();
//	bit_arith_and_or();
//	use_or_swap_number();
//	left_shift();
//	right_shift();
//	exercise_1();
	printf_bin(15); //output:0000 0000 0000 0000 0000 0000 0000 1111

	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-05 12:18:15

C语言学习笔记:16_位运算的相关文章

R语言学习笔记

參考:W.N. Venables, D.M. Smith and the R DCT: Introduction to R -- Notes on R: A Programming Environment for Data Analysis and Graphics,2003. http://bayes.math.montana.edu/Rweb/Rnotes/R.html 前言:关于R 在R的官方教程里是这么给R下注解的:一个数据分析和图形显示的程序设计环境(A system for data

go语言学习笔记

go语言学习笔记 go语言学习笔记(初级) 最近一直在学习go语言,因此打算学习的时候能够记录 一下笔记.我这个人之前是从来没有记录笔记的习惯, 一直以来都是靠强大的记忆力去把一些要点记住. 读书的时候因为一直都是有一个很安静和很专心的环境, 因此很多事情都能记得很清楚,思考的很透彻.但是随着 年纪不断增加,也算是经历了很多的事情,加上工作有时会让人 特别烦闷,很难把心好好静下来去学习,去思考大自然的终极 奥秘,因此需要记录一些东西,这些东西一方面可以作为一种自我激励 的机制,另一方面,也算是自

Go语言学习笔记(二) [变量、类型、关键字]

日期:2014年7月19日 1.Go 在语法上有着类 C 的感觉.如果你希望将两个(或更多)语句放在一行书写,它们 必须用分号分隔.一般情况下,你不需要分号. 2.Go 同其他语言不同的地方在于变量的类型在变量名的后面.例如:不是,int a,而是 a int.当定义了一个变量,它默认赋值为其类型的 null 值.这意味着,在 var a int后,a 的 值为 0.而 var s string,意味着 s 被赋值为零长度字符串,也就是 "". 3.Go语言的变量声明和赋值 在Go中使

TCP/IP详解学习笔记 这位仁兄写得太好了.(转载)

TCP/IP详解学习笔记   这位仁兄写得太好了 TCP/IP详解学习笔记   这位仁兄写得太好了. http://blog.csdn.net/goodboy1881/category/204448.aspx TCP/IP详解学习笔记(13)-TCP坚持定时器,TCP保活定时器 TCP/IP详解学习笔记(12)-TCP的超时与重传TCP/IP详解学习笔记(11)-TCP交互数据流,成块数据流 TCP/IP详解学习笔记(1)-基本概念 为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着

Perl语言学习笔记 day 2

1.在Perl中,子程序名与变量名属于不同的命名空间,可以使用同一个名字分别命名子程序和变量,但不建议这样使用. 2.子程序的定义是全局的,同名的子程序后边的会覆盖掉前边的定义. 3.定义子程序 sub subProgram{ #body } 4.调用子程序 &subProgram 5.所有的子程序都有返回值,默认最后一行的运算结果为返回值. 6.子程序未定义参数时,传递的参数默认传给"@_",可以通过$_[0].$_[1].....访问: 7.在子程序中创建私有变量 my($

Perl语言学习笔记 9 正则表达式处理文本

1.替换 s/PATTERN/REPLACE/; #返回是否替换成功的布尔值 可以使用捕获变量,如:s/(\w)/$1/ 匹配失败则不做任何处理 2.定界符 对于没有左右之分的定界符,重复三次即可,如:s///.s### 对于有左右之分的定界符,需使用两对,一对包含模式,一对包含替换字符串,这两对可以不一样,如:s{}{}.s[]{}.s<>[] 3.可选修饰符 /g可进行全局替换,替换所有匹配到的字符串,如:s/ / /g /s:使得 . 匹配所有字符 /i:大小写无关 4.绑定操作符 $f

Perl语言学习笔记 6 哈希

1.哈希的键是唯一的,值可以重复! 2.访问哈希元素 $hashname{"$key"};#哈希为大括号,数组为方括号,键为字符串 $family_name{"fred"} = "firstd";#给哈希元素赋值 3.哈希键支持任意表达式 $foo = "na"; $family_name{$foo."me"};#获取$family_name{"name"}对应的值 4.访问整个哈希 %

JavaScript--基于对象的脚本语言学习笔记(二)

第二部分:DOM编程 1.文档象模型(DOM)提供了访问结构化文档的一种方式,很多语言自己的DOM解析器. DOM解析器就是完成结构化文档和DOM树之间的转换关系. DOM解析器解析结构化文档:将磁盘上的结构化文档转换成内存中的DOM树 从DOM树输出结构化文档:将内存中的DOM树转换成磁盘上的结构化文档 2.DOM模型扩展了HTML元素,为几乎所有的HTML元素都新增了innerHTML属性,该属性代表该元素的"内容",即返回的某个元素的开始标签.结束标签之间的字符串内容(不包含其它

R语言学习笔记2——绘图

R语言提供了非常强大的图形绘制功能.下面来看一个例子: > dose <- c(20, 30, 40, 45, 60)> drugA <- c(16, 20, 27, 40, 60)> drugB <- c(15, 18, 25, 31, 40) > plot(dose, drugA, type="b") > plot(dose, drugB, type="b") 该例中,我们引入了R语言中第一个绘图函数plot.pl