C语言操作符详解

操作符

算术操作符

+  -  *  /  %
  • 除了%操作符,其他几个操作符都可以作用于整数和浮点数
  • 对于/操作符,如果两个操作数都为整数,执行整数除法,只要有浮点数,则执行浮点数除法
  • %操作符的两个操作数必须为整数,返回的是整除之后的余数

位操作符

<< 左移操作符
>> 右移操作符   例:num << 2;   num >> 2;
~  按位取反
&  按位与
|  按位或
^  按位异或

注意:参与运算的数均以 补码 的形式参与运算; 只适用于整型变量和字符型变量。

  • 左移操作符: << (需要移动的数字 << 移动的位数)
    • 按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
    • 数学意义:在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。

在这里插入图片描述

  • 右移操作符: >> (需要移位的数字 >> 移动的位数)

    • 算术右移(低位丢弃,高位补原符号位)

      • 按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。
      • 数学意义:右移一位相当于除2,右移n位相当于除以2的n次方。(注意是整除)

在这里插入图片描述

  • 逻辑右移(低位丢弃,高位补0)

    • 按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补0。
  • 正数的算术右移和逻辑右移一致。

  • 注意:移位操作符的操作数只能是整数;移动的位数是正整数。

  • 按位取反 ~

对操作数按二进制的各位取反,即0变1,1变0。

  • 按位与 & (均为1,结果为1)

    • 参与运算的两个数各对应的二进制位相与,只有对应的两个二进制位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。
    • 按位与可以用于设置字节中的某位为0,其余位为1。
  • 按位或 | (出现1,结果为1)

    • 参与运算的两个数各对应的二进制位相或,只要对应的一个二进制位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。
    • 按位或可以用于设置字节中的某位为1,其余位为0。
  • 按位异或 ^ (不相同,结果为1)

    • 参与运算的两个数各对应的二进制位相异或,当两个数对应的二进制位不相同时,结果位就为1;否则结果位为1。参与运算的两个数均以补码出现。

    • 按位异或可以用于翻转字节中的相应位,设置字节中的某位为1,其余位为0。

    • 例:交换两个变量的值(不能临时创建一个新变量)

      int main()
      {
          int a = 2;
          int b = 3;
          //交换
          a = a ^ b;
          b = a ^ b;
          a = a ^ b;
          return 0;
          //优解
      }
      
      int main()
      {
          int a = 2;
          int b = 3;
          //交换
          a = a + b;
          b = a - b;
          a = a - b;
          return 0;
          //此方法可行,但存在弊端,若a,b数值太大,可能会导致溢出
      }
      

赋值操作符

赋值操作符       =
复合赋值操作符   += -= *= /= %= >>= <<= &= |= ^=

复合赋值操作符:对于复合赋值操作符,可以理解为先操作(+ - * / % >> << & | ^)再赋值。

int a = 3;
int b = 2;
a = a + b;
a += b;
//这两种写法表达的意思相同。

注意:=表示赋值;==表示判断相等。

单目操作符

!  逻辑非运算符
~  按位取反
-  负号运算符
+  正号运算符
++ 自增运算符
-- 自减运算符
&  取地址
*  指针运算符(间接访问操作符(解引用操作符))
(类型) 类型转换运算符
sizeof 长度运算符(操作数的类型长度(以字节为单位))
  • ! 操作符

    • 单目运算符,只有右操作数,结果与右操作数相反。

      a!a
      01
      非00
  • ++-- 运算符

    • 在使用变量的同时使变量的值增加1或者减少1;
      • 前缀表示法(先变再用):++i ,–j 意义是先修改变量的值后再用修改后的值。
      • 后缀表示法(先变再用):i++ ,j-- 意义是先使用变量的值后再修改变量的值。
  • sizeof 操作符

    • 测试出数据类型或表达式所占用的内存字节的大小;

      • sizeof 在测试表达式的时候,不会真正计算表达式,而是仅仅给出该表达式结果的类型所占用的内存大小

        short s = 5;
        int i = 3;
        printf("%d", sizeof(s = i + 2));    //编译结果为2
        
      • sizeof 的括号内如果为变量,则括号可以省略——sizeof 是操作符,而不是函数。

  • & 操作符和* 操作符

    • 这两个操作符在指针章节详细说明。
  • (类型)强制类型转换

    • 把变量从一种类型转换为另一种数据类型;

    • int a = (int)3.14; //强制将浮点型数据转换为整型数据
      

关系操作符

> >= < <= 
==   等于运算符 
!=  不等于运算符
运算符含义作用
<小于左操作数小于右操作数,返回1;否则返回0
<=小于等于左操作数小于等于右操作数,返回1;否则返回0
>大于左操作数大于右操作数,返回1;否则返回0
>=大于等于左操作数大于等于右操作数,返回1;否则返回0
==等于左操作数等于右操作数,返回1;否则返回0
!=不等于左操作数不等于右操作数,返回1;否则返回0

逻辑操作符

&&  逻辑与
||  逻辑或
操作符含义作用
&&逻辑与只有左右操作数都为非0(逻辑真),返回1(逻辑真)
||逻辑或只有左右操作数都为0(逻辑假),返回0(逻辑假)

注意:在逻辑表达式中,并不是所有的逻辑运算符都会被执行。只要在计算过程中,能明确得出最终结果的值,那么求值的过程立即结束,这种现象称为逻辑运算的短路。例:

#include <stdio.h>
int main()  //逻辑运算的短路
{
    int i = 0, a = 0, b = 2, c = 3, d = 4;
    i = a++ && ++b && d++;//当a++的值在表达式中为0,由于后面是逻辑与,整个表达式的值一定为0,则后面的表达式不需要计算。
    // i = c++ || ++b || d++;//当c++的值在表达式中为3,由于后面是逻辑或,整个表达式的值一定为1,则后面的表达式不需要计算。
    printf("%d %d %d %d", a, b, c, d);
    return 0;
} //编译结果:逻辑与:1 2 3 4 ;逻辑或:0 2 4 4

条件操作符

exp1 ? exp2 : exp3
  • 条件操作符是C语言中唯一一个三目操作符;
  • 运算过程:如果 exp1 的值为真(非0),那么整个条件表达式的值为 exp2 的值,否则为 exp3 的值。

逗号表达式

,
  • 逗号表达式按自左向右的顺序依次计算各表达式的值**(一定要计算),并以最右端的表达式的类型与值作为逗号表达式的类型和值。**

下标引用、函数调用、结构成员

[]  下标引用
()  函数调用
->  结构体指针运算符
.   结构体成员运算符
  • []下标引用操作符

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

    • int arr[10];//创建数组
      arr[9] = 10;//使用下标引用操作符;[]的两个操作数是arr和9
      
  • ()函数调用操作符

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

    • int ADD(int x, int y)//函数定义
      {
          return x + y;
      }
      int main()
      {
          int a = 10, int b = 20;
          int ret = ADD(a,b);//函数调用操作符
          return 0;
      }
      
  • .->操作符

    • 这两个操作符在结构体章节详细说明。

表达式求值

  • 表达式求值的顺序一部分是由操作符的优先级和结合性决定的,同样,有些表达式的操作数在求值过程中肯需要转换为其他类型。

显示类型转换

  • 需要使用()运算符

  • 格式:(类型说明符) 表达式;括号内的类型说明符就是转换后的数据类型

  • 值域小的类型转换为值域大的类型是安全的,而值域大的类型转换为值域小的类型需要注意,可能会舍弃部分数据

隐式类型转化

整型提升
  • C语言的整型算数运算总是至少以缺省整型类型的精度来进行的

  • 整型提升:为了获取上述精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型。

  • 整型提升的意义:

    表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。

    因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

    通用CPU(general-purpose CPU)是难以直接实现两个8bit字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。

  • 如何进行整型提升?

    整型提升分为有符号和无符号两种。

    **有符号的:**整型提升时是按照变量的补码被截断时的最高位是什么进行补位的,如果截断后最高位即最左面的一位数为 1 则在最高位前补 1 ,如果最高位是 0 则在前面补 0 ,补够32位即int类型即可。

    **无符号的:**直接在被截断的前面补 0 即可。

  • 例:

    • //例一
      #include <stdio.h>
      int main()
      {
          char a = 3;//a的补码:00000000 00000000 00000000 00000011
          //a为char类型,发生截断,a以00000011存入内存
          //发生整型提升:00000000 00000000 00000000 00000011
          char b = 127;//b的补码:00000000 00000000 00000000 01111111
          //b为char类型,发生截断,b以01111111存入内存
          //发生整型提升:00000000 00000000 00000000 01111111
          char c = a + b;
          //a+b:00000000 00000000 00000000 10000010
          //赋值给c后,结果被截断:10000010
          printf("%d", c);
          //c发生整型提升:11111111 11111111 11111111 10000010 补码
          //将c的补码转化为原码:10000000 0 0000000 00000000 01111110  原码  得到结果:-126
          return 0;
      }//编译结果:-126
      
      //例二
      #include <stdio.h>
      int main()
      {
          char c = 1;
          printf("%u\n", sizeof(c));
          printf("%u\n", sizeof(+c));
          printf("%u\n", sizeof(-c));
          return 0;
      }//编译结果:1 4 4
      //sizeof(+c)和sizeof(-c)中,c参与运算,发生了整型提升,所以是4个字节
      
算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的类型转换为另一个操作数的类型,否则操作就无法进行。

也就是说,在包含两种数据类型的任何运算中,值域小的类型会隐式转换为值域大的类型

下列数据类型的值域为向下由大到小

long double;
double;
float;
unsigned long int;
long int;
unsigned int;
int;

警告: 算术转换要合理,要不然会有一些潜在的问题。

函数传参时的隐式转换

在函数调用传参时,charshort会被隐式转换为intfloat会被隐式转换为double

操作符的属性

复杂表达式的求值有三个影响因素:操作符的优先级、操作符的结合性、是否控制求值顺序

  • 操作符的优先级

  • 操作符的结合性

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C语言中的string函数主要包括字符串的处理函数和字符串的操作函数。 字符串的处理函数主要有以下几个: 1. strlen:用于计算字符串的长度,即包含的字符数目。 2. strcpy:用于将一个字符串复制到另一个字符串中。 3. strcat:用于将两个字符串连接起来。 4. strcmp:用于比较两个字符串的大小关系。 5. strchr:用于在一个字符串中查找指定字符的位置。 6. strstr:用于在一个字符串中查找指定子串的位置。 字符串的操作函数主要有以下几个: 1. sprintf:用于将格式化的数据写入字符串中。 2. sscanf:用于从字符串中读取格式化的数据。 3. strtok:用于将一个字符串按照指定的分隔符进行分割。 4. strncmp:用于比较两个字符串的前n个字符的大小关系。 5. strncpy:用于将一个字符串的部分内容复制到另一个字符串中。 6. memset:用于给字符串的指定范围内的每个字符赋予相同的值。 这些函数可以帮助我们在C语言中方便地处理字符串,实现字符串的复制、连接、比较、查找等操作。通过这些函数,我们可以更高效地处理文本数据,提高代码的可读性和可维护性。 需要注意的是,使用这些函数时要确保输入的参数合法,以避免内存越界等错误。同时,字符串的内存空间需要提前分配好,以免出现不可预知的问题。在实际编程中,我们需要灵活运用这些函数,结合具体需求,进行字符串的处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ALMAN8

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

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

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

打赏作者

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

抵扣说明:

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

余额充值