c语言操作符总结(基础)

操作符分类

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

算术操作符

所有符号:+、-、*、/、%求余运算符
要注意的:

  1. /后不可为0;
  2. %左右必须是整数
  3. 当/两边有一个类型高于另一个,会隐式升级类型 // 比如有浮点型和整形,就会转换成浮点型的结果。

移位运算符

所有符号:>> 右移操作符、<<左移操作符
移位运算符顾名思义就是对二进制位进行移动操作。其中移位主要有两种移位方式。
1、逻辑移位
逻辑移位是指逻辑左移和逻辑右移,移出的空位都用0来补,移出去的抛弃。
2、算数移位
算术移位 就需要分有符号型值和无符号型值
对于无符号型值,算术移位等同于逻辑移位。
而对于有符号型值 ,算术左移等同于逻辑左移,算术右移补的是符号位,正数补0,负数补1。如下图所示
在这里插入图片描述

位操作符

 
所有符号:&  //按位与
      |  //按位或
      ^  //按位异或
举几个简单的例子就能明白这三个操作符的意义
1、按位与&   0&0=0;  0&1=0;  1&0=0;  1&1=1
例子:11&6: 0000 1011 & 0000 0110 = 0000 0010 = 2
与运算”的一些用途:
(1)清零。如果想将一个值清零,只需要令这个值与二进制位全为0(即0)的数进行与运算,那么得到的值就是0;
(2)取一个数的二进制序列中指定位的值
方法:首先确定要取位置,然后令和他与运算的数的位置为1,其他置为0。在进行与运算,得到的结果就是取我们需要的值。(看下面例子能更直观)
例:有一个数的二进制序列为1011 0110,
取X的高四位,用 这个数(即1011 0110) & 11110000= 10110000即可得到;
 
2、按位或|  0|0=0;  0|1=1;  1|0=1;  1|1=1
例子:11|6: 0000 1011 & 0000 0110 = 0000 1111= 15
即有真则为真
或运算”的一些用途:
(1)常用来对一个数据的某些位置1。
方法:找到一个数X,对应X要置1的位,取该数的对应位为1,其余位为零。此数与之相或可使X中的某些位置1。
例:将X=10100000的低4位置1 ,用 X | 0000 1111 = 1010 1111即可得到。
 
3、按位异或^  0^0=0;  0^1=1;  1^0=1;  1^1=0
例子:11|6: 0000 1011 ^* 0000 0110 = 0000 1101= 13
即不一样则为真,一样为假
异或运算”的一些用途:
(1)1)使特定位翻转 找一个数。
方法:对应X要翻转的位,该数的对应位为1,其余位为零,此数与X对应位异或即可。
例:将X=10100001的低4位翻转 ,用 X ^ 0000 1111 = 1010 1110即可得到。
(2)与0相异或,保留原值 ,
例:X ^ 0000 0000 = 1010 0001。
(3)交换a和b

//不能创建临时变量(第三个变量),实现两个数的交换。
#include <stdio.h>
 int main() 
 {   
 	 int a = 10;    
 	 int b = 20;   
  	 a = a^b;    
 	 b = a^b;    
 	 a = a^b;    
  	 printf("a = %d  b = %d\n", a, b);    
  	 return 0;
 }

赋值操作符

符号:=
它的功能就是给一个变量赋值,他的优先级别低于其他的运算符,所以对该运算符往往最后读取。
**需要了解的:**复合赋值符

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

复合运算符的目的是减少书写,更加简洁,举个例子

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

单目操作符

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

用一个代码理解前面四个符号

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

sizeof运算符
作用:sizeof运算符能计算一个变量或者一个类型的字节长度
需要注意的:
1、sizeof是运算符不要和函数混淆;例如

#include<stdio.h>
int main()
{
 int a=0;
  printf("%d\n", sizeof a);//这样写行不行?    
  printf("%d\n", sizeof int);//这样写行不行? 
  return 0;
  //第一种写法可以,但是第二种不行。
  //第一种写法就说明sizeof不是函数,函数需要函数调用符()。
  }

2、sizeof与数组
sizeof可以计算数组中元素数目的多少
方法:

sizeof(数组名)/sizeof(数组首元素)

前面会算出整个数组中\0前的字节长度,数组的字节长度等于数组元素类型字节长度乘数组元素个数,因此除数组首元素的长度就能得到数组元素个数(俗称数组长度)
需要注意,当我们向函数传递数组名,需要用到数组长度时,不能在函数内部算出此长度,必须将长度也传进函数。因为这时候的数组名代表的只是一个地址,并不代表整个数组。

++ - -运算符
运用方法

 #include <stdio.h>    
 int main()    
 {       
 int a = 10;        
 int x = ++a;        
 //先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。
 //x为11。        
 int y = --a;        
 //先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。
 y为10;        
  a = 10;        
  x = a++;        
  //先对a先使用,再增加,这样x的值是10;之后a变成11; 
   y = a--;        
  //先对a先使用,再自减,这样y的值是11;之后a变成10;
  return 0;  	
  //这就是前置和后置的区别
  }

* 间接访问操作符(解引用操作符)
用于对地址解引用,间接访问是相对于直接访问而言的,比如

int a = 1 ;
a = a + 1 ; //这就是直接访问a,因为用的是变量a本身

int b = 2 ;
int* p = &b ; 
*p = 3 ; // 这就是间接访问,用指针p访问b。 

(类型) 强制类型转换
其功能是把表达式的运算结果强制转换成类型说明符所表示的类型,举个例子来了解怎么用

int main()
{
float f=5.75;
printf("f=%d,f=%f\n",(int)f,f);
//运行结果 f=5,f=5.750000
}

关系操作符

所有符号:

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

这些关系运算符比较简单,没什么可讲的,但是我们要注意一些运算符使用时候的陷阱。
警告: 在编程的过程中== 和=不小心写错,导致的错误

逻辑操作符

所有符号:

&&          逻辑与
||          逻辑或

与运算,双目,对应数学中的“且”
或运算,双目,对应数学中的“或”
在编程中,我们一般将零值称为“假”,将非零值称为“真”。逻辑运算的结果也只有“真”和“假”,“真”对应的值为 1,“假”对应的值为 0。
注意:
1、区分逻辑与和按位与,区分逻辑或和按位或

1&2----->0 
1&&2---->1
 
1|2----->3 
1||2---->1 

2、当进行与运算时,如果第一个表达式为假,则不会执行和判断第二个表达式,有假为假。
当进行或运算时,如果第一个表达式为真,则不会执行和判断第二个表达式,有真为真。
举个例子:
360面试题

#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; 
 } //程序输出的结果是什么?

在这里插入图片描述

条件操作符

符号:

条件? 表达式1 : 表达式2

条件运算操作会首先计算条件,然后根据条件的计算结果,再决定要计算两个表达式中的哪一个。
举个例子:找出两个数中的较大值

int iMax(int a, int b) 
{ 
return a >= b ? a : b; 
}
int iMAX2(int a,int b)
{
if (a > =b) 
return a;
else 
return b;
}//这两个函数实现的功能是一样的,但用条件操作符更加简单

逗号表达式

符号:

 表达式1, 表达式2, 表达式3,......表达式N

它将两个及其以上的式子联接起来,从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值。
举个例子:

//代码1
 int a = 1; 
 int b = 2; 
 int c = (a>b, a=b+10, a, b=a+1);//逗号表达式 c是多少?
 
//代码2 
if (a =b + 1, c=a / 2, d > 0)
 
//代码3 
a = get_val(); 
count_val(a); 
while (a > 0)
 {         
 //业务处理        
 a = get_val(); 
 count_val(a); 
 }
 如果使用逗号表达式,改写: 
 while (a = get_val(), count_val(a), a>0) 
 {         
 //业务处理 
 }

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

1.[ ] 下标引用操作符
操作数:一个数组名 + 一个索引值

int arr[10];//创建数组    
arr[9] = 10;//实用下标引用操作符。   
 [ ]的两个操作数是arr和9

2.( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

 #include <stdio.h>    
 void test1()    
 {        
 printf("hehe\n");    
 }    
 void test2(const char *str)    
 {        
 printf("%s\n", str);    
 }   
 int main()   
  {        
  test1();            //实用()作为函数调用操作符。        
  test2("hello bit.");//实用()作为函数调用操作符。        
  return 0;   
   }

3.访问一个结构的成员
.  结构体.成员名
->  结构体指针->成员名

#include <stdio.h> 
struct Stu 
{    
char name[10];    
int age;    
char sex[5];    
double score; 
}void set_age1(struct Stu stu) 
{    
stu.age = 18;
 } 
void set_age2(struct Stu* pStu)
 {    
 pStu->age = 18;//结构成员访问 
 } 
 int main() 
 {    
 struct Stu stu;    
 struct Stu* pStu = &stu;//结构成员访问        
 stu.age = 20;//结构成员访问    
 set_age1(stu);        
 pStu->age = 20;//结构成员访问    
 set_age2(pStu);    
 return 0; 
 }

发布了35 篇原创文章 · 获赞 13 · 访问量 2113

猜你喜欢

转载自blog.csdn.net/weixin_42458272/article/details/89004754