【从饮水机到名人堂之c语言】详解操作符(2)

文章详细介绍了C语言中的赋值操作符,包括复合赋值符的使用,以及单目操作符如逻辑非、负值、正值、取地址、解引用、sizeof、位取反、自增自减等。还讨论了逻辑操作符、条件操作符和逗号表达式的用法,强调了它们在简化代码和控制流程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、赋值操作符

 复合赋值符

二、单目操作符  

1.单目操作符类型

 2.  !逻辑反操作符

2.-负值 +正值 

3.取地址&  解引用*   

4.sizeof操作符

 5.~按位取反操作符

 6.--减减和++加加操作符

7.强制类型转换() 

三、关系操作符 

四、逻辑操作符 

五、条件操作符 

六、逗号表达式 

 

 

 

前言

上一节我们讲解了操作符的第一部分,即算术操作符,移位操作符和位操作符,接下来我们来学习操作符的第二部分。


 

一、赋值操作符

赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。
例如:
int main() {
	int a = 0;
	a = 10;
	printf("%d", a);
	return 0;
}

初始化a=0,当我们想改变a的值时,我们可以通过复制操作符来改变它。

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

 复合赋值符

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

这些运算符都可以进行复合复制,例如:

a=a+1;

a+=1;

a++;

这三种表达形式都是正确的,在我们写代码的过程中,合适的用上复合复制操作符有助于简化我们的代码。 


 

二、单目操作符  

1.单目操作符类型

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

 2.  !逻辑反操作符

逻辑反操作符就是代表过来,的意思,在我们的C语言中有一种bool类型,false代表假,而true代表真,一个数为0时为假,非0时为真,一个负数也为真,只要不为0就为真。

下边一个例子来说明逻辑反操作符:

int main() {
	int a = 0;
	if (a) {
		printf("a\n");
	}
	if (!a) {
		printf("!a\n");
	}
	return 0;
}

 

2.-负值 +正值 

负值,正值这两个操作符可以改变数值的正负号,由于正号并不会对数值产生实质性的影响,平时我们将这个正号省略,想要改变数值的正负时,加上一个负号“-”。

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

可见,负号可以改变数字的正负,而正号不会产生影响。 

3.取地址&  解引用*   

取地址操作符在我们的函数和指针中很常见,如果我们定义了一个变量,内存为它分配了空间,它有了自己的地址,我们想要得到这个地址时,我们就可以通过取地址操作符来获得地址。

 

int main() {
	int a = 0;
	int* pa = &a;
	printf("%p", pa);
	return 0;
}

 

 

而解引用操作符相反,当我们得到一个地址,我们就可以通过解引用来获得这个地址所对应的元素,在我们前边的传值调用和传址调用中我们已经有所涉及,传递过去的是地址,通过地址解引用获得对应的元素来进行操作。

 

int main() {
	int a = 0;
	int* pa = &a;
	*pa = 10;
	printf("%d", a);
	return 0;
}

 我们得到变量a的地址时,我们可以通过解引用来改变a的值。

4.sizeof操作符

sizeof操作符可以计算出该类型元素所占字节的大小,如:

int main() {
	int a = 0;
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof a);
	//printf("%d\n", sizeof int);这种写法不行
	return 0;
}

我们也要记得sizeof()内表达式不计算,例如:我们在sizeof(),在操作符内部计算b的值,b并不会发生变化。

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

 

 同时,sizeof关键字可以计算出数组中元素的个数,在数组arr中,sizeof(arr)/sizeof(arr[0])可以计算出arr数组中元素的个数。

int main() {
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int num = sizeof(arr) / sizeof(arr[0]);
	printf("%d", num);
	return 0;
}

 5.~按位取反操作符

~按位取反操作符也是对二进制序列进行操作,我们前边学了数据在内存中是通过补码的形式存储的,这个操作符就是对二进制的每一位进行取反操作,0改为1,1改为0。

例如:

-1的补码为1111 1111 1111 1111 1111 1111 1111 1111

取反后    0000 0000 0000 0000 0000 0000 0000 0000

由于正数原码和补码相同,所以-1按位取反后得到的数为0

int main() {
	int a = -1;
	int b = ~a;
	printf("%d", b);
	return 0;
}

 

 6.--减减和++加加操作符

 通过--和++操作符我们可以完成自减或者自加的目的,自减或者自加也分为前置和后置,前置代表先自减或者自加后使用,而后置代表自减或者自加前就使用。

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

 

可以看到,前置是先加后使用,而后置是先使用后加。

7.强制类型转换() 

在我们的代码中,有时候会有类型改变的情况,当我们需要进行数据类型的改变时,我们可以通过强制类型转换来实现。

例如:

#include<stdio.h>

int main() {
	float a = 0;
	a = 3.14;
	printf("%d", (int)a);
	return 0;
}

 当我们有一个浮点型的变量,我们需要让他变为整型时,我们可以通过强制类型转换来操作,但是当我们由浮点型转换为整型时,可能存在数据的丢失,编译器会对我们发出警告。

三、关系操作符 

>
>=
<
<=
!=   用于测试 不相等
==       用于测试 相等

关系操作符可以用于判断语句,它与赋值操作符不同,当我们使用if语句时,判断一个数是否大于0,可以写成if(a>0),判断一个数是否等于0,必须写成if(a==0),而不是if(a=0),当写成这样时,if语句判断为假,永远不会执行。


 

四、逻辑操作符 

&&     逻辑与
||           逻辑或
区分 逻辑与 按位与
区分 逻辑或 按位或
 
1 & 2 -----> 0
1 && 2 ----> 1
1 | 2 -----> 3
1 || 2 ----> 1
按位与和按位或时对二进制序列某一位进行操作,而逻辑与与逻辑或则是对数字进行操作,结果只为0或1,0为假,1为真。

我们通过判断闰年的例子可以更好地掌握逻辑与和逻辑或的知识。 

int main() {
	int year = 2022;
	if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){
		printf("%d是闰年\n", year);
	}
	else {
		printf("%d不是闰年\n", year);
	}
	return 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;
}
//程序输出的结果是什么?

 我们看到变量i的值由一串逻辑与操作符复合而成,所以我们要判断a,b,c的值来判断真假,但是我们从左向右计算时,a++的值为0,先使用为0,所以不管后边的数是什么都没有影响,i的值都为0,所以后边的数计算没有了意义,这在C语言中被叫做短路,当我们后边的计算结果对前边的计算结果不产生影响时,我们就不用去计算后边的表达式。

同理在表达式2中,前边的表达式都为真,在逻辑或中,有真就为真,所以d的值就不用计算了。

 

 

通过代码验证我们的结果也是正确的。


 

五、条件操作符 

exp1 ? exp2 : exp3

条件操作符,也被称作三目表达式,有三个语句复合而成,当语句1成立时,执行语句2,反之执行语句3。

我们要找出两个数中最大的数时,我们就可以使用条件操作符。

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


 

六、逗号表达式 

exp1 , exp2 , exp3 , …expN
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式
c是多少?

我们从左向右依次执行,a=12,b=13,故c=b=13。


总结

今天讲解了操作符的第二部分,希望大家能通过操作符来简化代码,以及在使用操作符的过程中注意到一些细节,本文中肯定有很多不足,希望能和大家一起进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

清扰077

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

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

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

打赏作者

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

抵扣说明:

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

余额充值