C语言操作符详解

简介: 当我们学习C语言时会遇到许多操作符,在许多语句中都能使用,可以起到举足轻重的作用。不要小看这些操作码,下面让我详细讲解一下操作符。

       当我们学习C语言时会遇到许多操作符,在许多语句中都能使用,可以起到举足轻重的作用。不要小看这些操作码,下面让我详细讲解一下操作符。


操作符有很多:


算数操作符


移位操作符


位操作符


赋值操作符


单目操作符


关系操作符


逻辑操作符


条件操作符


逗号操作符 ......


算数操作符


+    -   *   /   %


这些操作符都是我们经常见到的,如同数学运算符一样,适合于运算。但是算数运算符有一些注意事项:


1.除了%操作符以外,其他的几个操作符可以作用于整数和浮点数。


2.对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行就是浮点数除法。


3.%操作符的两个操作数必须为整数。返回的是整数之后的余数。


4.算数操作符一定在数学知识的基础上进行的。


移位操作符


<<(左移)          >>(右移)    注:移位操作符的操作数只能是整数


移位操作符是基于二进制数的基础上操作的,移动的是二进制的数据。计算机存储的就是二进制的数据由0和1组成的。如:10: 0000 0000 0000 0000 0000 0000 0000 1010,而计算机存储的一般是一个数的补码。正数的原码反码补码都是一样的,而负数的原码得到后将除过符号位(最高位)不变剩下的位数一律取反得到,补码就是反码加1。


移位移动的是补码的二进制序列


例子:-10


原码:1000 0000 0000 0000 0000 0000 0000 1010


反码:1111 1111 1111 1111 1111 1111 1111 0101


补码:1111 1111 1111 1111 1111 1111 1111 0110


<<(左移)


就是把一个二进制数整体向左移动, 舍弃超出的部分,在移动的空白处加0。


比如:00000000000000000000000000000011向左移动一位就是:


00000000000000000000000000000110


>>(右移)


把一个二进制整数向右移动,舍弃超出的部分,但在空白的最高位应该加什么呢?


这里有两种情况:


1.算数右移:右边丢弃,左边补原来的符号位


2.逻辑右移:右边丢弃,左边补0


C语言没有明确规定是算数右移还是逻辑右移,一般编译器上采用的算数右移


我们可以举一个代码来证明:


#include<stdio.h>
int main(void)
{
  int a = -15;
  int b = a >> 1;
  printf("%d\n", b);
  return 0;
}


a = -15(1000 0000 0000 0000 0000 0000 0000 1111) 原码


1111 1111 1111 1111 1111 1111 1111 0000反码


1111 1111 1111 1111 1111 1111 1111 0001补码


当15向右移一位


算数右移:1111 1111 1111 1111 1111 1111 1111 1000(-8)


逻辑右移:0111 1111 1111 1111 1111 1111 1111 1000  (8)


运行程序:


419aee0e22dc458d83ec3dae9949558d.png


所以右移采用的是算数右移,左移不牵扯这样的事。


不要采用稀奇古怪的左右移方式:a << -1; b >> -3; 这样的方式虽然编译器不会报错,但是是一种标准为定义的行为。


位操作符


&     //按位与


|      //按位或


^     //按位异或


他们的操作数是整数


让我们来认识一下他们怎么用:


int main(void)
{
  int a = 3;//补码:00000000000000000000000000000011
  int b = 5;//补码:00000000000000000000000000000101
  int c = a & b; &--对应二进制位有0则0,同时为1则为1
  printf("%d\n", c);
  c = a | b;     |--对应二进制有1则1,同时为0则为0
  printf("%d\n", c);
  c = a ^ b;     ^--对应二进制位两个相同则为0,两个不同则为1
  printf("%d\n", c);
  return 0;
}

9da0c926ca34450e8564006b667dcbf9.png


赋值操作符(=)


赋值操作符可以将一个之前不满意的值进行替换,也就是重新赋值。


int high = 175;//不满意现在的身高


high = 188;//重新赋值


赋值操作符也可以连续使用,比如:


int  a =10;


int b = 0;


int y = 20;


a = b = c + 10;但是可读性很差


复合赋值符号


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


比如x = x + 10:可以写做 x += 10;


单目操作符(只有一个操作数)


!            逻辑反操作


-              负值              


+             正值


&             取地址


sizeof      操作数的类型长度(以字节为单位)


~              对一个数的二进制按位取反


--             前置、后置--


++            前置、后置++


*               间接访问操作符(解引用操作符)


(类型)       强制类型转换


!:一般把逻辑判断的答案取相反的,比如在if while语句中的判断条件。


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


flag = 0; if(flag)相当于if(0)条件为假,但加上!就相当于条件为真,打印haha。


&和*应用于指针,&为取地址操作符。*为解引用操作符,引用指针指向变量,引用其实就是引用该变量的地址,解就是把该地址对应的东西打开。


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


6d6f60ceb2a74eee8ee97746460e624e.png


sizeof 不是函数,是操作符,计算的是类型创建变量的大小,单位是字节


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


~:按二进制补码进行取反


int main(void)
{
  int a = 0;
  printf("%d\n", ~a);
//00000000000000000000000000000000   0的补码
//11111111111111111111111111111111   按位取反
//11111111111111111111111111111110   反码
//10000000000000000000000000000001   -1
  return 0;
}


前置、后置++:前置++就是先给变量加1在使用此值,后置++就是先使用此值在给变量加1


前置、后置--:前置--就是先给变量减1在使用此值,后置--就是先使用此值在给变量减1


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


a72f874c929840569ee3f1327537aaea.png


第一个打印先打印a的值在给a+1;a就成了2,第二个打印是先b+1再打印,b最开始等于1,所以b+1 = 2,应打印2。


(类型)强制类型转换:把一个类型数据强制转换成另一个类型的数据,多用于将浮点数转换为整数。


nt main(void)
{
  int a = (int)3.14;
  printf("%d\n", a);
  return 0;


3.14本来是个浮点数,不能将其放在整型变量中去,但将其强制类型转换就可以放入整型变量中去,但是会丢失原来的精度,将3.14打印出3。


关系操作符


用来做两种相同类型变量的比较的


>


>=


<


<=


!=         用于测试“不相等”


==        用于测试“相等”


逻辑操作符


&&           逻辑与       (并且)


 ||             逻辑或         (或者)


举个通俗易懂的例子:


班长和副班长今天都必须来教室(&&)


班长或副班长今天有一个来教师就行(||)


int main(void)
{
  int a = 0;
  int b = 0;
  if (a == 0 && b == 0)
    printf("haha\n");
  if (a == 0 || b == 0)
    printf("hehe\n");
  return 0;
}


第一个if必须a 和b都为0才打印haha,而第二个if是a或者b只有一个为0就打印hehe。


||逻辑或操作符在执行时,当第一个条件已经满足时就不会对后面的条件进行判断。


&&逻辑与操作符在执行时,当第一个条件不满足时也就不会对后面的条件进行判断。


条件操作符


exp1  ?  exp2  :  exp3


条件操作符也被称为三目操作符,有三个操作数。


以表达式1为判断标准,如果表达式1为真,那就执行表达式2,相反如果表达式1为假,那就执行表达式3。


int main(void)
{
  int a = 0;
  int b = 0;
  if (a > 5)
    b = 3;
  else
    b = -3;
  printf("%d", b);
  return 0;
}


这个if可以用条件操作符代替


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


逗号表达式


exp1, exp2, exp3, ...expn


逗号表达式就是用逗号隔开的多个表达式,从左到右依次执行。整个表达式的结果是最后一个表达式的结果。


举个例子:


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


这个代码中的c是多少呢?我们来分析一下,a>b是一个判断表达式,无实际赋值。a=a+10,证明a = 11。b = a + 1就相当于b = 12,然后将逗号表达式的最后一项赋值给c,所以c就是12。


ee9607ccea3f4e9781d721c4779a04fd.png


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


1.[ ] 下标引用操作符


操作数:一个数组名+一个索引值


int arr[10];//创建数组


arr[9] = 10;//实用下标引用操作符


[ ] 的两个操作数就是arr和9


2()函数调用操作符


接受一个或多个操作数:第一个操作数是函数名,剩余的操作数是传给函数的参数。


int add(int x, int y)
{
  return x + y;
}
int main(void)
{
  int a = 0;
  int b = 0;
  scanf("%d %d", &a, &b);
  int c = add(a, b);
  printf("%d\n", c);
  return 0;
}


这个简单的程序就使用了函数调用操作符add(a, b),有三个操作数add函数名、a、b。


3.结构成员操作符


结构成员操作符在结构体中会用到,分别为.和->操作符。


.     结构体.成员名


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


struct Book
{
  char name[30];
  float p;
};
int main(void)
{
  struct Book b1 = { "C语言", 55.5f };
  printf("%s %.1f\n", b1.name, b1. p);
  return 0;
}


使用.可以访问结构体中的数据。


struct Book
{
  char name[30];
  float p;
};
void print(struct Book* pp)
{
  printf("%s %.1f\n", pp->name, pp->p);
}
int main(void)
{
  struct Book b1 = { "C语言", 55.5f };
  print(&b1);
  return 0;
}


当用到指针指向结构体时,可以使用->访问结构体中的数据。

目录
相关文章
|
4月前
|
存储 C语言 索引
【C语言篇】操作符详解(下篇)
如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。
76 0
|
4月前
|
程序员 编译器 C语言
【C语言篇】操作符详解(上篇)
这是合法表达式,不会报错,但是通常达不到想要的结果, 即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执⾏的是下⾯的表达式。
272 0
|
2月前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
43 10
|
2月前
|
存储 编译器 C语言
【C语言】简单介绍进制和操作符
【C语言】简单介绍进制和操作符
164 1
|
2月前
|
存储 编译器 C语言
初识C语言5——操作符详解
初识C语言5——操作符详解
181 0
|
4月前
|
C语言
C语言操作符(补充+面试)
C语言操作符(补充+面试)
46 6
|
4月前
|
存储 编译器 C语言
十一:《初学C语言》— 操作符详解(上)
【8月更文挑战第12天】本篇文章讲解了二进制与非二进制的转换;原码反码和补码;移位操作符及位操作符,并附上多个教学代码及代码练习示例
60 0
十一:《初学C语言》—  操作符详解(上)
|
5月前
|
C语言
五:《初学C语言》— 操作符
本篇文章主要讲解了关系操作符和逻辑操作符并附上了多个代码示例
44 1
五:《初学C语言》—  操作符
|
6月前
|
C语言
C语言逻辑操作符的短路问题
C语言逻辑操作符的短路问题
|
6月前
|
编译器 C语言
【C语言】:中移位操作符,位操作符详运算规则详解
【C语言】:中移位操作符,位操作符详运算规则详解
47 1