0%

操作符

文章时效性提示

本文发布于 516 天前,部分信息可能已经改变,请注意甄别。

分类

  • 算数操作符
  • 移位操作符
  • 位操作符
  • 赋值操作符
  • 单目操作符
  • 关系操作符
  • 逻辑操作符
  • 条件操作符
  • 逗号操作符
  • 下标引用、函数调用和结构成员

算数操作符

+、-、*、/、%
int a = 5 / 2;商2余1,a = 2
int a = 5 % 2; a = 1
float a = 5.0 / 2; a = 2.500000
取模%的左右两边数字必须都是整数,例如5.0 % 2是不合法的。
除了取模%操作符之外,其他几个操作符都必须作用于整数和浮点数
对于/操作符,如果两边都是整数,执行整数除法,只要两边有浮点数,就执行浮点数除法。


移位操作符

<< 左移位操作符;
>> 右移位操作符。
移的是二进制位
左移位操作符规则:左边抛弃,右边补0。

1
2
3
    int a = 16;
    int b = a >> 2;
    printf("%d\n",b);

打印的结果是4。
右移1位有除2的效果,左移1位有乘2的效果。
警告⚠️:


位操作符

位是指二进制位,操作数必须是整数

  • & 按位与
  • | 按位或
  • ^ 按位异或

& 按位与

1
2
3
    int a = 3;
    int b = 5;
    int c = a & b;

a的二进制位是00000000 00000000 00000000 00000011
b的二进制位是00000000 00000000 00000000 00000101
按位与的结果是00000000 00000000 00000000 00000001,有0则0,全1为1。

| 按位或

1
2
3
    int a = 3;
    int b = 5;
    int c = a | b;

a的二进制位是00000000 00000000 00000000 00000011
b的二进制位是00000000 00000000 00000000 00000101
按位或的结果是00000000 00000000 00000000 00000111,有1则1,全0为0。

^ 按位异或

1
2
3
    int a = 3;
    int b = 5;
    int c = a ^ b;

a的二进制位是00000000 00000000 00000000 00000011
b的二进制位是00000000 00000000 00000000 00000101
按位或的结果是00000000 00000000 00000000 00000110,有1则1,全1为0。


题目:a = 3,b = 5,交换两个变量的值,不使用第三个变量(即a = 5,b = 3)

加减法-数值过大可能溢出

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
int main() {
    int a = 3;
    int b = 5;
    a = a + b;
    b = a - b;
    a = a - b;
    printf("%d\n",a);
    printf("%d\n",b);
    return 0;
}

异或法(一个数与自身异或等于0,一个数与0异或不变)

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
int main() {
    int a = 3;
    int b = 5;
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    printf("%d\n",a);
    printf("%d\n",b);
    return 0;
}

题目:编写代码,求一个整数存储在内存中二进制1的个数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main() {
    int a = 0;
    int count =0;
    printf("求一个整数存储在内存中二进制1的个数\n");
    printf("请输入一个整数:->");
    scanf("%d",&a);
    while (a) {
        if (a % 2 == 1) {
            count++;
        }
        a = a / 2;
    }
    printf("%d\n",count);
    return 0;
}

赋值操作符

= 就是赋值操作符,当一个变量已经存在,想更改它的值,就用赋值操作符

1
2
int a = 100;
a = 20;

a = 20;中的=就是赋值操作符。

1
2
3
4
int a = 10;
int b = 20;
int c = 30;
a = b = c + 1;

a = x = c + 1;连续赋值,这种写法是不推荐的。
可以改写成

1
2
3
4
5
int a = 10;
int b = 20;
int c = 30;
b = c + 1;
a = b;

警告⚠️:赋值操作符是一个等号=,判断操作符是两个等号==。

复合赋值符

  • +=
  • -=
  • \*=
  • /=
  • %=
  • =

  • <<=
  • &=
  • |=
  • ^=

单目操作符

只有一个操作数的操作符

!逻辑反操作
-负值
+正值
&取地址
sizeof操作数的类型长度(字节单位)
~对一个数的二进制位按位取反
前置、后置–
++前置、后置++
*间接访问操作符(解引用操作符)
(类型)强制类型转换

关系操作符

>
>=
<
<=
!=用于测试“不相等”
==用于测试“相等”

逻辑操作符

&&逻辑与
||逻辑或
  • 逻辑与&&操作符,如果左侧为假,不管右侧是什么,都不再计算。
  • 逻辑或||操作符,如果左侧为真,不管右侧是什么,都不再计算。
    区分逻辑与和按位与
    1 & 2 –> 0
    1 && 2 –> 1

区分逻辑或和按位或
1 | 2 –>3
1 || 2 –> 1

  • &&一个条件为假,结果为假
  • ||一个条件为真,结果为真
1
2
3
4
5
6
7
8
#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\n d = %d\n",a,b,c,d);
}

打印的结果是1,2,3,4

1
2
3
4
5
6
7
8
#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\n d = %d\n",a,b,c,d);
}

打印的结果是1,2,3,4


条件操作符

条件操作符


逗号表达式

exp1,exp2,exp3,...expn
逗号表达式,从左往右执行,整个表达式的结果是最后一个表达式的结果。


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

1、[]下标引用操作符
操作数:一个数组名 + 一个索引值

1
2
int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符

[]的两个操作数是arr和9

2、( )函数调用操作符

3、访问一个结构的成员

  • . 结构体.成员名
  • -> 结构体指->成员名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Stu
{
//里面是成员变量
char name[20];
int age;
char id[20];
};

int main()
{
//使用struct Stu这个类型创建了一个学生变量s1,并初始化
struct Stu s1 = {"张三",20,"121312312"};
struct Stu* ps = &s1;
printf("%s\n",(*ps).name);
printf("%s\n",ps->name);
//结构体指针->成员
printf("%s\n",s1.name);
printf("%d\n",s1.age);
printf("%s\n",s1.id);
//结构体.成员名(点.操作符)
}

表达式求值

隐式类型转换

为了获得精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换叫整型提升。

如何进行整型提升?
——整型提升是按照变量的数据类型的符号位来提升的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
int main()
{
    char a = 3;
    //3的2进制序列:00000000 00000000 00000000 00000011
    //a的值:00000011
    char b = 127;
    //127的2进制序列:00000000 00000000 00000000 01111111
    //b的值:01111111
    char c = a + b;
    //a和b如何相加:为了获得精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换叫整型提升。
    //如何进行整型提升?
    //——整型提升是按照变量的数据类型的符号位来提升的
    //a:00000000 00000000 00000000 00000011
    //b:00000000 00000000 00000000 01111111
    //a + b =00000000 00000000 00000000 10000010
    //截断后 c = 10000010
    //对c整型提升:
    //11111111 11111111 11111111 10000010 - 补码
    //11111111 11111111 11111111 10000001 - 反码
    //10000000 00000000 00000000 01111110 - 原码
    printf("%d\n",c);//打印的结果是-126
    return 0;
}

算数转换

如果某个操作符的各个操作数属于不同类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作无法进行。
警告:算数转换要合理,否则会有问题。

1
2
folat f = 3.14;
int num = f;//隐式转换,会有精度丢失。

操作符的属性

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