[C语言初阶]操作符

目录

在C语言中,操作符是构成表达式的基本元素,用于对变量和常量进行各种运算操作。掌握操作符的使用对于编写高效、正确的C程序至关重要。下面我们将全面介绍C语言中的各类操作符及其应用场景。

一、算术操作符

算术操作符用于基本的数学运算:

  • /:除法操作符
    • 两端都是整数时,结果为整数(截断小数部分)
    • 至少一端为浮点数时,结果为浮点数
  • %:取模操作符
    • 两端必须为整数,返回除法后的余数
c 复制代码
int a = 5 / 2;    // 结果为2
float b = 5.0 / 2; // 结果为2.5
int c = 5 % 2;     // 结果为1

二、移位操作符(操作数必须为整数)

移位操作直接对二进制补码进行操作:

  1. 左移<<

    • 二进制位整体向左移动指定位数
    • 右侧补0
    • 相当于乘以2^n(无溢出时)
  2. 右移>>

    • 分为逻辑右移和算术右移
    • 逻辑右移:右边向右移一位,左边补0
    • 算术右移(常用):右边向右移一位,左边补原符号位(符号位即是最高位,0表正数,1表负数)
    • 相当于除以2^n(向下取整)

注意

  • 移位操作不改变原变量值,只影响表达式结果
  • 避免移动负数位,这是未定义行为
  • 负数移位后需要将补码转换回原码才能得到正确结果

补充:原反补的转化

  • 原码:直接写出二进制序列
  • 反码:符号位不变,其他位按位取反
  • 补码:反码+1(整数在内存中存放的是补码,注意这种原反补的计算只使用于负数,即如果写出的原码最高位是1,则要进行这种计算,而最高位如果是0,则原反补码都相同,左移,右移都是对补码进行操作,但最后如果是负数要转化为原码才是正确的结果)

三、位操作符(操作数必须为整数,类比逻辑操作符)

位操作符直接对二进制补码进行操作:

  1. 按位与&

    -位是二进制位,对应二进制位按位与,规则是对应位只要有0,结果为0,对应位都是1,结果才为1

    • 应用:清零特定位、取指定位
  2. 按位或|

    • 对应位,如果有1,结果为1,两个同时为0,则为0
    • 应用:将特定位设为1
  3. 按位异或^

    • 对应位相同为0,不同为1
    • 特性:
      • a ^ a = 0
      • a ^ 0 = a
    • 应用:交换变量值、加密解密

3.1 经典面试题:不借助临时变量交换两个值

解法一(有溢出风险)

c 复制代码
a = a + b;
b = a - b;
a = a - b;
//这种解法好,但有缺陷,如果数字太大,相加会超出上限溢出

解法二(推荐,无溢出风险)

c 复制代码
a = a ^ b;
b = a ^ b; // 相当于a^b^b = a
a = a ^ b; // 相当于a^b^a = b
//原理分析:任何两个相同数异或,结果为0,而0与任何数异或,结果还是那个数
//a=a^b,b=a^b,相当于a^b^b,先算b^b,结果为0,所以a^0结果为a,于是就完成了交换

3.2 位操作应用实例

  1. 统计二进制中1的个数

解法:按位与+右移操作符

分析:用1来按位与,同时为1时,结果才为1,然后用右移操作符讲要判断的二进制序列向右移1位,1位1位来判断,如果结果是1则自增,从最高位到最低位只用移动31次,用循环来实现

c 复制代码
int count_ones(int num) {
    int count = 0;
    for(int i=0; i<32; i++) {
        if(num & (1 << i)) count++;
    }
    return count;
}
  1. 把整数二进制序列中的某一位改为1
  • 解法:按位或+左移操作符
  • 分析:用1来按位或,只要有1个为1,就为1,用左移操作符把1移动到要改的那个数的二进制序列的那一位,即可
  • 衍生:现在把那一位改为1了,如何改回来呢?
    • 解法:按位与+左移操作符+ ~
    • 分析:用这个数来和1按位与,左移到那一位,就可以改回来,但是如果这个数字很多1,我们就很难计算这个数是多少,于是我们就可以运用逆向思维,把这个数除符号位不变外,其他位按位取反,记为a,则~a就表示这个数,我们就用这个数来和1进行按位与

四、赋值操作符

  1. 简单赋值=

    • 支持连续赋值:a = b = c(从右向左计算,先把c赋给b,再把b赋给a)
    • 但不推荐这种写法,可读性较差
  2. 复合赋值+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=

五、单目操作符

  1. sizeof

    • 计算变量/类型所占字节数

    • 返回无符号整型,用%u打印

    • 特点:内部表达式不参与运算

      • 若变量s是short类型,a是int类型,计算sizeof(s=a+2),结果还是为2,因为sizeof()内部的表达式不参与运算,不会因为有个int就改变类型,算的还是是s类型的大小
      c 复制代码
      short s; int a;
      sizeof(s = a + 2); // 结果为2(short类型大小)
  2. ~

    • 二进制序列按位取反(包括符号位,0变成1,1变成0)
    • 应用:在上面讲过的配合位操作修改特定位
  3. ++/--

    • 前置:先增减,后使用
    • 后置:先使用,后增减
  4. &*

    • &:取地址操作符
    • *:解引用操作符
    • 指针大小:32位系统4字节,64位系统8字节
  5. 强制类型转换(类型)

六、关系与逻辑操作符

  1. 关系操作符>, <, >=, <=, ==, !=

    • 注意:字符串比较不能用==,需用strcmp()
  2. 逻辑操作符

    • &&:逻辑与(短路特性:左假则右不算)
    • ||:逻辑或(短路特性:左真则右不算)
  3. 360笔试题

c 复制代码
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
//i = a++||++b||d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
//程序输出的结果是什么?
  • 360笔试题总结:
    • a && b:当a为假时,不计算b
    • a || b:当a为真时,不计算b

七、其他操作符

  1. 条件操作符(三目)表达式1 ? 表达式2 : 表达式3

  2. 逗号操作符

    • 从左到右依次计算表达式
    • 整个表达式结果为最后一个表达式的结果
    c 复制代码
    int a = (b=1, c=2, b+c); // a=3
  3. 下标引用,函数调用,结构成员访问

  • 下标引用:下标引用[]:如arr[4],操作数是两个,arr和4
  • 函数调用: ()
  • 结构体成员访问
    • .:直接访问成员
    • ->:通过指针访问成员,如果创建了结构体指针,则访问可以用->,如结构体指针pb,pb->name表示的是它指向的对象的name

八、表达式求值注意事项

  1. 隐式类型转换

    • 整型提升:char/short运算时先提升为int
    • 算术转换:不同类型运算时向高精度转换
  2. 操作符优先级

    • 不确定时使用括号明确优先级
    • 常见优先级:() > 单目 > 算术 > 移位 > 关系 > > 逻辑 > 条件 > 赋值 > 逗号

掌握C语言操作符是编写高效代码的基础。通过本文的学习,相信您已经对C语言操作符有了全面了解。在后续编程实践中,我们可以灵活运用这些操作符解决各种问题。下一篇,我们将介绍指针初阶,敬请期待!

作者其他文章链接:
[C语言初阶]扫雷小游戏
[C语言初阶]三子棋小游戏
Gitee详细使用教程

相关推荐
AI+程序员在路上31 分钟前
Qt6中模态与非模态对话框区别
开发语言·c++·qt
nbsaas-boot5 小时前
Java 正则表达式白皮书:语法详解、工程实践与常用表达式库
开发语言·python·mysql
chao_7895 小时前
二分查找篇——搜索旋转排序数组【LeetCode】两次二分查找
开发语言·数据结构·python·算法·leetcode
风无雨6 小时前
GO 启动 简单服务
开发语言·后端·golang
斯普信专业组6 小时前
Go语言包管理完全指南:从基础到最佳实践
开发语言·后端·golang
秋说7 小时前
【PTA数据结构 | C语言版】一元多项式求导
c语言·数据结构·算法
我是苏苏8 小时前
C#基础:Winform桌面开发中窗体之间的数据传递
开发语言·c#
斐波娜娜8 小时前
Maven详解
java·开发语言·maven
小码氓8 小时前
Java填充Word模板
java·开发语言·spring·word