操作符,详细讲解

简介: 操作符,详细讲解

操作符分类:

🦎算术操作符

>>    +   -    *    /    %    <<

>>注意<<

  • 除了 % 以外,其他操作符都可以作用于整数和浮点数。
  • 对于 / 操作符如果两个数都是整数,执行整数除法。但是只要有一个数是浮点数,就执行小数除法。
  • % 操作符的两个操作数必须是整数。返回的是整除之后的余数。


🐊位移操作符

这里我们来讲一下整数的二进制位的相关知识:
1)整数进制的表示:
  • 我们以12为例
    二进制: 00000000 00000000 00000000 00001100
    八进制: 14
    十进制: 12
    十六进制: c
二进制中(从左往右数)第一位是符号位,若为1,则该数十进制数为负,反之;

>> 在十六进制中0 ~ 9之后,a ~ f 分别表示10 ~ 15 <<

2)进制的相互转化:

谈到进制转化,涉及到 权重问题

  • 权重问题
  • 基数
    -数码的个数。比如二进制数的基数为2。十进制数的基数为10。十六进制数的基数为 16。
  • 位权

位即位置、权即是权重,数字中每一个位置对应的单位值称为位权,也就是不同进制里的“1”在不同的位置上所代表的值。

例如 十进制第2位的位权为101,第3位的位权为102;而二进制第2位的位权为21,第3位的位权为22。那么我们可以得出,某位置上的数码对应的值等于数码乘以位权。

可以这样去理解:位权是数码在某个位置上的步进,在不同位上步进大小不一样,高位大低位小。


  • 我们还是以12为例

二进制转换为十进制:

这里只是简单介绍下,具体多进制转换方法,我会出一篇博客的,博客出来后,这里会有超链接直通车----->《 进制转换,详解

三码(原码、反码、补码)
  • 原码: 按照一个数的正负,直接写出它的二进制表示形式得到的就是原码
  • 反码: 是原码的符号位不变,其他位按位取反,就是反码
  • 补码: 是反码+1
  • 正数
    正数的原码、反码、补码是相同的
  • 负数
    负数的原码、反码、补码要经过计算的

整型占4个字节(32bit)

  • 正数
    正数的原码、反码、补码是相同的
    int a = 10;

00000000000000000000000000001010 - 原码

00000000000000000000000000001010 - 反码

00000000000000000000000000001010 - 补码

  • 负数
    负数的原码、反码、补码要经过计算的
    int b = -10;

10000000000000000000000000001010 - 原码

11111111111111111111111111110101 - 反码

11111111111111111111111111110110 - 补码

负数三码转换:


>> 好了,接下来就开始进入位移操作符的介绍了<<

<< 左移操作符   >>  右移操作符


注意:

1.这里移动的是二进制位(补码);

2.移位操作符的操作数只能是整数;

<< 左移操作符

  • 运算规则:
    左边舍弃,右边不0;
    a = 10; b = a << 1;

a << 1表示a的二进制数向左移动一位:

00000000000000000000000000001010 ------> 00000000000000000000000000010100

此时表达式a<<1就变成了20;但是a的值并没有发生任何变化。

  • 右移效果
    右移n位,就有原始值 / 2^n^ 的效果


🦖位操作符

位操作符:

& //按位与 >> 0是老大<<

| //按位或 >> 1是老大<<

^ //按位异或 >> 同0异1<<

注意:他们的操作数必须为整数。


这里我们就用代码来浅浅演示下吧

#include<stdio.h>
int main()
{
  int num1 = 1;//00000000 00000000 00000000 00000001
  int num2 = 2;//00000000 00000000 00000000 00000010
  printf("%d\n", num1 & num2);
  //按位与“0是老大”==“有0则0,两个为1才为1”
  //00000000 00000000 00000000 00000001
  //00000000 00000000 00000000 00000010
  //00000000 00000000 00000000 00000000 --->按位与后的结果0

  printf("%d\n", num1 | num2);
  //按位或“1是老大”==“有1则1,两个为0才为0”
  //00000000 00000000 00000000 00000001
  //00000000 00000000 00000000 00000010
  //00000000 00000000 00000000 00000011 --->按位或后的结果3
  printf("%d\n", num1 ^ num2);
  //按位异或 相同为0,相异为1;
  //00000000 00000000 00000000 00000001
  //00000000 00000000 00000000 00000010
  //00000000 00000000 00000000 00000011 --->按位异或后的结果3
  return 0;
}


好,这里我们再来看一道比较变态的面试题吧

题目要求:在不使用临时变量的条件下,完成两个数的交换。

  • 解答过程:
#include<stdio.h>
int main()
{
   int a = 5, b = 3;
   a = a ^ b;----->a=a^b
   b = a ^ b;----->b=a^b=a^b^b=a
   a = a ^ b;----->a=a^b=a^b^a=b
   printf("a = %d b = %d", a, b);
   return 0;
}

这里涉及到异或的一些结论:

  1. a^a=0;
  2. a^0=a;
  3. 异或是支持交换律的;

我们带着结论再回去看看是不是了解了。

· 这里也存在几个缺点:

a 只能用于整数交换

b 效率真的不太高

c 不容易读懂

所以它仅仅是面试官的特异照顾。。。。

🐲赋值操作符

赋值操作符我们想必已经相当了解了,所以这里我就浅浅介绍几下它的细节吧

  1. 连续赋值

a=x=y-1------>这种赋值重点考虑它的顺序——>从右至左。

  1. 复合赋值符:

+=

-=

*=

/=

%=

‘>>=’

<<=

&=

|=

^=

这些都存在复合的效果就拿其中一个举例子吧

+= ------->它表示的是先自加再赋值-----> a+=2---->a=a+2;

其他符号也是同理,这里就不过度赘述了

🐢单目操作符

! --------> 逻辑反操作

– -- -------->前置、后置-- –

++ -------->前置、后置+ +

& --------> 取地址

sizeof --------> 操作数的类型长度

星号* --------> 间接访问操作符(解引用操作符)

(类型) --------> 强制类型转换

讲解下sizeof吧

输入形式:

sizeof(a)

sizeof a ------>括号可去掉

sizeof(int)----->这里的括号不能去除

讲解下 – -- , + +吧

int a=10; int y=a++; int x=++a;

主要讲解前置和后置

++前置:

先使用a,再让a增加

---->所以这里y的值为10,a的值为11;


++后置

先让a增加,再使用a

---->所以这里x的值为11,a的值为11


🦖关系操作符

—> > -----------大于号

—> >= ---------大于等于号

—> < -----------小于号

—> <= ----------小于等于号

—> == ----------相等(等号)

—> != -----------不相等

这里重点注意敲代码过程中‘=’与‘= =’的区分

🐍逻辑操作符

&&------>逻辑与----->一假全假

|| ------>逻辑或----->一真全真

判断为真,整体值为1;

判断为假,整体值为0;


这里我们就举一个360面试题:

#include<stdio.h>
int main()
{
  int i = 0, a = 0, b = 2, c = 3, d = 4;
  i = a++ && ++b && d++;
  ------> 答案: 1 2 3 4
  或许,大家看到这个大那有些惊讶。是的我也惊讶。我们来细细看一下吧
  ------>这里是存在电脑短路(就是电脑很懒)a++先使用a=0;被判断为假,&&一假则假----->所以整体判断就一定是假了,所以就相当于把后面的表达式屏蔽了。
  我们就知道了,&&,||,具有控制求值顺序的性质
  //i = a++ && ++b && d++;
  ------> 答案: 1 3 3 4
  printf("a = % d, b = % d, c = % d, d = % d", a, b, c, d);
  return 0;
  
}


🦕条件操作符

  • exp1?exp2:exp3
    ------>解析:exp1表达式1成立?
    ------>成立整体的值就是exp2的结果
    ------>否则就是exp3

逗号表达式

  • 逗号表达式,就是用逗号隔开几个表达式。
    从左向右依次运算。整体的结果为最后一个表达式的结果。

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

  1. []下标引用操作符:一个数组名+一个索引值;
  2. ()函数调用操作符:函数名+其余传给函数的参数;
  3. 访问一个结构的成员:
  1. 结构体-----自定义类型(聚合类型)
    生活中有些对象要被描述出来的话,不能简单的实用内置类型表示。

. --------> 结构体.成员名

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

#include<stdio.h>

struct Book
{
  char name[20];
  char auther[30];
  int price;
};
void print(struct Book* p)
{
  printf("《%s》 %s %d", p->name, p->auther, p->price);
  //结构体指针->成员名
}

int main()
{
  struct Book b1 = { "高等数学","某某",99 };
  printf("《%s》 %s  %d\n", b1.name, b1.auther, b1.price);
  //结构体变量.成员名
  print(&b1);
}


相关文章
|
存储 索引
【操作符】
【操作符】
41 0
|
编译器 C语言 索引
操作符详解下(非常详细)
操作符详解下(非常详细)
46 0
|
30天前
操作符详解
操作符详解
8 0
|
4月前
|
SQL 数据库
IN 操作符
【7月更文挑战第15天】IN 操作符。
40 4
|
6月前
|
存储 编译器
操作符详解1(一)
本文介绍了编程中的操作符分类和位操作,包括算术操作符(如 +, -, *, /, %)、移位操作符(<<, >>)、位操作符(&, |, ^)、赋值操作符、单目操作符、关系操作符、逻辑操作符和条件操作符。还讨论了原码、反码和补码的概念,以及左移(<<)和右移(>>)操作符的工作原理,包括逻辑右移和算术右移的区别。最后提到了位操作符按位与(&)、按位或(|)、按位异或(^)和按位取反(~)的运算规则。
41 1
|
6月前
|
存储 C语言
操作符详解2(一)
C语言操作符具有优先级和结合性,决定表达式求值顺序。优先级高的运算符先执行,相同优先级时看结合性,左结合从左到右,右结合从右到左。例如,3+4*5中乘法优先级高于加法,5*6/2中乘法和除法优先级相同,但都是左结合,所以先计算5*6。圆括号具有最高优先级,可改变其他运算符优先级。表达式求值时,整型运算以缺省整型精度进行,小整型值会被提升为int或unsigned int。正数提升时高位补0,负数提升时高位补1,无符号整型提升始终补0。
50 0
|
编译器
详解操作符(下)
详解操作符(下)
|
Linux C++ 索引
操作符详解(二)
操作符详解(二)
90 0
|
存储 编译器 C语言
7.27C语言知识点之操作符
7.27C语言知识点之操作符
56 0