C语言操作符详解

        当我们学习C语言时会遇到许多操作符,在许多语句中都能使用,可以起到举足轻重的作用。不要小看这些操作码,下面让我详细讲解一下操作符。

操作符有很多:
算数操作符

移位操作符

位操作符

赋值操作符

单目操作符

关系操作符

逻辑操作符

条件操作符

逗号操作符 ......


算数操作符

+    -   *   /   % 

这些操作符都是我们经常见到的,如同数学运算符一样,适合于运算。但是算数运算符有一些注意事项:

1.除了%操作符以外,其他的几个操作符可以作用于整数和浮点数。

2.对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行就是浮点数除法。

3.%操作符的两个操作数必须为整数。返回的是整数之后的余数。

4.算数操作符一定在数学知识的基础上进行的。


移位操作符

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

 移位操作符是基于二进制数的基础上操作的,移动的是二进制的数据。计算机存储的就是二进制的数据由0和1组成的。如:10: 0000 0000 0000 0000 0000 0000 0000 1010,而计算机存储的一般是一个数的补码。正数的原码反码补码都是一样的,而负数的原码得到后将除过符号位(最高位)不变剩下的位数一律取反得到,补码就是反码加1。

移位移动的是补码的二进制序列

例子:-10

原码:1000 0000 0000 0000 0000 0000 0000 1010

反码:1111 1111 1111 1111 1111 1111 1111 0101

补码:1111 1111 1111 1111 1111 1111 1111 0110

<<(左移)

就是把一个二进制数整体向左移动, 舍弃超出的部分,在移动的空白处加0。

比如:00000000000000000000000000000011向左移动一位就是:

00000000000000000000000000000110

>>(右移)

把一个二进制整数向右移动,舍弃超出的部分,但在空白的最高位应该加什么呢?

这里有两种情况:

1.算数右移:右边丢弃,左边补原来的符号位

2.逻辑右移:右边丢弃,左边补0

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

我们可以举一个代码来证明:

#include<stdio.h>

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

	return 0;
}

a = -15(1000 0000 0000 0000 0000 0000 0000 1111) 原码

1111 1111 1111 1111 1111 1111 1111 0000反码

1111 1111 1111 1111 1111 1111 1111 0001补码

当15向右移一位 

算数右移:1111 1111 1111 1111 1111 1111 1111 1000(-8)

逻辑右移:0111 1111 1111 1111 1111 1111 1111 1000  (8)

运行程序:

所以右移采用的是算数右移,左移不牵扯这样的事。 

不要采用稀奇古怪的左右移方式:a << -1; b >> -3; 这样的方式虽然编译器不会报错,但是是一种标准为定义的行为。


位操作符

&     //按位与

|      //按位或

^     //按位异或

他们的操作数是整数

让我们来认识一下他们怎么用:

int main(void)
{
	int a = 3;//补码:00000000000000000000000000000011
	int b = 5;//补码:00000000000000000000000000000101
	int c = a & b; &--对应二进制位有0则0,同时为1则为1
	printf("%d\n", c);
	c = a | b;     |--对应二进制有1则1,同时为0则为0
	printf("%d\n", c);
	c = a ^ b;     ^--对应二进制位两个相同则为0,两个不同则为1
	printf("%d\n", c);
	return 0;
}


赋值操作符(=)

赋值操作符可以将一个之前不满意的值进行替换,也就是重新赋值。

int high = 175;//不满意现在的身高

high = 188;//重新赋值

赋值操作符也可以连续使用,比如:

int  a =10;

int b = 0;

int y = 20;

a = b = c + 10;但是可读性很差

复合赋值符号

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

比如x = x + 10:可以写做 x += 10;


单目操作符(只有一个操作数)

!            逻辑反操作

-              负值              

+             正值

&             取地址

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

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

--             前置、后置--

++            前置、后置++

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

(类型)       强制类型转换

 !:一般把逻辑判断的答案取相反的,比如在if while语句中的判断条件。

int main(void)
{
	int flag = 0;
	if (!flag)
		printf("haha\n");

	return 0;
}

flag = 0; if(flag)相当于if(0)条件为假,但加上!就相当于条件为真,打印haha。 

&和*应用于指针,&为取地址操作符。*为解引用操作符,引用指针指向变量,引用其实就是引用该变量的地址,解就是把该地址对应的东西打开。

int main(void)

{
	int a = 10;
	int* p = &a;
	printf("%d\n", *p);
	return 0;
}

sizeof 不是函数,是操作符,计算的是类型创建变量的大小,单位是字节

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

	return 0;
}

 ~:按二进制补码进行取反

int main(void)
{
	int a = 0;
	printf("%d\n", ~a);
//00000000000000000000000000000000   0的补码
//11111111111111111111111111111111   按位取反
//11111111111111111111111111111110   反码
//10000000000000000000000000000001   -1
	return 0;
}

前置、后置++:前置++就是先给变量加1在使用此值,后置++就是先使用此值在给变量加1

前置、后置--:前置--就是先给变量减1在使用此值,后置--就是先使用此值在给变量减1

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

第一个打印先打印a的值在给a+1;a就成了2,第二个打印是先b+1再打印,b最开始等于1,所以b+1 = 2,应打印2。

(类型)强制类型转换:把一个类型数据强制转换成另一个类型的数据,多用于将浮点数转换为整数。

nt main(void)
{
	int a = (int)3.14;

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

 3.14本来是个浮点数,不能将其放在整型变量中去,但将其强制类型转换就可以放入整型变量中去,但是会丢失原来的精度,将3.14打印出3。


关系操作符 

用来做两种相同类型变量的比较的

>

>=

<

<=

!=         用于测试“不相等”

==        用于测试“相等”


逻辑操作符

 &&           逻辑与       (并且)

  ||             逻辑或         (或者)

举个通俗易懂的例子:

班长和副班长今天都必须来教室(&&)

班长或副班长今天有一个来教师就行(||)

int main(void)
{
	int a = 0;
	int b = 0;
	if (a == 0 && b == 0)
		printf("haha\n");
	if (a == 0 || b == 0)
		printf("hehe\n");
	return 0;
}

 第一个if必须a 和b都为0才打印haha,而第二个if是a或者b只有一个为0就打印hehe。

||逻辑或操作符在执行时,当第一个条件已经满足时就不会对后面的条件进行判断。

&&逻辑与操作符在执行时,当第一个条件不满足时也就不会对后面的条件进行判断。


条件操作符

exp1  ?  exp2  :  exp3

条件操作符也被称为三目操作符,有三个操作数。

以表达式1为判断标准,如果表达式1为真,那就执行表达式2,相反如果表达式1为假,那就执行表达式3。

int main(void)
{
	int a = 0;
	int b = 0;
	if (a > 5)
		b = 3;
	else
		b = -3;
	printf("%d", b);

	return 0;
}

 这个if可以用条件操作符代替

int main(void)
{
	int b = 0;
	b = (b > 5) ?  3 : -3;
	printf("%d", b);
	return 0;
}

逗号表达式

exp1, exp2, exp3, ...expn

逗号表达式就是用逗号隔开的多个表达式,从左到右依次执行。整个表达式的结果是最后一个表达式的结果。

举个例子:

int main(void)
{
	int a = 1;
	int b = 2;
	int c = (a > b, a = a + 10, b = a + 1);
	printf("%d", c);
	return 0;
}

这个代码中的c是多少呢?我们来分析一下,a>b是一个判断表达式,无实际赋值。a=a+10,证明a = 11。b = a + 1就相当于b = 12,然后将逗号表达式的最后一项赋值给c,所以c就是12。


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

1.[ ] 下标引用操作符

操作数:一个数组名+一个索引值

int arr[10];//创建数组

arr[9] = 10;//实用下标引用操作符

[ ] 的两个操作数就是arr和9

2()函数调用操作符

接受一个或多个操作数:第一个操作数是函数名,剩余的操作数是传给函数的参数。

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

int main(void)
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int c = add(a, b);
	printf("%d\n", c);
	return 0;
}

 这个简单的程序就使用了函数调用操作符add(a, b),有三个操作数add函数名、a、b。

3.结构成员操作符

结构成员操作符在结构体中会用到,分别为.和->操作符。

.     结构体.成员名

->   结构体指针->成员名

struct Book
{
	char name[30];
	float p;
};
int main(void)
{
	struct Book b1 = { "C语言", 55.5f };
	printf("%s %.1f\n", b1.name, b1. p);
	return 0;
}

使用.可以访问结构体中的数据。

struct Book
{
	char name[30];
	float p;
};
void print(struct Book* pp)
{
	printf("%s %.1f\n", pp->name, pp->p);
}
int main(void)
{
	struct Book b1 = { "C语言", 55.5f };
	print(&b1);
	return 0;
}

当用到指针指向结构体时,可以使用->访问结构体中的数据。

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W…Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值