操作符,详细讲解

简介: 操作符,详细讲解

操作符分类:

🦎算术操作符

>>    +   -    *    /    %    <<

>>注意<<

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


🐊位移操作符

这里我们来讲一下整数的二进制位的相关知识:
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);
}


相关文章
|
1月前
|
存储 C++
C/C++中位操作符(&,|,^,~)的详解使用
C/C++中位操作符(&,|,^,~)的详解使用
|
8月前
|
编译器 C语言 索引
操作符详解下(非常详细)
操作符详解下(非常详细)
30 0
|
28天前
|
存储 程序员 C语言
操作符详解1(二)
该内容是一个关于C语言操作符和结构体的教程摘要。首先提到了加法操作符`+`的使用,并给出了一种不使用临时变量交换两个数的方法。接着讨论了如何计算整数的二进制表示中1的个数,通过位操作符实现。然后介绍了逗号表达式和函数调用操作符`()`,以及结构体成员访问操作符`.`和`-&gt;`,用于访问和修改结构体内的成员变量。文章以讲解结构体的声明、初始化和通过指针访问结构体成员为重点,展示了如何直接和间接地操作结构体数据。
22 0
|
28天前
|
存储 C语言
操作符详解2(一)
C语言操作符具有优先级和结合性,决定表达式求值顺序。优先级高的运算符先执行,相同优先级时看结合性,左结合从左到右,右结合从右到左。例如,3+4*5中乘法优先级高于加法,5*6/2中乘法和除法优先级相同,但都是左结合,所以先计算5*6。圆括号具有最高优先级,可改变其他运算符优先级。表达式求值时,整型运算以缺省整型精度进行,小整型值会被提升为int或unsigned int。正数提升时高位补0,负数提升时高位补1,无符号整型提升始终补0。
29 0
|
1月前
|
C语言 C++
操作符详解
操作符详解
20 0
|
10月前
|
C语言 索引
【C】操作符详解
今天给大家带来一篇关于C语言操作符的详细介绍,在C语言中操作符主要有以下几种:
|
10月前
操作符详解(一)
操作符详解(一)
62 0
|
10月前
|
存储 C语言 C++
S5——C操作符详解,你都知道吗? 上
讲解主要内容: 1. 各种操作符的介绍 2. 表达式求值 以下让我们开始正式重新认识和理解操作符吧!
|
11月前
|
存储
|
存储
操作符(详解)
操作符(详解)
121 0