C语言学习之操作符(1)

目录

1.操作符分类

2.算数操作符 + - * / %

 3.移位操作符

4.位操作符

5.单目操作符

7.逻辑操作符


1.操作符分类

2.算数操作符 + - * / %

a.对于除法来说:

(1)整数除法(两边都是整数)

(2)浮点数除法(只要除号一边又浮点数就执行浮点数除法,得出来的结果是浮点数)

(3)除数不能为0

int main()
{
	int r = 7 / 2;
	printf("%d\n", r);
	double d = 7 / 2;
	printf("%lf\n", d);//3.5?
	return 0;
}

 运行结果如下

d的计算中,因为/左右两边都是整数,所以结果还是取商

要算出3.5 要采用浮点数的方法


b.%是取模负号,%的两边必须是整数

 3.移位操作符

<<左移操作符    >>右移操作符

注意:移位操作符的操作数只能是整数


一般来说,计算机能够处理的是二进制信息,所以当我们输入一个十进制整数的时候,电脑会自动将他转换成2进制来操作

整数的二进制有三种表示形式

原码,反码,补码

1.正整数的原码、反码、补码是相同的

2.负的整数原码、反码、补码是要通过计算的

以15为例子举例

int a = 15;//1111

1个整型是4个字节 = 32bit位,所以我们要把它补成32位

对于正整数来说,符号位第一位是0

00000000000000000000000000001111 - 原码
00000000000000000000000000001111 - 反码
00000000000000000000000000001111 - 补码

 对于负数来说(以-15为例)符号位第一位是1

 10000000000000000000000000001111 - 原码
 11111111111111111111111111110000 - 反码(原码的符号位不变,其他按位取反得到的就是反码)
 11111111111111111111111111110001 - 补码(反码+1就是补码)

注意:整数在内存中存储的是补码,计算的时候也是用补码来计算的

右移有除二的效果
移位移动的是补码的二进制序列

int main()
{
	int a = 15;
	int b = a >> 1;
	printf("%d\n", b);//7
	printf("%d\n", a);
	return 0;
}

 

int main()
{
	int a = -15;
	int b = a >> 1;
	printf("%d\n", b);
	printf("%d\n", a);
	return 0;
}

 
右移

算术右移:(右边丢弃,左边补原来的符号位,正补0,负补1)

逻辑右移:(右边丢弃,左边直接补0)

C语言没有明确规定用的是算术右移还是逻辑右移,一般编译器上采用算数右移


左移的话,直接在末尾加一个0就行

4.位操作符

& 按位与     

| 按位或         

^按位异或

 应用:

不用中间变量交换两个整型的值

这个是怎么实现的呢 

int main()
{
	int a = 3;
	int b = 5;

	//a ^ a = 0
	//a ^ 0 = a
	//异或是支持交换律的
	//a ^ b ^ a
	//011  a
	//101  b
	//110  a ^ b
	//011  a
	//101  (a ^ b) ^ a
	//a ^ a ^ b = 5
	a = a ^ b;
	b = a ^ b;//(a ^ b) ^ b = a
	a = a ^ b;//a ^ (a ^ b) = b
	return 0;
}

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

1. 整数有32个bit位

2. 获得32个bit位的每一位

3. 判断这一位是否为1

4. 是1就计数器+1

#include <stdio.h>
int countOnes(unsigned int num) 
{
  int count = 0;
  while (num != 0) 
  {
    count += num & 1; // 判断最低位是否为1
    num >>= 1; // 将num右移一位,相当于去掉了最低位
  }
  return count;
}


int main() 
{
  unsigned int num;
  scanf("%u", &num);
  printf("%d\n", countOnes(num));
  return 0;
}

5.单目操作符

! - 逻辑反操作

 & - 取地址  * - 解引用操作符   运用于指针

int main()
{
	int a = 10;
	//pa是指针变量
	int* pa = &a;//&-取地址操作符-取出a的地址

	*pa = 20;//解引用操作符(间接访问操作符)-单目操作符-通用pa中存放的地址,找到指向的空间(内容)
	int c = *pa;

	return 0;
}

sizeof (1)不是函数,是操作符

          (2)计算的是类型创建变量的大小,单位是字节

int main()
{
	int a = 10;
	printf("%d\n", sizeof(int));//4
	printf("%d\n", sizeof(a));//4
	printf("%d\n", sizeof a);//4
	//说明sizeof不是函数,因为一般函数必须带括号加形参
	return 0;
}
int main()
{
	int arr[10] = {0};
	printf("%d\n", sizeof(arr));//40 - 计算整个数组的大小,单位字节
	printf("%d\n", sizeof(int [10]));//40
	return 0;
}

~补码按二进制位取反(其实就是在每一位中0变1,1变0)

//int main()
//{
//	int a = 0;
//	printf("%d\n", ~a);
//	//00000000000000000000000000000000
//	//11111111111111111111111111111111 - 补码
//	//11111111111111111111111111111110
//	//10000000000000000000000000000001 //-1
//	return 0;
//}
int main()
{
	int a = 13;
	a |= (1 << 4);
	//00000000000000000000000000001101
	//00000000000000000000000000010000 -- (1 << 4)
	//00000000000000000000000000011101 -- a | (1 << 4) = 29
	printf("%d", a);
	a &= (~(1 << 4));
	printf("%d", a);//13
	return 0;
}

三种循环输入方式 

//int main()
//{
//	int a = 0;
//	while (scanf("%d", a) == 1)
//	{
//		printf("%d", a);
//	}
//	return 0;
//}
//int main()
//{
//	int a = 0;
//	scnaf 读取失败返回EOF
//	while (scanf("%d", a) != EOF)
//	{
//		printf("%d", a);
//	}
//	return 0;
//}
//int main()
//{
//	int a = 0;
//	scnaf 读取失败返回EOF
//	假设scanf读取失败,返回EOF --> EOF = -1
//	while (~scanf("%d", a))
//	{
//		printf("%d", a);
//	}
//	return 0;
//}

++和--

//--前置,后置--
//++前置,后置++

//int main()
//{
//	int a = 1;
//	int b = a++;//后置++,先使用,后++
//	//b = a, a = a + 1
//	printf("a = %d, b = %d", a, b);//2 1
//	return 0;
//}
//int main()
//{
//	int a = 1;
//	int b = a--;//后置--,先使用,后--
//	//b = a, a = a - 1
//	printf("a = %d, b = %d", a, b);//0 1
//	return 0;
//}
int main()
{
	int a = 1;
	int b = ++a;//前置++,先++,后使用
	//a = a + 1, b = a
	printf("a = %d, b = %d", a, b);//2 2
	return 0;
}

前置--跟前置++道理相同,不再赘述

强制类型转换

练习 

下列代码输出结果是啥?

 

 答案

6.关系操作符 

7.逻辑操作符

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	//a 和 b 都是5就打印hehe 两个都得满足才打印hehe
	if (a == 5 && b == 5)
	{
		printf("hehe\n");
	}
	//a或者b是5就打印haha 一个满足就能打印haha
	if (a == 5 || b == 5)
	{
		printf("haha\n");
	}
	return 0;
}

 

练习 

打印结果是啥

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
	int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;//a++ 
	printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);




	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ || ++b || d++;

	printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//1 3 3 4
	return 0;
}

答案和分析 

#include <stdio.h>
int main()
{
	//int i = 0, a = 0, b = 2, c = 3, d = 4;
	//i = a++ && ++b && d++;//a++ +使用前= 0为假,
	//&& 操作符,左边为假,右边就不计算了!
	//printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);// 1 2 3 4
	//int i = 0, a = 1, b = 2, c = 3, d = 4;
	//i = a++ && ++b && d++;//a++ +使用前=1为真,后面继续计算
	//printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
	// a = 2(因为a在前面已经使用过了,所以这里加上1等于2)
	//b = 3 c = 3 d = 5



	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++||++b||d++;// || 左右两边有一个是真就可以计算
	
	printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//1 3 3 4
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值