C语言操作符篇章-程序员宅基地

技术标签: 算法  c语言  C语言的系统性学习  开发语言  

附带操作符的优先性和结合性图片

在讲解操作符之前需要讲解一下原反补和进制之间的转换

并且在讲解操作符的时候会重点对难点进行讲解,也就是算数操作符和逻辑操作符

并且会在讲解附带实例 和最后面的代码分析

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

补码反码掩码以及原理

补码、反码和掩码是计算机科学中用于表示和处理数值的三种编码方式。

原码

原码是最直观的数值表示方法,它将数值的二进制表示与其符号位结合起来。在原码表示中,正数的符号位为0,而负数的符号位为1。原码的缺点在于它无法直接表示负数,因为在计算负数的时候需要进行特殊的处理。

反码

反码用于简化负数的运算。对于正数,其反码与原码相同;对于负数,反码是将原码除符号位外的所有位取反(0变1,1变0)。反码解决了原码在进行加减运算时需要额外的符号位转换的问题,但它仍然存在正负零的区分问题。
 

补码

补码是目前计算机中最常用的数值表示方法。对于正数,补码与原码相同;对于负数,补码是在反码的基础上加1。补码的优点在于它将符号位的概念和数值的表示统一起来,并且使得加法和减法运算统一化,简化了计算机内部的逻辑电路设计。

下面顺便提一嘴掩码,不过多赘述。

掩码

掩码通常用于位操作中,它是一个用于遮掩或选择特定位数的二进制数。在计算机编程中,掩码常用于位运算,比如设置或清除特定的位。通过掩码,可以很方便地控制数值的某几位是否参与运算或被设置为特定的值。

例如,如果要设置一个整数的第3位到第5位,可以构造一个掩码,其中只有这些位是1,其余位是0。然后将这个掩码与整数进行按位与操作,就能达到设置这些位的目的。
综上所述,补码、反码和掩码都是计算机中数值表示和处理的重要工具,它们各有特点和应用场景。补码广泛应用于计算机中的数值计算,反码在某些特定的数学运算中有所应用,而掩码则主要用于位操作和特定位的控制。

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

C语言代码实例代码解释原码反码补码

解释:计算机里面进行数值的计算往往是补码进行计算,也就是在计算机里面进行计算是32位,如果数值是正整数的情况下32位的初始位从左到右的第一个位是0也就是符号位,如果是负数的情况下,从左到右初始位也就是符号位是1。

——————————————————————————————————————————————————————————————————————————————————————

进制的计算:

这里拿术语和画图进行计算

二进制的计算

二进制计算是基于计算机内部采用的二进制数系统来进行的。二进制数系统仅使用两个数字:0和1,低位向高位进位是逢二进一,借一当二。在二进制中,借一当二意味着,当某一位上的数字达到2时,它将向更高位进1,同时,进位的1将会被加到下一位的计算中。
二进制计算包括基本的加法、减法、乘法和除法,以及更高级的运算如幂和对数计算。以下是一些基础的二进制运算的解释:
1. **二进制加法**:
   - 类似于十进制加法,二进制加法也是从最低位(最低有效位)开始相加。
   - 如果相加的结果小于2,则直接写下来;
   - 如果相加的结果为2或更高,则向前进一位,并将剩余的数值(1或0)写下来。
   - 进位会在下一位的计算中加入。
2. **二进制减法**:
   - 二进制减法类似于加法,不过是通过添加负数来实现的。
   - 借一当二规则在这里也适用,不过是从高位向低位借位。
3. **二进制乘法**:
   - 二进制乘法使用类似于十进制的乘法算法。
   - 每一位乘数乘以另一个数的每一位,然后将结果相加。
4. **二进制除法**:
   - 二进制除法通过重复减去除数的最小倍数来实现。
   - 这可以通过不断左移除数来实现,直到被除数小于除数为止。
5. **二进制幂运算**:
   - 计算二进制幂可以通过重复乘以2来实现,即每次将现有的二进制数左移一位。
6. **二进制对数运算**:
   - 二进制对数可以通过幂的逆运算来计算。
   - 具体来说,可以通过查找2的幂次方表,来确定一个二进制数是多少次方。

——————————————————————————————————————————————————————————————————————————————————————

画图举例二进制和十进制之间的关系:        

我们计算拿15举例

首先计算15转换成二进制

15转换成二进制

14举例

14转换成二进制

再计算二进制转换成十进制

这里是1 1 1 1二进制 换算成十进制15的数值

这里是1 1 1 0二进制 换算成十进制14的数值

——————————————————————————————————————————————————————————————————————————————————————

画图进行解释进制的转换关系

二进制和八进制之间的互相转化

这里是二进制的转换关系 左边是十进制 右边是二进制

 简单的说就是二进制转换成八进制可以进行一次三位的计算

简单的说就是二进制转换成16进制可以进行一次4位的计算

这里解释完二进制的计算,我们继续回归主体,讲解原码反码补码。

——————————————————————————————————————————————————————————————————————————————————————

讲解原码反码补码:

什么是原码反码补码

这里再赘述一遍

原码、反码和补码是计算机中表示有符号整数的三种不同的编码方式,主要用于二进制数的表示和运算。下面分别解释这三种编码方式:
1. **原码**:原码是最直观的一种表示方法,每一位二进制数位都表示一个数的二进制位。对于正数,原码和其二进制表示相同;对于负数,原码在最高位(符号位)为1,其余位表示该数的绝对值。例如,+0的原码是00000000,-1的原码是10000000。
2. **反码**:反码用于简化正负数的加减运算。对于正数,其反码与原码相同;对于负数,其反码是将原码中除符号位外的所有位取反(0变1,1变0)。例如,+0的反码是00000000,-1的反码是11111111。
3. **补码**:补码也是为了简化计算机中的加减运算,特别是减法运算。正数的补码与其原码相同;负数的补码是其反码加1。例如,+0的补码是00000000,-1的补码是11111111(反码是11111111,加1得到11111110,但由于计算机通常使用补码表示负数,所以通常直接将11111111作为-1的补码)。
补码的优点在于,它将符号位的概念和数值的表示统一起来,同时使得加法和减法运算统一化,简化了计算机内部的逻辑电路设计。在现代计算机系统中,补码是最常用的表示方法。

——————————————————————————————————————————————————————————————————————————————————————

计算机是如何计算的

在计算机计算数值里面,计算机会把数值计算成

 这里我们拿代码进行举例

这里是正数的数值 正数的数值原码反码补码的数值是一样的

这里的数值是10来进行举例

这里需要知道的是,计算机进行计算转换的时候是把十进制的数值转换成二进制,然后把二进制计算成补码然后进行计算。

正数的计算是原码反码补码是一样的。

负数的原码反码不一样是有计算过程的

是在原码的基础上 取反+1

如图

这里我们需要知道,计算的时候数值是由32位的比特位组成,从右边向左边进行加减,也就是正常的加减乘除。如果是类型不一样的情况下,则会进行截断,也就是丢失数据,下面会进行讲解。

 计算机运用符号,按位与或者按位或计算期间是利用补码进行计算

计算完毕之后返回原路 也就是之前是取反+1

补码计算完成之后需要 补码取反+1 变成原码 呈现给你看

需要知道 32位 最前面的是符号位 0是正数 1是负数

——————————————————————————————————————————————————————————————————————————————————————

下面我们举两个例子

拿这个来举例

举例1:

代码解释 

所以-1是最特殊的 32位1 

下面会剖析为什么是32位 


举例2:

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

操作符的详解

 1.左移操作符<<

向左移动补的是0

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int a = 6;
	int b = a << 1;
	printf("%d", b);
	return 0;
}

 向左移动一位

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int a = 6;     //0000000000 0000000000 000000000 111
	int b = a << 1;//000000000 0000000000 000000000 1110
	printf("%d", b);
	return 0;
}

——————————————————————————————————————————————————————————————————————————————————————

2.右移操作符>>

右移操作符和左移操作符基本上一样,左移操作符是向左移动补0,右移操作符是向右移动补符号位

移位规则:首先右移运算分两种:
1.逻辑右移:左边用填充,右边丢弃
2,算术右移,左边用原该值的符号位填充,右边丢弃

右移到底是算术右移,还是逻辑右移是取决于编译
器的实现,常见的编译器都是算术右移

向右移动补的是算数位

简单的说就32位的二进制的数字每次右移动(下面会介绍为什么是32位)

之前我们讲解了原码反码补码,这里直接上代码 计算机计算的过程是正数的原反补一样,负数需要符号位取反,然后除符号位全部取反+1,得到补码进行计算。计算完毕后,补码除符号位之外全部取反+1得到原码转化成二进制进行计算。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int a = 5;
	int b = a >> 1;
	printf("%d", b);
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int a = 5;//转换成补码是110->000000000 0000000000 0000000000 110
	int b = a >> 1;//右移动一位 最左边补上符号位 也就是 0000000000 0000000000 0000000000 11
	printf("%d", b);
	return 0;
}

 需要知道a还是5

但是接收a数值的b则是产生了变化 

这里千万记住计算的时候是先换算成补码,补码补码之间进行计算,然后计算出的补码换算成原码转换成二进制。——————————————————————————————————————————————————————————————————————————————————————

3.算数运算符和逻辑运算符

按位与&

按位与逻辑是

按位与运算符是位运算符的一种,它对两个操作数(通常为整数)的每一位进行 AND 运算。如果两个操作数的相应位都为1,则结果的相应位为1,否则为0。

这里千万记住计算的时候是先换算成补码,补码补码之间进行计算,然后计算出的补码换算成原码转换成二进制。

——————————————————————————————————————————————————————————————————————————————————————

按位或|

这里千万记住计算的时候是先换算成补码,补码补码之间进行计算,然后计算出的补码换算成原码转换成二进制。——————————————————————————————————————————————————————————————————————————————————————

异或^

相同为0 不同为1

再取反 +1

这里取反+1的目的是自己看自己算出来是数值几

这里千万记住计算的时候是先换算成补码,补码补码之间进行计算,然后计算出的补码换算成原码转换成二进制。——————————————————————————————————————————————————————————————————————————————————————

~波良号 按位取反

对二进制数列 按位取反

11111111111111111111111111111111(这个数值是-1 特殊数值进行记忆)

然后这里 依旧是 取反 +1

这里千万记住计算的时候是先换算成补码,补码补码之间进行计算,然后计算出的补码换算成原码转换成二进制。

——————————————————————————————————————————————————————————————————————————————————————

4.实例操作

1.实现数值的交换

版本1 

版本2

版本3

异或^

相同为0 不同为1 也就是把第一个a相互代入 下面的a b

简单的说就是a^b就是一把钥匙

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//交换两个变量(不创建临时变量)
//3
int main()
{
	int a = 3; int b = 5;
	printf("交换前a = %d  b = %d\n", a, b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("交换后a = %d  b = %d", a, b);
}

 2
int main()
{
	int a = 3; int b = 5;
	printf("交换前a = %d  b = %d", a, b);
	a = a + b;
	b = a - b;
	a = a - b;
	printf("交换后a = %d  b = %d", a, b);
}
//
//
//1.创建变量的情况下
int main()
{
	int a = 3; int b = 5;
	int c = 0;
	c = a;
	a = b;
	b = c;
	printf("%d %d", a, b);
}

——————————————————————————————————————————————————————————————————————————————————————

2.求一个整数二进制里面1的个数

版本1

但是这里-1是错误的也就是 这个代码对于负数是不正确的

无符号整数来看待 满足计算要求

版本2

版本3

 

 

执行一次去掉一个1

二进制里面的嘴右边的1 消失

说明执行一次去掉1一次

//#define _CRT_SECURE_NO_WARNINGS 1
//#include<stdio.h>
3
//int main()
//{
//	int input = 0; int count = 0; 
//	printf("输入数值,系统自动计算二进制里面1的个数:\n");
//	scanf("%d", &input);
//	while (input)
//	{
//		input = input & (input - 1);
//		count++;
//	}
//	printf("二进制里面1的个数是:%d", count);
//	return 0;
//}
//
//2
int main()
{
	int input = 0; int count = 0; 
	printf("输入数值,系统自动计算二进制里面1的个数:\n");
	scanf("%d", &input);
	for (int i = 0; i < 32; i++)
	{
		if (((input >> i) & 1) == 1)
			count++;
	}
	printf("二进制里面1的个数是:%d", count);
	return 0;
}
//
1
int main()
{
	unsigned int input = 0; int count = 0; 
	printf("输入数值,系统自动计算二进制里面1的个数。");
	scanf("%d", &input);
	while (input != 0)
	{
		if (input % 2 == 1)
			count++;
		input = input / 2;
		
	}
	printf("%d", count);
	return 0;
}

——————————————————————————————————————————————————————————————————————————————————————

3.比较二进制的个数

版本 1

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
1
//int main()
//{
//	unsigned int input1 = 0; unsigned int input2 = 0; int count = 0;
//	printf("输入两个数值,系统自动计算成二进制并且计算几个位不一样:\n");
//	scanf("%d %d", &input1, &input2);
//	while (input1 != 0 || input2 != 0)//这里只能是或者 并且的话 缺少条件 或者就是一个没有完成 继续循环
//	{
//		if ((input1 % 2) != (input2 % 2))
//			count++;
//		input1 = input1 / 2;
//		input2 = input2 / 2;
//
//	}
//	printf("%d", count);
//	return 0;
//}

下面还会用实例两个有难度的代码进行剖析

在此之前补充一些知识

包括这个举例 用逻辑运算符写出代码

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

5.操作符的优先级和结合性

优先级

这个是优先级,但是计算好优先级不代表可以写出正确的代码

优先级只是决定优先级不同的进行先后运算

优先级相同决定的是结合性

结合性是什么 简单的说就是大部分的运算符是从左到右进行结合的

小部分是从右向左

就比如这里 是先计算5*6 再计算除以二

——————————————————————————————————————————————————————————————————————————————————————

结合性

这里也可以通过圆括号进行优先级的修改

赋值运算符的优先级是非常低的

——————————————————————————————————————————————————————————————————————————————————————

问题代码

问题表达式解释

1.简单的说就是么有确定唯一的计算路径 这里就是很危险

这里如果abcef的每一个的表达式 并且每一次的表达式有相同的变量 这里就会导致不能确定唯一的计算路径 计算的结果是不一样的

这里的解决办法是拆开写 或者加上括号

所以一个表达式解决所有的问题是不现实的

——————————————————————————————————————————————————————————————————————————————————————

2.这里无法确定c是优先计算还是后计算

——————————————————————————————————————————————————————————————————————————————————————

3.问题代码

——————————————————————————————————————————————————————————————————————————————————————

4.问题代码

下面补充一些二进制为什么是32位

以及整形提升和算数转换

下面还会用实例两个有难度的代码进行剖析

在此之前补充一些知识

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

计算机里面的二进制计算的32位指的是什么

32位环境

通常指的是一个计算机系统或操作系统的架构,其中处理器、内存地址以及其他硬件和软件资源都使用32位二进制数来表示。这意味着该系统可以处理的数据量最大为2的32次方(即4,294,967,296)个不同的值。
在32位环境中,

处理器的寄存器、内存寻址以及其他硬件参数都是32位的。这影响了系统的地址空间大小、可以处理的数据量以及可以同时运行的程序的大小。例如,32位系统上的内存地址空间最大为4GB(2的32次方字节),尽管实际上由于各种系统开销,可用内存可能少于这个量。
32位环境也可以指编译器或编程语言的执行环境,例如,某些编译器或编程语言可以在32位操作系统上运行,或者专门为32位处理器优化。

——————————————————————————————————————————————————————————————————————————————————————


在操作系统方面

32位操作系统是指系统核心以及运行在系统上的应用程序都是为32位硬件环境设计的。这包括Windows XP、Windows 7等,它们都可以在32位处理器上运行。
在编程语言和工具方面,32位环境可能涉及到汇编语言、C语言、C++等编程语言,以及相关的开发工具和库,它们都是针对32位处理器架构的。

这里涉及到一些指针的知识简单的理解就是

首先,必须理解,计算机内是有很多的硬件单元,而硬件单元是要互相协同工作的。所谓的协同,至少相互之间要能够进行数据传递
但是硬件与硬件之间是互相独立的,那么如何通信呢?答案很简单,用"线”连起来
而CPU和内存之间也是有大量的数据交互的,所以,两者必须也用线连起来
不过,我们今天关心一组线,叫做地址总线

计算机中的编址,并不是把每个字节的地址记录下来而是通过硬件设计完成的。

钢琴、吉他 上面没有写上"剁、来、咪、发、唆、拉西”这样的信息,但演泰者照样能够准确找到每一个琴弦的每一个位置,这是为何?因为制造商已经在乐器硬件层面上设计好了,并且所有的演奏者都知道。本质是一种约定出来的共识!
硬件编址也是如此
32位机器有62根地址总线,每根线我们可以简单理解只有两态,表示0,1[电脉冲有无],那么一根线,就能表示2种含义,2根线就能表示4种含义,依次类推。32就能表示2^32种含义,每一种含义都代表一根地址线个地址
地址信息被下达给内存,在内存上,就可以找到该地址对应的数据,将数据在通过数据总线传入CPU内寄存器。

简单说就是每一个数值代表一个信号 比如01代表信号 11代表信号

可以简单理解为32位就是 2的32次方个信号 

这里就可以理解为 

——————————————————————————————————————————————————————————————————————————————————————

计算里面的32位指的是什么

32位通常指的是32位二进制数,而不是32位字节。在计算机科学中,位(bit)是衡量数据存储和处理容量的基本单位,而字节(byte)是由8位组成的,是计算机中常用的数据单位。
32位二进制数意味着有32个独立的二进制位,每个位可以是0或1,因此它可以表示2^32(即4,294,967,296)个不同的值。这32位可以用来表示数据、地址或其他信息。
在计算机体系结构中,32位处理器意味着处理器可以一次处理32位的数据。这32位数据通常在处理器内部的寄存器中进行运算。寄存器是CPU内部的高速存储单元,用于存储指令、数据和地址等信息。
总结来说,32位是指32位二进制数,而不是32个字节。在计算机中,一个字节由8位组成,因此32位等于4个字节。

——————————————————————————————————————————————————————————————————————————————————————

不同环境下占据的不同字节长度

在计算机术语中,x86和x64通常指的是处理器的指令集架构,而不是直接指代四个字节或八个字节。不过,这两个术语确实与处理器的字长有关,字长决定了处理器可以一次性处理的二进制数据的位数。
x86架构,最初是指32位处理器架构,它起源于1978年英特尔发布的8086处理器。随着时间的推移,x86架构逐渐扩展,支持更高级的功能和更大的内存寻址空间。x86架构的处理器可以处理32位数据,也就是说,它们一次可以处理32个二进制位的数据。
x64架构,也称为x86-64或amd64,是在x86架构的基础上扩展而来的64位处理器架构。它由AMD公司首次提出,并得到了英特尔等公司的支持。x64架构的处理器可以处理64位数据,即一次可以处理64个二进制位的数据。
在这里,“四个字节”和“八个字节”是指数据传输和存储的单位。在32位系统中,通常使用的数据单位是四个字节,因为32位数据正好占用四个字节的空间。而在64位系统中,由于处理的位数增加,通常使用的数据单位是八个字节,即64位数据占用八个字节的空间。
总结来说,x86和x64指的是处理器的指令集架构,而四个字节和八个字节是指数据传输和存储的单位。在32位系统中,一个字节由8位组成,因此32位等于4个字节。而在64位系统中,一个字节仍然由8位组成,但64位数据通常占用8个字节的空间。

——————————————————————————————————————————————————————————————————————————————————————

指针变量不同环境下占据字节长度

指针变量x86环境下 占据的是4个字节 x64的环境下占据的是8个字节

——————————————————————————————————————————————————————————————————————————————————————

指针类型

不同指针类型占据的字节长度是不一样的

比如int

在大多数现代计算机系统中,int 类型通常占用 4 个字节(32位)的内存空间。这意味着一个 int 类型的变量可以存储 2 的 32 次方,即 4,294,967,296 种不同的值。
然而,这并不是绝对的。在一些旧的或特殊的硬件平台上,int 可能占用不同的字节数,例如 2 个字节(16位)。此外,在 C99 标准中,int 的大小被定义为至少 16 位,但在 C99 之前的标准中,int 的大小没有这样的保证。
在编写跨平台的代码时,如果你想确保 int 类型的大小,可以使用 int32_t 和 int64_t 类型,它们分别代表有 32 位和 64 位的整数类型,这些类型在 C99 标准中定义在 <stdint.h> 头文件中。

这里还需要讲解一下整形提升和算数转换

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

什么是整形提升,什么是算数转换

整形提升

这里需要知道的是计算机进行计算的时候在C语言的编译器里面除去

 整型提升
C语言中整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。
通用CPU (eneral-purpose CPU) 是难以直接实现两个8比特字节直接相加运算 (虽然机器指中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。

举例

进行解释的意思就是

这里面的是char的类型 小于整形的类型 进行整形提升

char存放一个字节 也就是八个比特位

然后ab进行整形提升

高位补0 把除 一个字节 八个比特位之外的补满32位

但是此时char只有一个字节 也就是八个比特位 然后再对其进行八个比特位 一个字节之外的进行截断

但是这里是整形的打印%d

打印的时候也是会进行整形提升的

但是此时char的最高位是1

进行整形转换 char转换成int 补满32位

补满 11111111111111111

但是计算机的计算是补码计算的 然后取反+1

这里需要知道 计算的结果 和所有计算的过程都是补码 只有计算打印出来的结果才是原码

关于char的讲解

这里为什么是

简单说 就是提升取决于编译器环境是32位还是64位,而不是类型

——————————————————————————————————————————————————————————————————————————————————————

算数转换

简单的说就是向上转换的形式进行转换 被称为算数转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为!一个操作数的类型,否则操作就无法进行。下面的层次体系称为导常算术转换。
1 long double
2 double
3 float
4 unsigned long int
5 long int
6 unsigned int
7 int
如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外一个操
数的举型后执行运管

简单的说就是向上转换的形式进行转换 被称为算数转换

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

上述内容举例代码和具体的应用:

结合性实例1:

单身狗1

找出 出现一次的数字

在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。

例如:

数组中有:1 2 3 4 5 1 2 3 4,只有5出现一次,其他数字都出现2次,找出5

单身狗1

找出 出现一次的数字

异或 相同为o 不同为1

所以

这里可以理解成加等于 同理异或也是一样 

这是从0开始异或 0异或任何数字都是数字本身

代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int arr[] = { 1,2,3,1,2 }; 
	int len = sizeof(arr) / sizeof(arr[0]);
	int sum = 0;
	for (int i = 0; i < len; i++)
	{
		sum ^= arr[i];
	}
	printf("%d", sum);
	return 0;
}

——————————————————————————————————————————————————————————————————————————————————————

结合性实例2:

打印二进制里面的奇偶数位

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

打印二进制里面的奇偶数

 

判断是1还是0

 

内存的最小划分是字节 不能是比特位

 //这里还需要注意一点就是 为什么不是32 而是30 或者31而是因为数值在计算的时候首位已经计算,右移操作符右移动的时候是不能越界的,如果i==32的话进行计算的时候是容易超过最后一位的

代码1(上面的是代码1 的讲解)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void Printbit(int num)
{
	for (int i = 31; i >= 1; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");

	for (int i = 30; i >= 0; i -= 2) 
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");
}
int main()
{
	int num = 14;
	Printbit(num);
	return 0;
}

代码2

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//打印整数二进制的奇数位和偶数位
int main()
{
	int i = 0; int count = 0;
	printf("输入十进制,系统打印整数二进制的奇数位和偶数位:");
	scanf("%d", &i);
	for (int j = 0; j < 32; j++)
	{
		if (((i >> j) & 1) == 1 || ((i >> j) & 1) == 0)
		{
			count++;
			if (count % 2 == 0)
			{
				printf("偶数位:%d\n", (i >> j) & 1);
			}
			else
			{
				printf("奇数位:%d\n", (i >> j) & 1);

			}
		}
	}
	return 0;
}

——————————————————————————————————————————————————————————————————————————————————————

整形提升的实例讲解1

 

short类型的指针每次解引用只会修改两个字节

类型不一样 自然会进行强制类型的转换

——————————————————————————————————————————————————————————————————————————————————————

整形提升的实例讲解2

这这里是有符号数据和无符号数据进行整形提升 编程无符号数据

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Jason_from_China/article/details/135863815

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签