操作符详解

一. 算术运算符

Include: + - * / %
  • /——除法,得到的是商,%——取模(取余),得到的是余数。

  • 对于 / 操作符:如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。且打印格式要对应匹配。

  • 对于%操作符:两个操作数必须为整数。 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。


二. 移位操作符

Include: << 左移操作符
>> 右移操作符
  • 移位操作符移动的是2进制的位。

  • 移位操作符的操作数只能是整数。

  • 整数在内存中存储的是补码,计算时也是用补码计算,因为计算是拿内存中的值进行计算的。

补码是2进制的,而vs为了表达更简洁,用16进制显示内存中存储的值。e.g.: -5在内存中实际存入的应是其补码——1111 1111 1111 1111 1111 1111 1111 1011,而在vs内存中看到的其转换为16进制后的值——0xFF FF FF FB.

  • 左移操作符:

移位规则:左边丢弃,右边补零。(不关心符号位)

  1. 区分:b=a<<1和a=a<<1,前者b为a左移一位产生的结果,但a自身的值仍为a、未变化;后者是赋值运算,a发生变化,结果为a左移一位产生的值。

  • 右移操作符:

  1. 移位规则:(移n位也一样)
    首先右移运算分两种:

  1. 逻辑移位
    左边用0填充,右边丢弃

  1. 算术移位
    左边用原该值的符号位填充,右边丢弃
    警告⚠ :
    对于移位运算符,不要移动负数位,这个是标准未定义的。(e.g.num>>-1//err)

  1. 右移时,采用i还是ii,是取决于编译器的,vs采用算术移位,一般情况下也是算术移位较常见。(只能通过负数来测试)


三. 位操作符

Include: & 按位与
| 按位或 ^ 按位异或
  • 操作数必须是整数,操作的位是2进制位

  • 规则:

  1. & 按位与:0&0=0,0&1=0,1&1=1;

  1. | 按位或:0 | 0=0,0 | 1=1,1 | 1=1;

  1. ^ 按位异或:

  1. 对应2进制位,相同为0,相异为1;

  1. 异或支持交换律;

  1. 0^a=a,a^a=0;

  • 异或的应用: 不能创建临时变量(第三个变量),实现两个数的交换。

//F1:异或
//优:不可能进位导致溢出;
//缺:1.局限性(异或只能用于整数)
//    2.效率低(相较于创建临时变量)
#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    a = a^b;
    b = a^b;//<=>b=(a^b)^b=a^(b^b)=a^0=a;
    a = a^b;//<=>a=(a^a)^b=b;
    printf("a = %d b = %d\n", a, b);
    return 0;
}

//F2:
//缺:存在潜在问题——溢出
#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    a = a+b;
    b = a-b;
    a = a-b;
    printf("a = %d b = %d\n", a, b);
    return 0;
}

四. 赋值操作符

  • 连续赋值:a=x=y+1; 从右往左结合;可读性差,尽量少用。

  • 复合赋值:

复合赋值符 +=
-= *= /= %= >>= <<= &= |= ^=
  • a+3=15,这样的赋值是不可取的,因为左边的表达式无法代表一块空间。

  • 区分:初始化(创建变量的同时赋值)和赋值(对已有变量赋值)。


五. 单目操作符

  • 逻辑反操作符 !的应用:与标记变量结合使用

int main()
{
    int flag=5;
    if(flag)//flag为真时,就做什么
    {
        
    }
    if(!flag)//flag为假时,就做什么
    {
        
    }
    return 0;
}
  • 取地址操作符 & 注意点:&arr——取出整个数组的地址

  • sizeof:

  1. 规范表达形式:1. sizeof(类型),括号不可省;2. sizeof(变量),括号可省;

 printf("%d\n", sizeof(a));
 printf("%d\n", sizeof(int));
 printf("%d\n", sizeof a);//这样写行
 printf("%d\n", sizeof int);//这样写不行

1. 不关心放的是什么类型,只关心所占空间大小。

2. sizeof 和 数组传参

#include <stdio.h>
void test1(int arr[])
{
    printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
    printf("%d\n", sizeof(ch));//(4)
}
int main()
{
    int arr[10] = {0};
    char ch[10] = {0};
    printf("%d\n", sizeof(arr));//(1)40——因为此处arr表示整个数组,类型为int[10];
    printf("%d\n", sizeof(ch));//(3)10——因为此处ch表示整个数组,类型为char[10];
    test1(arr);
    test2(ch);
    return 0;
}
//(2),(4)都为4/8
//因为传过去的是数组首元素的地址,形参相当于用对应的指针变量接收,
//所以此时的arr本质是指针变量,永远为4/8

对一个数的2进制按位取反 ~:是对补码进行取反!!(e.g.a = 0,则~a = -1)

  • 对指定的2进制位进行操作:灵活应用 & | ^ ~ >> <<(下例为将某指定位改成0/1)

  • ++,--前后置区别

  • 强制类型转换 (类型):

是一种临时的状态,本质类型不会被改变(强扭的的瓜不甜,只能解渴)

float a = 3.14f;
int b = (int)a;//a只是在赋值时短暂地转换为了int型,但a本质仍为float型;

六. 关系操作符

=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
  • 区分:赋值 = 和 关系操作符 == ,前者是赋值用的,后者是用于判断相等的。


七. 逻辑操作符

&& 逻辑与 ——并且——同为真才为真
|| 逻辑或 ——或者——同为假才为假
  • 逻辑操作符只关心真or假,其中0为假,非0为真,但一般用1表示真。

int a = 3 && 5;
printf("%d\n",a);//1

区分:

  • 逻辑与和或的特点:(短路)

  1. &&——左边为假,右边不再计算;

  1. | | ——左边为真,右边不再计算;

#include <stdio.h>
int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++ && ++b && d++;//(1)
    //i = a++||++b||d++;//(2)
    printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
    return 0;
}
//程序输出的结果为
//(1) 1,2,3,4
//(2) 1,3,3,4

八. 条件操作符

exp1 ? exp2 : exp3
  • exp1为真,则不会计算exp3,整个表达式的结果为exp2的结果;

  • exp1为假,则不会计算exp2,整个表达式的结果为exp3的结果;


九. 逗号表达式

exp1, exp2, exp3, …expN
  • 逗号表达式,就是用逗号隔开的多个表达式。

  • 逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。

  • 逗号表达式的应用:

//代码1
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//c=13

//代码2
if (a =b + 1, c=a / 2, d > 0)
    
//代码3
a = get_val();
count_val(a);
while (a > 0)
{
         //业务处理
        a = get_val();
        count_val(a);
}
//如果使用逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)//避免了第一次的冗余;
{
         //业务处理
}

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

  1. [ ] 下标引用操作符

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

int arr[10];
arr[9] = 10;//实用下标引用操作符;
//[ ]的两个操作数是arr和9。
  1. ( ) 函数调用操作符

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

  1. 访问一个结构的成员(详见结构体note)

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

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值