C语言——运算符

C语言目录:

1. 概述

2. 数据类型

3. 量

4. 运算符

5. 流程控制

6. 函数

7. C程序编译过程

8. 文件

9. 内存管理


4.1 基本概念

运算符:告诉程序执行特定的算术或逻辑操作的符号

表达式:利用运算符连接在一起的有意义、有结果的语句

  • 表达式一定要有结果

4.1.1 分类

按功能化划分:

  • 算术运算符
  • 赋值运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符

按照参与运算符的个数划分:

  • 单目运算符

    如:i++

  • 双目运算符

    如:a+b

  • 三目运算符

    如:a>b ? 1 : 0;

4.1.2 优先级与结合性

不同优先级 的运算符,运算次序按照 优先级从高到低执行

相同优先级 的运算符,运算次序按结合性规定的方向执行

#include <stdio.h>

int main(){
    int a = 10;
    int b = 5;
    
    // 算术运算符的结合性和优先级
    // 结合性: 左结合性, 从左至右
    int c = 50;
    result = a + b + c; // 15 + c;  65;
    printf("%i\n", result);
    
    // 优先级: * / % 大于 + -
    result = a + b * c; // a + 250; 260;
    printf("%i\n", result);
}

单目运算符,赋值运算符,三目运算符为右结合性;
其余为左结合性(从左向右看)

x = 2;
x+=x+=x-=1; //=> x = 4

y = x&1 == x%2; //=> y = 1
/*
 *设x = 10 0&1 = 0 , x % 2 = 0   y = 1
 */
 
a = b = c = 1;
++a||++b&&++c;
//a = 2,b = 1,c = 1;
优先级运算符名称或含义使用形式结合方向说明
1[]数组下标数组名[常量表达式]左到右
()圆括号(表达式)/函数名(形参表)
.成员选择(对象)对象.成员名
->成员选择(指针)对象指针->成员名
2-符号运算符-表达式右到左单目运算符
(类型)强制类型转换(数据类型)表达式
++自增运算符++变量名/变量名++
--自减运算符--变量名/变量名--
*取值运算符*指针变量
&取地址运算符&变量名
!逻辑非!表达式
~按位取反~表达式
sizeof长度运算符sizeof(表达式)
3/表达式/表达式左到右双目运算符
*表达式*表达式
%取余表达式%表达式
4+表达式+表达式左到右双目运算符
-表达式-表达式
5<<左移变量<<表达式左到右双目运算符
>>右移变量>>表达式
6>大于表达式>表达式左到右双目运算符
>=大于等于表达式>=表达式
<小于表达式<表达式
<=小于等于表达式<=表达式
7==等于表达式==表达式左到右双目运算符
!=不等于表达式!=表达式
8&按位与表达式&表达式左到右双目运算符
9^按位异或表达式^表达式左到右双目运算符
10|按位或表达式|表达式左到右双目运算符
11&&逻辑与表达式&&表达式左到右双目运算符
12||逻辑或表达式||表达式左到右双目运算符
13?:条件运算符表达式1?表达式2:表达式3;右到做三目运算符
14=赋值运算符变量=表达式右到左
/=除后赋值变量/=表达式
*=乘后赋值变量*=表达式
%=取余后赋值变量%=表达式
+=加后赋值变量+=表达式
-=减后赋值变量-=表达式
<<=左移后赋值变量<<=表达式
>>=右移后赋值变量>>=表达式
&=按位与后赋值变量&=表达式
^=按位异或后赋值变量^=表达式
|=按位或后赋值变量|=表达式
15,逗号运算符表达式,表达式,...左到右

4.2 逗号运算符和括号运算符

#include <stdio.h>

int main(){
    int a = 10, b = 20, c;
    // ()优先级高于,和=, 先计算()中的内容
    // c = (11,21);
    // ()中是一个逗号表达式, 结果是最后一个表达式的值, 所以计算结果为21
    c = (a + 1,b + 1);
    printf("c = %d\n", c); // 21
}

4.3 自增自减

  • 前缀表达式:++x, --x;表示先自增再运算
  • 后缀表达式:x++, x–;表示先运算再自增
#include <stdio.h>

int main(){
    int n = 1;
    // ++在后, 先参与表达式运算, 再自增
    // 表达式运算时为: 3 + 1;
    int res = 3 + n++;
    printf("res = %d\n", res); // 4
    printf("n = %d\n", n); // 2
}

#include <stdio.h>

int main(){
    int n = 1;
    // ++在前, 先自增, 再参与表达式运算
    // 表达式运算时为: 3 + 2;
    int res = 3 + ++n;
    printf("res = %d\n", res); // 5
    printf("n = %d\n", n); // 2
}

自增、自减运算只能用于单个变量,只要是标准类型的变量(整型、实型还是字符型变量),但不能用于表达式或常量

  • 错误用法:++(a+b); 5++;
int i = 10;
int b = i++; // 不推荐
或者
int b = ++i; // 不推荐
或者
int a = 10;
int b = ++a + a++;  // 不推荐

int i = 10;
int b = i; // 推荐
i++;
或者;
i++;
int b = i; // 推荐
或者
int a = 10;
++a;
int b = a + a; // 推荐
a++;

4.4 sizeof

用于计算一个变量、或常量、数据类型占用的内存字节数

sizeof(常量 or 变量);

sizeof(10); //sizeof 10;

char c = 'a';
sizeof(c); //sizeof c;

sizeof(数据类型);

sizeof(float);

sizeof是一个运算符,不是函数

  • sizeof 运算符优先级为2
int a = 10;
double b = 3.14;
double res = sizeof(a+b);// sizeof a+b;

# sizeof 运算符优先级比+高,所以会先计算sizeof(a),再利用结果和b相加
//res = 7.14

4.5 算数运算符

优先级符号含义表达式结合性
3/表达式/表达式左到右双目运算符
*表达式*表达式
%取余表达式%表达式
4+表达式+表达式左到右双目运算符
-表达式-表达式
  • 如果参与运算的两个操作数都是整数,那么结果也是整数

  • 如果参与运算的两个操作数有一个是浮点数,那么结果一定是浮点数

    #include <stdio.h>
    int main(){
        // 整数除以整数, 结果还是整数
        printf("%i\n", 10 / 3); // 3
    
        // 参与运算的任何一个数是小数, 结果就是小数
        printf("%f\n", 10 / 3.0); // 3.333333
    }
    
  • 取余运算符,参与运算的两个操作数必须是整数,不能包含浮点数

    取余运算结果的符号与被除数有关

    #include <stdio.h>
    int main(){
        // 被除数是正数结果就是正数,被除数是负数结果就是负数
        result = 10 % 3;
        printf("%i\n", result); // 1
        result = -10 % 3;
        printf("%i\n", result); // -1
        result = 10 % -3;
        printf("%i\n", result); // 1
    }
    
  • 取余运算符,被除数为0,结果为0

  • 除法/取余运算,除数为0,没有意义

4.6 关系运算符

非零值都是 true ,只有零才是 false

关系运算符的运算结果只有两种:

  • 条件成立,结果为 true
  • 条件不成立,结果为 false

4.6.1 优先级与结合性

# include<stdio.h>

int main(){
    //== 优先级小于 > ,所以先计算 > 
    int result = 10 == 5 > 3;//10 == 1 -> true
    printf("%d\n",result);
}
# include<stdio.h>

int main(){
    // == 和 != 优先级一样,所以按照结合性
    int res = 10 == 5 != 3;// 10 == true -> true
    printf("%d\n",res);
}

无论是 float 还是 double 都有精度问题, 所以一定要避免利用 == 判断浮点数是否相等

4.7 位运算符

程序中所有数据都是以二进制形式存储,位运算符就是直接对整数在内存中的二进制操作

符号名称运算结果
&按位与同1为1,有0则0
|按位或同0位0,有1为1
^按位异或同0异1
~按位取反0变1,1变0
<<n按位左移乘以2的n次方
>>n按位右移除以2的n次方

4.7.1 按位与

9&5 = 1

    1001
  & 0101
    ----
    0001
a. 判断奇偶

任何数和1进行&操作,得到这个数的最低位

	1000
   &0001
    ----
    0000  // 结果为0, 代表是偶数

	1011
   &0001
    ----
    0001 // 结果为1, 代表是奇数

4.7.2 按位或

9|5 = 13

    1001
  | 0101
    ----
    1101
a. 权限设置
enum Unix {
    S_IRUSR = 256,// 100000000 用户可读
    S_IWUSR = 128,//  10000000 用户可写
    S_IXUSR = 64,//    1000000 用户可执行
    S_IRGRP = 32,//     100000 组可读
    S_IWGRP = 16,//      10000 组可写
    S_IXGRP = 8,//        1000 组可执行
    S_IROTH = 4,//         100 其它可读
    S_IWOTH = 2,//          10 其它可写
    S_IXOTH = 1 //           1 其它可执行
};
// 假设设置用户权限为可读可写
printf("%d\n", S_IRUSR | S_IWUSR); // 384 // 110000000

4.7.3 按位异或

相同整数异或为0,如 5^5=0

多个整数相异或的结果跟顺序无关,如 5^6^7 == 5^7^6

  • 同一数异或另外一个数两次,结果还是那个数,如 5^7^7=5
9^5 = 12

    1001
  ^ 0101
    ----
    1100
a. 交换两个数的值
a = a^b;
b = b^a; // b = b^a^a = a;
a = b^a; // a = b^a^b = a^a^b = b;

4.7.4 按位取反

~9 = -10

原码    0000 1001
补码    1111 0110

转为十进制    0000 1001+1 = 0000 1010 = -10

4.7.5 按位左移

2<<n :相当于乘2的n次方

高位舍弃,低位补0,高位丢弃,但符号位也会丢弃,造成正负性改变

2<<1; //相当于 2 *= 2 // 4
  0010
<<0100

2<<2; //相当于 2 *= 2^2; // 8
  0010
<<1000

4.7.6 按位右移

2>>n :相当于除以2的n次方

正数时,符号位为0,最高位补0

负数时,符号位为1,最高位是补0 或 是补1取决于编译系统

4.8 逻辑运算符

优先级符号名称符号结合性
2!逻辑非!表达式右结合性单目运算符
11&&逻辑与表达式&&表达式左到右双目运算符
12||逻辑或表达式||表达式左到右双目运算符

4.8.1 逻辑非

! 条件A;

运算结果:

  • !true = false;
  • !false = true;

4.8.2 逻辑与

条件A && 条件B;

判断过程

  • 条件A为真,则接着判断条件B,也真,则表达式为 true
  • 条件A为假,则不执行B,则表达式为 false

4.8.3 逻辑或

条件A || 条件B;

判断过程

  • 条件A为假,且条件B为假,则表达式为 false
  • 条件A为假,条件B为真,则表达式为 true
  • 条件A为真,则不会执行条件B,则表达式为 false
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AmosTian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值