c语言初阶学习笔记——操作符详解(上)

一、操作符分类:

(操作符也是运算符)

算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员

二、算术操作符

 -   +   *   /   %
int main()
{
	//  / 除法 - 得到的是商
	// 除法操作符的两个操作数都是整数的话,执行的是整数除法
	// 除法操作符的两个操作数只要有一个浮点数,执行的是小数除法
	// 
	//  % 取模(取余)得到的是余数
	//  取模操作符的操作数必须是整数

	printf("%lf\n", 10 / 3.0);//5
	printf("%d\n", 10 % 2);//0

	return 0;
}

总结:

  1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
  2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
  3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

三、移位操作符

(移动的是二进制的位)

<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。

int a = -5;
查看整数在内存中存储的补码是什么:
在这里插入图片描述
4个二进制位表示一个16进制位
在这里插入图片描述

1.左移操作符

在这里插入图片描述
在这里插入图片描述
b=a<<1
a自身的值不会变化

int main()
{
	int a = -3;
	//10000000000000000000000000000011
	//11111111111111111111111111111100
	//11111111111111111111111111111101 - 补码
	//
	int b = a << 1;
	//11111111111111111111111111111010
	//11111111111111111111111111111001
	//10000000000000000000000000000110

	//11111111111111111111111111111010
	//10000000000000000000000000000101
	//10000000000000000000000000000110
	printf("%d\n", b);//-6
	printf("%d\n", a);//-3

	return 0;
}

在这里插入图片描述

2.右移操作符

右移运算分两种:

  1. 逻辑移位
    左边用0填充,右边丢弃
  2. 算术移位
    左边用原该值的符号位填充,右边丢弃

在这里插入图片描述
常见采用算术右移

注意:

对于移位运算符,不要移动负数位,这个是标准未定义的。

  int num = 10;
  num>>-1;//error

四、位操作符

& //按位与
| // 按位或
^ //按位异或
注:他们的操作数必须是整数。

int main()
{
	int a = 3;
	int b = -5;
	int c = a ^ b;//按位异或 - 对应的二进制位,相同为0,相异为1
	11111111111111111111111111111011 - -5的补码
	00000000000000000000000000000011 - 3的补码
	11111111111111111111111111111000
	11111111111111111111111111110111
	10000000000000000000000000001000

	int c = a | b;//按位或
	11111111111111111111111111111011 - -5的补码
	00000000000000000000000000000011 - 3的补码
	11111111111111111111111111111011

	int c = a & b;//按位与
	00000000000000000000000000000011 - 3的补码
	
	10000000000000000000000000000101 
	11111111111111111111111111111010
	11111111111111111111111111111011 - -5的补码
	00000000000000000000000000000011 - 3的补码
	00000000000000000000000000000011
	printf("%d\n", c);

	return 0;
}

小题一道

不能创建临时变量(第三个变量),实现两个数的交换

a^a = 0
0^a = a
3^ 3^ 5 = 5
3^ 5^ 3 = 5

int main()
{
	int a = 3;
	int b = 5;
	printf("交换前:a=%d b=%d\n", a, b);
	
	方法3:
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;

	方法2:(a和b加起来可能会超出整形大小)
	a = a + b;
	b = a - b;
	a = a - b;
	
	方法1:(不满足要求)
	int tmp = 0;
	tmp = a;
	a = b;
	b = tmp;
	
	printf("交换后:a=%d b=%d\n", a, b);

	return 0;
}

五、赋值操作符

赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
这样的代码感觉怎么样?
那同样的语义,再看看:
x = y+1;
a = x;
这样的写法是不是更加清晰且易于调试。

复合赋值符

+=
-=
*=
/=
%=
<<=
.>> =
&=
|=
^=

int x = 10;
x = x+10;
x += 10;//复合赋值
//其他运算符一样。这样写更加简洁。

六、单目操作符

单目操作符介绍

// ! 逻辑反操作
// - 负值
// + 正值
// & 取地址
// sizeof 操作数的类型长度(以字节为单位)
// ~ 对一个数的二进制按位取反
// – 前置、后置–
// ++ 前置、后置++
// * 间接访问操作符(解引用操作符)
// (类型) 强制类型转换

// !

int main()
{
	int flag = 5;
	if (flag)//flag为真做什么
	{

	}
	if (!flag)//flag为假做什么
	{

	}
	return 0;
}

// *

int main()
{
	int a = 10;
	int* p = &a;//&取地址操作符
	*p = 20;//解引用操作符(间接访问操作符)

	//int arr[10];
	//&arr;//取出数组的地址

	return 0;
}

// sizeof

int main()
{
	int a = 10;
	printf("%d\n", sizeof a);
	printf("%d\n", sizeof(a));

	printf("%d\n", sizeof(int));

	int arr[10] = { 0 };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr[0]));
	int sz = sizeof(arr) / sizeof(arr[0]);
	printf("%d\n", sz);

	return 0;
}

错误案例:

int main()
{
	int a = 3;
	a = 10;
	a + 3 = 15;//err
	return 0;
}

// ~

int main()
{
	int a = 0;
	//00000000000000000000000000000000
	//11111111111111111111111111111111
	//11111111111111111111111111111110
	//10000000000000000000000000000001
	//
	printf("%d\n", ~a);

	return 0;
}

在这里插入图片描述

结合使用

int main()
{
	int a = 3;
	//00000000000000000000000000000011
	//00000000000000000000000000001000
	a |= (1 << 3);
	printf("%d\n", a);

	//00000000000000000000000000001011
	//11111111111111111111111111110111
	a &= (~(1 << 3));
	printf("%d\n", a);

	return 0;
}

前置++和后置++

int main()
{
	int a = 10;
	//int b = --a;//前置--,先--,后使用
	int b = a--;//后置--,先使用,后--
	printf("a=%d b=%d\n", a, b);

	//printf("%d\n", ++a);//前置++,先++,后使用
	//printf("%d\n", a);

	//int b = a++;//后置++,先使用,再++
	//int b = a,a=a+1;
	//printf("a=%d b=%d\n", a, b);

	return 0;
}

强制类型转换是一种临时的状态

int main()
{
	float a = 3.14f;
	int b = (int)a;
	a还是float类型
	//int b = int(a);//err
	return 0;
}

sizeof和数组

#include <stdio.h>
void test1(int arr[])
{
 printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
 printf("%d\n", sizeof(ch));//(4)
}
int main()
{
 int arr[10] = {0};
 char ch[10] = {0};
 printf("%d\n", sizeof(arr));//(1)
 printf("%d\n", sizeof(ch));//(3)
 test1(arr);
 test2(ch);
 return 0;
}1)、(2)两个地方分别输出多少?   40  43)、(4)两个地方分别输出多少?   10  4

七、关系操作符

// >

// >=

<

<=
!= 用于测试“不相等”
== 用于测试“相等”

注意==和=不要写错

八、逻辑操作符

int main()
{
	int a = 3 && 5;
	a = 1 或者 0 因为真为1假为0
	printf("%d\n", a);// 1

	int a = 0 || 0;//1 0
	printf("%d\n", a);// 0

	return 0;
}

在这里插入图片描述
习题1:
在这里插入图片描述
结果1 2 3 4

习题2:
在这里插入图片描述
结果2 3 3 5

习题3:
在这里插入图片描述
结果2 2 3 4

习题4:
在这里插入图片描述
结果1 3 3 4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值