C语言操作符详解

4 篇文章 0 订阅

c语言提供了各种各样的操作符,可大致分为以下类型:

1. 算术操作符      
2. 移位操作符            
3. 位操作符                    
4. 赋值操作符
5. 单目操作符
6. 关系操作符
7. 逻辑操作符
8. 条件操作符
9. 逗号表达式
10. 下标引用
11. 函数调用和结构成员


一:算术操作符

算术操作符大家都很熟悉,只需注意以下几点即可:
1. 对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
2. %操作符的两个操作数必须为整数。


二:移位操作符

移位操作符分为左移右移右移又分为逻辑右移和算术右移,为啥要分成这两种呢,因为在右移过程中左边到底是补0还是补符号位,所以有了逻辑和算术右移,那怎样来具体使用哪种呢,这里是没有办法的,右移取决于你的编译器,具体哪种你可以用自己编译器试试。(注意:目前基本上所有编译器都是算术右移,想想也只有算术右移更合理嘛)

注意:某一个数在只进行移位操作时不会改变本身的值。(例如:a<<1,单单这一条语句a的值没发生任何变化;a = a<<1,a才得到了它左移一位的值)

举例:

int a = -1;
a = a >> 1;
printf("%d", a);
return 0;

来做个简单的分析:
提示:所有数在计算机中都是以补码的形式储存,所以移位操作也是在补码的形式上进行的。
-1的源码为(32位编译器):1000 0000 0000 0000 0000 0000 0000 0001
-1的
反码为(32位编译器):1111  1111  1111  1111  1111  1111 1111  1110   (源码基础上符号为不变,其余位取反
-1的
补码为(32位编译器):1111  1111  1111  1111  1111  1111 1111  1111    (反码基础上加一
右移一位,左边补上符号为:1111  1111  1111  1111  1111  1111 1111  1111 
这是补码,我们再反转回去变到源码,再输出,结果为:

这只是移位操作最基础的知识,移位再结合其他运算可以解决很多问题,后面我们具体分析。


三:位操作符

位操作符有:
按位与(&):都为一为一,否则为0
按位或(|):都为零为零,否则为一
按位异或(^):相同为零,不同为一

实例1:交换两个数,不创建临时变量(直接上代码)

int a = 1;
int b = 2;
a = a^b;
b = a^b;
a = a^b;

记忆技巧a^b相当于一个中间转换站,谁和它异或就会得到另一个数

实例二:找出数组:123452345中唯一单的那个数

解:将所有数字异或在一起,结果就是那个单的数


四:单目操作符

!           逻辑反操作  (对一个数的所有二进制位取反)
-           负值          
+           正值
&           取地址

sizeof      操作数的类型长度(以字节为单位)
~           对一个数的二进制按位取反
--          前置、后置-
++          前置、后置++
*           间接访问操作符(解引用操作符)

(类型)       强制类型转换

这里面很多大家都常见,sizeof出现在这里有没有很意外?对,他就是个操作符,不是个函数,下面一段代码可以细细品尝,运行结果已经写在上面:

        int a = 1;
	char b = 1; 
	char c = 10;
	printf("%d\n",sizeof a);    //4   一方面证明了sizeof不是函数,所以后面可以没有() 
	//printf("%d",sizeof int);   //错误语句     当后面是类型时必须加() 
	printf("%d\n",sizeof (int));   //4 
	printf("%d\n",sizeof (c=b+3));   //1 
	printf("%d\n",c);    //10    证明了sizeof不是函数,不会计算出结果 

再介绍一个奇怪的题(不必过于纠结,不同编译器可能会出现不同的值,我的DEV运行结果为十)

	int i = 1;
	int ret = (++i) + (++i) +(++i);
	printf("%d\n",ret);
	printf("%d",i);

 


 五:逻辑操作符

逻辑操作符分为: 逻辑与 &&          逻辑或 ||
具体需要注意的地方,我们来看一个典例:

	int i = 0;
	int a = 0;
	int b = 2;
	int c = 3;
	int d = 4;
//	i = a++ && ++b && d++;
//	printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);   //1 2 3 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;

可以看到逻辑与与逻辑或满足短路原则,左边表达式的真与假可决定右边是否再执行。


六:条件操作符

exp1  ?  exp2  :  exp3
实用代码:

        int a = 2;
	int b = 5;
	int max = a>b?a:b;
	printf("max=%d\n",max);
	return 0;

该程序一目了然,实现了两个数求较大值,当然也可以求较小值;
 


七:逗号表达式

exp1,  exp2,  exp3,  …expN
逗号表达式遵循从左向右依次执行最终结果取决于最右边的表达式;
下面看一段代码,结果在注释里:
 

        int a = 1;
	int b = 2;
	int c = (a>b, a=b+10, a, b=a+1);  
	printf("c=%d\n",c);   //13
	
	if (a>100, b>0, a>10)         //此时a的值为12 
	printf("yes\n");   //会输出yes 
	return 0;

 注意:逗号表达式取决于最右边,但左边的都会依次执行   ?


八:下表引用操作符

符号为:[ ]
大家对这个符号很熟悉吧,在数组里经常用到它,例如a[3],因为它是个操作符,所以也可写成3[a],但最好不要这样写,大大降低了程序的可读性。

 


九:访问一个结构的成员

访问一个结构体成员有两种方式:
1.   . 操作符       结构体.成员名
2.  ->操作符       结构体指针->成员名

看一段例程代码:

#include<stdio.h>
#include<string.h>
struct stu
{
	int age;
	char name[20];
	char sex[5];	
};
int main()
{
	struct stu student;
	struct stu* pstu = &student;
	student.age = 20;
	strcpy(student.name , "zhangsan");
	strcpy(student.sex , "男");
	printf("%s\n",student.name);    //直接引用 
	printf("%s\n",pstu->name);   //指针引用 
	return 0;
}

 当结构体作为函数传参时,我们最好用结构体指针作为形参,在函数内用->来调用成员,因为如果用结构体名作为形参,这样函数传参时会把结构体所有内容都拷贝一份,如果结构体内容很大,则会浪费许多空间,降低运行效率;




 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值