C语言入门---位操作

目录

1. 两个数不同的二进制位个数

 2.原码、反码、补码

3.不创建临时变量实现两个数的交换

4.求一个整数存储在内存中的二进制中1的个数

5. 特例-1

6.将指定的位置置1

 7.将指定位置置1

8.++a与a++

9.||与&&

10.逗号表达式

11.srand与rand

12.sizeof

 13.结构体初始化

 14.枚举初始化与赋值


1. 两个数不同的二进制位个数

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

 

 2.原码、反码、补码

int main()
{
	/*首先写出两个数的补码,再按位与,再求出它的原码,按规定打印出来*/
	int a = 3;
	int b = -5;
	//00000000 00000000 00000000 00000011 -- 原码、反码、补码一样
	//10000000 00000000 00000000 00000101 -- 原码
	//11111111 11111111 11111111 11111010 -- 取反
	//11111111 11111111 11111111 11111011 -- 加1得补码
	//00000000 00000000 00000000 00000011 -- 3和-5的补码按位相与
	int c = a & b;
	printf("%d\n", c);//相与的结果以%d的形式打印,即打印一个有符号的整数
	//我们求出的是3和-5的补码按位与的结果存在了c里面
	//但我们需要打印它的原码
	//而c最高位是0,是正数,原码补码反码都一样,故打印3
	return 0;
}

        首先写出两个数的补码,再按位与,再求出它的原码,按规定打印出来

    printf("%d\n", c);//相与的结果以%d的形式打印,即打印一个有符号的整数
    //我们求出的是3和-5的补码按位与的结果存在了c里面
    //但我们需要打印它的原码
    //而c最高位是0,是正数,原码补码反码都一样,故打印3

3.不创建临时变量实现两个数的交换

        容易溢出:

    int a = 3;//0000 0011
	int b = 5;//0000 0101
	a = a + b;//a = 8
	b = a - b;//b = 3
	a = a - b;//a = 5

        采用异或:

    0^a = a;相同为0,不同为1
	0000 0000 0000 0000
	0000 0101 0111 1011 -- a
	0000 0101 0111 1011 -- a
	/*本来是0的还是0,本来是1的还是1*/
	a^a = 0;相同为0
	那么a^a^b = b
	异或支持交换律
	a^(a^b) = b
	b^(a^b) = a
	那么b^b^a = a
	0000 0110 -- a = a^b
	0000 0101 -- b 
	0000 0011 -- b = b^a
	0000 0110 -- a
	0000 0101 -- a = a^b
	a = a ^ b;//a = 3^5
	b = b ^ a;//b = 5^3^5 = 3
	a = a ^ b;//a = 3^5^3 = 5

4.求一个整数存储在内存中的二进制中1的个数

    int a = 31;
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{

		if (((a >> i) & 1) == 1)
		{
			count++;
		}
	}
	printf("%d\n", count);

5. 特例-1

    int b = 0;
	printf("%d\n", ~b);//-1

规定了1111 1111 1111 1111 11111 1111 1111 1111为-1

6.将指定的位置置1

    //改变任意位
    int a = 5;//0000 0101
	//0000 0010
	//0000 0111 -- 7
	a |= (1 << 1);

以改变第1位为例:

        因为按位或,又一个规律,1|x = 1;0|x = x,那么与1相或如果是1还是1,如果是0还是1

 7.将指定位置置0

#include<stdio.h>
int check_num1(int n, int j)//0000 0001
//0000 0100
//1111 1011
//0000 0101
//相与的特点是:同1才为1,其余均为0,所以只要我把我想要变成0的位与0相与一定可以变成0
{
	n = (~(1 << (j - 1)) )& n;
	return n;
}
int main()
{
	int num = 5;//0000 0101
	int i = 0;
	scanf("%d", &i);
	int ret = check_num1(num,i);
	printf("%d\n", ret);
	return 0;
}
a &= ~(1 << 1);

8.++a与a++

	int main()
	{
		int c = 3;
		int d = c++;
		printf("%d %d\n", c, d);

		int m = 5;
		int n = ++m;
		printf("%d %d\n", m, n);

		int x = 10;
		printf("%d", x--);//先打印再--

		printf("\n");
		printf("%d", x);

		/*printf("\n");
		printf("%d", --x);*/
		return 0;
	}

	int x = 10;
	printf("%d", x--);//先打印再--
	printf("\n");
	printf("%d", x);

9.||与&&

    int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++ || ++b || d++;
    因为a = 1先赋值给i,a = 1为真,故不会对b和d进行计算还是原本的值
	之后a进行自增,故打印的是2234
	printf("%d\n", i);
	printf("%d %d %d %d", a, b, c, d);

	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ || ++b || d++;
	0为假,故会计算b,b先自增变成3为真,后面不计算
	int j = (a++ || ++b || d++);
	printf("%d\n", i);//0
	printf(" %d\n", j);//1
	printf("%d %d %d %d", a, b, c, d);//1334

注意:0为假,故会计算b,b先自增变成3为真,后面不计算

10.逗号表达式

逗号表达式,整个表达式的结果是最后一个表达式的结果
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d\n", c);//13
printf("%d %d\n", a ,b);
}

11.srand与rand

#include<stdlib.h>
#include<time.h>

int main()
{
	
	int i = 10;
	int j = 0;
	/*不加这句话每次都是打印相同的随机数*/
	//srand((unsigned int)time(NULL));
	while (i--)
	{
		
		j = (int)rand();
		printf("%d\n", j);
	}
	
	
	return 0;
}

 12.特殊的结构体初始化

	typedef struct student 
	{
		int grade;
		char name[10];
		int telenum[12];
		char age;
		char sex[10];
	}student;
    int main()
    {

	    student Stu = { 1, };//这种初始化就是让第一个成员变量特殊赋值
	    return 0;
    }

 13.枚举初始化与赋值

#define voice_max 100
typedef enum { DG, DN, UDG = 10, UDN } test;	注意test就是我这里给这个枚举类型自定义的一个新的类型名,类似与int,float等。
int main()
{
	//注意test就是我这里给这个枚举类型自定义的一个新的类型名,类似与int,float等。
	test b;

	//b = 2 //  注意此处虽然是对枚举变量赋值,赋的范围虽然也在枚举值范围内,但这是错的,因为你不能用数字直接对其进行赋值。 

	//	b = (test)2;  // 这样就可以了,加一个枚举类型的强制转换即可。

	//test b;
	b = UDG; //b是一个枚举变量,而UDG是一个枚举值常量,这样赋值就是正确的
	printf("%d", b);
	printf("%d", b);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值