Day 24 操作符 4.8

操作符分类:

算术操作符

移位操作符

位操作符

赋值操作符

单目操作符

关系操作符

逻辑操作符

条件操作符

逗号表达式

下标引用,函数调用和结构成员

算术操作符

int main()
{
	float b = 3 / 2;
	printf("%f\n", a);

	int a = 9 % 2;
	printf("%d\n", a);

	return 0;
}
//例如加减乘除这些。

移位操作符

整数的二进制表示有三种形式,原码,反码,补码。

正整数的原反补是相同的,

负整数的原反补的要计算的。

整数在内存中储存的是补码的二进制。

int a = 5;
//a有32给比特位,a的二进制位为
//00000000000000000000000000000101 --原码
//最高位的0是符号位,0表示正数,1表示负数。

int a = -5;
//10000000000000000000000000000101 --原码
//11111111111111111111111111111010 --反码是原码符号位不变,其他位按位取反。
//11111111111111111111111111111011 --反码加一即是补码
int main()
{
	int a = 5;
	int b = a << 1;
    //00000000000000000000000000000101
    //最高位的0移出去,后面补0进来
    //00000000000000000000000000001010

	printf("%d\n", a);
	printf("%d\n", b);
	//但是打印出来的是原码。需要计算得到原码。
    return 0;
}
int main()
{
	int a = 5;
	int b = a >> 1;
	//00000000000000000000000000000101

	printf("a=%d b=%d\n", a, b);
	return 0;
}
//右移的情况下,有两种:
//一种是算数右移:右边丢弃,左边补原符号位。
//一种是逻辑右移:右边丢弃,左边补0。
//采用哪一种是取决于编译器的。

不能写移动的数位为负数。

位操作符

&       按位与 (只有两个数的二进制同时为1,结果才为1,否则为0)

|        按位或 (参加运算的两个数只要两个数中的一个为1,结果就为1)

^       按位异或 (对应的二进制位,相同为0,相异为1)

int main()
{
	int a = 3;
	int b = -5;
	
    //int c = a & b;
    //00000000000000000000000000000011  3
	
    //int c = a | b;
    //11111111111111111111111111111011  -5
	
    int c = a ^ b;//异或
    //11111111111111111111111111111000
	//11111111111111111111111111110111
	//10000000000000000000000000001000  -8(原码)
	//对应的二进制位:相同位0,相异为1
	
    printf("%d\n", c);

	//00000000000000000000000000000011  -> 3的补码
	//11111111111111111111111111111011  -> -5的补码
	
	return 0;
}

a^a=0;

0^a=a;

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

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

	printf("a=%d b=%d\n", a, b);
	//int tmp = a;
	//a = b;
	//b = tmp;
	
	//a = a + b;
	//b = a - b;
	//a = a - b;

	a = a ^ b;
	b = a ^ b;
	a = a ^ b;

	printf("a=%d b=%d\n", a, b);

	return 0;
}

赋值操作符

int weight = 120;
weight= 80;
double salary = 10000.0;
salary = 200000.0;

赋值操作符还可以连续使用:

int a = 10;
int x = 0;
int y = 20;
a = x = y +1;//连续赋值。
//从右往左连等,y+1的值赋给x,x再赋给a。

但是连续赋值可读性较差。

复合赋值符

+=

-=

*=

/=

>>=

<<=

&=

|=

^=

布尔类型

用来表示真假的变量。

int main()
{
	_Bool flag1 = false;
	bool flag2 = true;

	if (flag2)
	{
		printf("hehe\n");
	}

	//C语言中0表示假,非0表示真
	//int num = 10;
	//if (num)
	//{

	//}
	//if (!num)//num为假,做事情
	//{

	//}
	//
	return 0;
}

单目操作符

!        逻辑反操作

-        负值

+        正值

&        取地址

sizeof 操作数的类型长度(以字节为单位) 

~        对一个数的二进制按位取反

--        前置,后置--

++      前置,后置++

*         间接访问操作符(解引用操作符)

(类型)    强制类型转换

&和* 


int main()
{
	//& 取地址操作符
	//* 解引用操作符(间接访问操作符)
	
	int a = 10;
	int* pa = &a;
	*pa = 20;//* - 解引用操作符
	//
	//*&a ==> a;
	//
	int arr[10] = {0};
	&arr;//取出数组的地址,数组的地址应该放到【数组指针】中去

	struct S s = {0};
	struct S* ps = &s;
	
	return 0;
}

sizeof

内部的表达式不参与计算。

int main()
{
	int a = 10;
	short s = 0;
	printf("%d\n", sizeof(s = a + 2));//
	//sizeof()中的表达式不参与计算,在编译的时候就被处理掉了。

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

	return 0;
}

为什么while(~scanf("%d",&n))可以终止循环?

while(scanf("%d",&n)!=EOF)
{}

当scanf读取失败的时候,返回EOF,EOF本质是-1。

-1的二进制序列为:

                 11111111111111111111111111111111,

按位取反为000000000000000000000000000。

所以读取失败时,EOF被按位取反成0后跳出了循环。从而实现循环终止。

--与++

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

	//printf("%d\n", ++a);
	return 0;
}

逻辑操作符

&&逻辑与

||逻辑或

1&2 -->1
1&0 -->0

1|2 -->1
1|0 -->1
0|0 -->0
#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	//i = a++ && ++b && d++;

	i = a++ || ++b || d++;

	printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
	return 0;
}
//对于这种并且操作符,左边为假右边的就不会再计算了。

条件操作符

exp1?exp2:exp3

比如a>5?3:-3    如果a>5,那么整个表达式结果为3,否则为-3。

逗号表达式

int main()
{
	int a = 1;
	int b = 2;
	int c = (a > b, a = b + 10, a, b = a + 1);    
    //a>b后不管他,如何a=12,b=13
	printf("a=%d b=%d\n", a, b);
	printf("%d\n", c);//13
	return 0;
}

下标引用操作符,函数调用操作符和结构成员

int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	printf("%d\n", arr[4]);//arr[4]--> *(arr+4)
	printf("%d\n", 4[arr]);

	//arr
	//arr[4] = 5;//[] 就是下标引用操作符
	//arr 4

	return 0;
}

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	int ret = Add(2, 3);//()函数调用操作符,操作数就是:Add,2,3
	printf("%d\n", ret);

	return 0;
}


struct Point
{
	int x;
	int y;
};

隐式类型转换

C的整形算数预算总是以缺省整形类型的精度来进行的。

为了获取这个精度,表达式中的字符和短整型操作数在使用前被转换为普通整形,这种转换被称为整形提升。

整形提升

int main()
{
	char c1 = 3;
	//00000000000000000000000000000011
	//00000011 - c1 
	char c2 = 127;
	//00000000000000000000000001111111
	//01111111 - c2
	

	char c3 = c1 + c2;
	//00000000000000000000000000000011
	//00000000000000000000000001111111
	//00000000000000000000000010000010
	//10000010 - c3
    //提升时高位全补1。
	//11111111111111111111111110000010(补码)
	//11111111111111111111111110000001
	//10000000000000000000000001111110
	//-126

	printf("%d\n", c3);//
	//
	return 0;
}
int main()
{
	char c = 1;
	printf("%u\n", sizeof(c));//1
	printf("%u\n", sizeof(+c));//4
	printf("%u\n", sizeof(-c));//4
	return 0;
    //只要有char类型参与计算,就会发生整形提升。
}

算术转换

如果某个操作符操作数为不同类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作无法进行,所以就有了算术转换。

long double
double
float
unsigned long int
long int
unsigned int
int
//向上转换,

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值