取余运算怎么算_c++ c语言 运算符和类型转换

c 语法5 - 运算符和类型转换

一、算术运算符

运算符描述实例
+把两个操作数相加A + B 将得到 30
-从第一个操作数中减去第二个操作数A - B 将得到 -10
*把两个操作数相乘A * B 将得到 200
/分子除以分母B / A 将得到 2
%取模运算符,整除后的余数B % A 将得到 0
++自增运算符,整数值增加 1A++ 将得到 11
--自减运算符,整数值减少 1A-- 将得到 9

1、加减乘除

和一般的加减乘除无区别,注意输出格式即可,无法除以0

除法运算后得到的结果给整型变量时候,取整数部分

#include 

int main(void){
 int a = 10;
 int b = 20;
 
 printf("a + b = %d\n",a+b);
 printf("a - b = %d\n",a-b);
 printf("a * b = %d\n",a*b);
 printf("b / a = %d\n",b/a);
 return 0;
}

5dba20c10b57f13856b062e9151f61e8.png

2、取余

%就是取余数运算,也就是模运算(mod)。设a,b是两个整数,a%b的结果就就是a÷b得到的余数 例如5%3=2 (商1余2) 9%4=1 (商2余1) 3%7=3 (商0余3)

#include 

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

05a2c16a8fa2c838269379f46c7a550e.png

3、(++)与(- -)

++ 与- -是一对让算数运算方便的自增属性的算术式。

++是自增,分为前缀自增与后缀自增。而- -则是自减,也分为前缀自减与后缀自减。

但是都是等效于

i ++ / ++i ==》 i = i+1

独立式子中,没有区别,但是在与其他表达式结合的时候将发挥作用。

#include 

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

4012c049f46602d81742417533da42df.png

明显可以看出,++a与a++的区别。

二、赋值运算符

赋值运算符代表了在运算结束之后,给予变量一个值。

这里仅展示非位运算的运算符

运算符描述实例
=简单的赋值运算符,把右边操作数的值赋给左边操作数C=A+B将把A+B的值赋给C
+=加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数C+=A相当于C=C+A
-=减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数C-=A相当于C=C-A
*=乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数C* =A相当于 C= C *A
/=除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数C/=A相当于C=C/A
%=求模且赋值运算符,求两个操作数的模赋值给左边操作数C %=A相当于C=C%A
<<=左移且赋值运算符C<<=2等同于C=C<<2
>>=右移且赋值运算符C>>=2等同于C=C>>2
&=按位与且赋值运算符C&=2等同于C=C&2
^=按位异或且赋值运算符C^=2等同于C=C^2
|=按位或且斌值运算符C|=2等同于C=C|2
#include 
int pf(int a,int c){
 printf("a = %d,c = %d\n\n",a,c);
 return 0;
}
int main(void){
   int a = 21;
   int c ;
   printf("Line 1 : =  运算符实例");c =  a;pf(a,c);
   printf("Line 2 : += 运算符实例");c +=  a;pf(a,c);
   printf("Line 3 : -= 运算符实例");c -=  a;pf(a,c);
   printf("Line 4 :*= 运算符实例"); c *=  a;pf(a,c);
   printf("Line 5 : /= 运算符实例"); c /=  a;pf(a,c);
   
   c  = 200;
   printf("Line 6 : %= 运算符实例,c 的原本值 = %d\n", c );c %=  a;pf(a,c);
   printf("Line 7 : <<= 运算符实例,c 的原本值 = %d\n", c );c <<=  2;pf(a,c);
   printf("Line 8 : >>= 运算符实例,c 的原本值 = %d\n", c ); c >>=  2;pf(a,c);
   printf("Line 9 : &= 运算符实例,c 的原本值 = %d\n", c );c &=  2;pf(a,c);
   printf("Line 10 : ^= 运算符实例,c 的原本值 = %d\n", c );c ^=  2;pf(a,c);
   printf("Line 11 : |= 运算符实例,c 的原本值 = %d\n", c );c |=  2;pf(a,c);
}

47213e85f9e565c0f4b76bda2b1df250.png

三、比较(关系)运算符

运算符含  义数学中的表示
<小于<
<=小于或等于
>大于>
>=大于或等于
==判等于=
!=不等于

关系运算符都是双目运算符,其结合性均为左结合。关系运算符的优先级低于算术运算符,高于赋值运算符。在六个关系运算符中,、>=的优先级相同,高于==和!=,==和!=的优先级相同。

#include 
int main(){
    char c='k';
    int i=1, j=2, k=3;
    float x=3e+5, y=0.85;
    int result_1 = 'a'+5-5.25<=x+y;printf( "%d, %d\n", result_1, -i-2*j>=k+1 );printf( "%d, %d\n", 15, result_2 );printf( "%d, %d\n", i+j+k==-2*j, k==j==i+5 );return 0;
}

46d5997f7f3c7c81d2f06faeda0a52e5.png

四、逻辑运算符

一般把0为假,非0为真。计算机里的话则是1一般代表计算机输出的真值

运算符术语实例结果
非(非真为假,非假为真)!a如果a为假,则!a为真;   如果a为真,则!a为假。
&&与(同真为真,有假为假)a&&b如果a和b都为真,则结果为真,否则为假。
||或(有真为真,同假为假)a||b如果a和b有一个为真,则结果为真,二者都为假时,结果为假。

逻辑符非

c#include 

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

f00a11914ecf76d5ca64365cd4cf736b.png

我们可以看到,当a = 10时,!a由于取反,则变成了代表假的0

当b  = 0时,则!b取反则变成了代表真的1

一般情况下,只要是非0即可代表真。

逻辑符与

#include 

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

27e57e9b15126ce5292c5451de795c76.png

由于a=10代表真,b=0代表假,则a&&b代表假

逻辑符或

#include 

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

aa46083dd024dfa8fa3c9fc56fe29782.png

五、位运算符

真值表

pqp & qp | qp ^ q
00000
01011
11110
10011

假设变量 A 的值为 60,变量 B 的值为 13,则:

与运算符&

按位与操作,按二进制位进行"与"运算。运算规则:

0&0=0;   
0&1=0;    
1&0=0;     
1&1=1;

(A & B) 将得到 12,即为 0000 1100

或运算符 |

按位或运算符,按二进制位进行"或"运算。运算规则:

0|0=0;   
0|1=1;   
1|0=1;    
1|1=1;

(A | B) 将得到 61,即为 0011 1101

异或运算符^

异或运算符,按二进制位进行"异或"运算。运算规则:

0^0=0;   
0^1=1;   
1^0=1;  
1^1=0;

(A ^ B) 将得到 49,即为 0011 0001

取反运算符 ~

取反运算符,按二进制位进行"取反"运算。运算规则:

~1=0;   
~0=1;

(~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。

左移运算符 <<

二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。

A << 2 将得到 240,即为 1111 0000

右移运算符 >>

二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。

A >> 2 将得到 15,即为 0000 1111

#include 

int main(void){
   unsigned int a = 60;    /* 60 = 0011 1100 */
   unsigned int b = 13;    /* 13 = 0000 1101 */
   int c = 0;
   c = a & b;       /* 12 = 0000 1100 */
   printf("Line 1 - c 的值是 %d\n", c );
   c = a | b;       /* 61 = 0011 1101 */
   printf("Line 2 - c 的值是 %d\n", c );
   c = a ^ b;       /* 49 = 0011 0001 */
   printf("Line 3 - c 的值是 %d\n", c );
   c = ~a;          /*-61 = 1100 0011 */
   printf("Line 4 - c 的值是 %d\n", c );
   c = a <2;     /* 240 = 1111 0000 */
   printf("Line 5 - c 的值是 %d\n", c );
   c = a >> 2;     /* 15 = 0000 1111 */
   printf("Line 6 - c 的值是 %d\n", c );
}

2f7be6163c8739d0d15de0f0b2d85341.png

六、三目运算符和逗号运算符

三目运算符 ?:

表达式1 表达式2**:** 表达式3

表达式1为一个判别表达式:若表达式1为真,则整个三目运算取值表达式2

若表达式1为假,则整个三目运算取值为表达式3

#include

int main(void){
 int a = 40;
 int b = 50;
 printf("%s",a>b ? "a>b" : "a );return 0;
}

c1c38e59dc800af419c2fbee201c3cad.png

逗号运算符

一般用于连接定义或者声明变量以及连接表达式的运算符。逗号运算符可以结合形成逗号表达式,通过运算之后获取的话会获取到最后一位。

#include

int main(void){
 int a = 40, b = 20, c = 10;    //同时定义三个整型变量
 int x = (a = 4, b = 2, c = 1); //逗号运算符表达式,x获得表达式最后一个值的结果,同时值被改写
 
 printf("X = %d\n", x);
 printf("a = %d\n", a);
 printf("b = %d\n", b);
 printf("c = %d\n", c);
 
 return 0;
}

70ab8ee6cb704ba65be5f125ec2b0567.png

七、运算符优先级

单目运算符:代表运算过程只有一个变量

双目运算符:代表运算过程存在两个变量

以此类推

同一优先级的运算符,运算次序由结合方向所决定。

简单记就是:!> 算术运算符 > 关系运算符 > && > || > 赋值运算符

优先级1

运算符名称或含义使用形式结合方向说明
[]数组下标数组名[常量表达式]左到右
()圆括号(表达式)/函数名(形参表)左到右
.成员选择(对象)对象.成员名左到右
->成员选择(指针)对象指针->成员名左到右
--后置自减运算符--变量名左到右单目运算符
++后置自增运算符++变量名左到右单目运算符

优先级2

运算符名称或含义使用形式结合方向说明
-负号运算符-表达式右到左单目运算符
(类型)强制类型转换(数据类型)表达式右到左
++前置自增运算符变量名++右到左单目运算符
--前置自减运算符变量名--右到左单目运算符
*取值运算符*指针变量右到左单目运算符
&取地址运算符&变量名右到左单目运算符
!逻辑非运算符!表达式右到左单目运算符
~按位取反运算符~表达式右到左单目运算符
sizeof长度运算符sizeof(表达式)右到左

优先级3

运算符名称或含义使用形式结合方向说明
/表达式/表达式左到右双目运算符
*表达式*表达式左到右双目运算符
%余数(取模)整型表达式/整型表达式左到右双目运算符

优先级4

运算符名称或含义使用形式结合方向说明
+表达式+表达式左到右双目运算符
-表达式-表达式左到右双目运算符

优先级5

运算符名称或含义使用形式结合方向说明
<<左移变量<左到右双目运算符
>>右移变量>>表达式左到右双目运算符

优先级6

运算符名称或含义使用形式结合方向说明
>大于表达式>表达式左到右双目运算符
>=大于等于表达式>=表达式左到右双目运算符
<小于表达式左到右双目运算符
<=小于等于表达式<=表达式左到右双目运算符

优先级7

运算符名称或含义使用形式结合方向说明
==等于表达式==表达式左到右双目运算符
!=不等于表达式!= 表达式左到右双目运算符

优先级8~13

优先级运算符名称或含义使用形式结合方向说明
8&按位与表达式&表达式左到右双目运算符
9^按位异或表达式^表达式左到右双目运算符
10|按位或表达式|表达式左到右双目运算符
11&&逻辑与表达式&&表达式左到右双目运算符
12||逻辑或表达式||表达式左到右双目运算符
13? :条件运算符表达式1? 表达式2: 表达式3右到左三目运算符

优先级14

运算符名称或含义使用形式结合方向
=赋值运算符变量=表达式右到左
/=除后赋值变量/=表达式右到左
*=乘后赋值变量*=表达式右到左
%=取模后赋值变量%=表达式右到左
+=加后赋值变量+=表达式右到左
-=减后赋值变量-=表达式右到左
<<=左移后赋值变量<<=表达式右到左
>>=右移后赋值变量>>=表达式右到左
&=按位与后赋值变量&=表达式右到左
^=按位异或后赋值变量^=表达式右到左
|=按位或后赋值变量|=表达式右到左

优先级15

运算符名称或含义使用形式结合方向说明
,逗号运算符表达式,表达式,…左到右从左向右顺序运算

类型转换

数据拥有不同的数据类型,不同数据类型之间进行混合运算必然涉及类型的转换问题。

转换的方法有两种: 自动转换(隐式转换):遵循一定的规则,由编译系统自动完成。 强制类型转换:把表达式的运算结果强制转换成所需的数据类型。

**类型转换的原则:**占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低。

大 ==》 小有可能存在问题;小 ==》 大没问题;

a8dea00d7209d7804a863957308e1d03.png

隐式转换

**特点:**由编译器自动完成的类型转换

  • 算术运算式中,低类型转换为高类型
  • 赋值表达式中,表达式的值转换为左边变量的类型
  • 函数调用时,实参转换为形参的类型
  • 函数返回值,return表达式转换为返回值类型
#include 

int main(void){
    int i = -2;
    unsigned int j = 1;
    if( (i + j) >= 0 ){
        printf("i+j>=0\n");
    }
    else{
        printf("i+j<0\n");
    }
    printf("i+j=%d\n", i + j);
    return 0;
}

1d88198cb65b1824f6c58de5889b0211.png

在计算时,转换为高类型,即unsigned int,判断>0,这里感觉没有错。那为什么输出-1,跟我们正常算-2+1的结果一样呢。

我们都知道计算机是补码存储,-2+1的unsigned int结果是0xffffffff,对于输出的%d其实是int类型,所以自然打印就是-1了。

强制类型转换

虽然自动类型转换不需要人工干预,使用方便,但有利也有弊,尤其当自动类型转换是从较高类型转换为较低类型时,将会降低精度或截断数据,可能得不到预期的结果。

为了给程序设计人员提供更多的类型转换控制权限,使程序设计更加灵活,转换的目的更加清晰,C 语言提供了可显式指定类型转换的语法支持,通常称之为强制类型转换。

强制类型转换的格式为:

(目标类型) 表达式
(目标类型) 变量
#include 

int main(void){
    float p = 3.6;
 int w = 4;
 double sum = (int)p*w;
 printf("输出浮点数:%lf",sum);
    return 0;
}

我们将p直接转成int类型,则p取整数部分进行运算

db2a0d499887ab342aba1ac51ed38b36.png

0604c1e88ad53de5dbfc4309a3c144d0.pnga4355ec557d74b876082d2f4850dd7d4.pnga4355ec557d74b876082d2f4850dd7d4.png

往期文章

2020-8-21

  • C++语法1、类与对象

  • c++语法2、c执行-命名空间-输入输出

  • c++ 3、语法 数据类型

  • c++ 4、语法 数组

  • c++  c语言- 概述

  • c++  c语言 - 控件及概述补充

  • c++  c语言 - 数据类型

  • c++  c语言 - 进制、原反补码、输入输出函数

图 | 郭嘉

文 | 郭嘉

56663157238c35bb6771cc2b31b35dbe.png

扫码关注桔梗与少年

微信号 : if-u-remembers

新浪微博:桔梗与少年


版权声明:本文为weixin_39646970原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。