C语言的操作符

本文详细介绍了C语言中的各种操作符,包括算数操作符如+、-、*、/和%,移位操作符<<和>>,位操作符如&、|和^,以及赋值、逻辑、条件和逗号等操作符。文章还通过示例代码解释了这些操作符的使用方法和效果,如位操作符在变量交换和计数中的应用,以及条件操作符和函数调用的语法。
摘要由CSDN通过智能技术生成

前言

C语言中的操作符是用于操作变量、常量和表达式的符号,以下是我学习操作符整理的相关知识点。

操作符分类

算数操作符

算数操作符: + - * / %

  1. +-*/可以用于操作整数和浮点数
  2. %只能操作整数,返回整除后的余数

移位操作符

<< 左移操作符

>> 右移操作符

这两个只能用于整数

  1. << 操作符

    • // 往左移,左边丢掉,右边补0
      
      // 例子
      int a = 3;  // 3在内存中二进制 00000000 00000000 00000000 00000011
      a = a << 1;  // 往左移1位,左边的丢掉,右边的补0,结果为 00000000 00000000 00000000 00000110  
      // 此时a=6
      
  2. >>操作符

    • /*
      往右移,分两种情况
      	逻辑移位: 左边补0,右边丢掉
      	算数移位: 左边补原符号,右边丢掉
      
      这里还有一个知识点,就是负数在内存中是以补码的形式存在的
      以下是-7的原码,反码,补码
      原码: 第一位代表符号位
      	10000000 00000000 00000000 00000111
      反码: 右原码除了符号位,其他位取反
      	11111111 11111111 11111111 11111000
      补码: 由反码+1得到
      	11111111 11111111 11111111 11111001
      */
      
      // 例子
      int a = -7;  // -1在内存中二进制 11111111 11111111 11111111 11111001
      a = a >> 1;  // 往右移一位,通常是使用算数移位,补原符号,得11111111 11111111 11111111 11111100
      /*
      补码: 11111111 11111111 11111111 11111100   
      -1得到反码: 11111111 11111111 11111111 11111011
      取反得到原码: 10000000 00000000 00000000 00000100  -> 4
      此时a=4
      */
      

位操作符

位操作符: & | ^
位操作符只能操作整数

  • &按位与

    • /*
      使用两个数的二进制进行运算,只要有0就是0,全1才为1
      */
      
      #include <stdio.h>
      
      int main()
      {
      	int x = 2;  // 00000000 00000000 00000000 00000010
      	int y = 1;  // 00000000 00000000 00000000 00000001
      	printf("%d\n", x & y);  // 00000000 00000000 00000000 00000000 -> 0
      	
          int a = 15;  // 00000000 00000000 00000000 00001111
      	int b = 8;  // 00000000 00000000 00000000 00001000
      	printf("%d\n", a & b);  // 00000000 00000000 00000000 00001000 -> 8
      	return 0;
      }
      
  • |按位或

    • /*
      使用两个数的二进制进行运算,全0才为0,只要有1就为1
      */
      
      #include <stdio.h>
      
      int main()
      {
      	int x = 2;  // 00000000 00000000 00000000 00000010
      	int y = 1;  // 00000000 00000000 00000000 00000001
      	printf("%d\n", x | y); // 00000000 00000000 00000000 00000011  -> 3
          
      	int a = 15;  // 00000000 00000000 00000000 00001111
      	int b = 8;  // 00000000 00000000 00000000 00001000
      	printf("%d\n", a | b);  // 00000000 00000000 00000000 00001111 -> 15
      	return 0;
      }
      
  • ^ 按位异或

    • /*
      使用两个数的二进制进行运算,相同为0,不相同为1
      */
      
      #include <stdio.h>
      
      int main()
      {
          int x = 2;  // 00000000 00000000 00000000 00000010
          int y = 1;  // 00000000 00000000 00000000 00000001
          printf("%d\n", x ^ y);  // 00000000 00000000 00000000 00000011  ->  3
          
          int a = 15;  // 00000000 00000000 00000000 00001111
          int b = 8;  // 00000000 00000000 00000000 00001000
          printf("%d\n", a ^ b);  // 00000000 00000000 00000000 00000111  -> 7
          return 0;
      }
      
  • 练习题

    • 不能创建临时变量(第三个变量),实现两个数的交换

      #include <stdio.h>
      
      int main()
      {
          int a = 2;  // 00000000 00000000 00000000 00000010
          int b = 3;  // 00000000 00000000 00000000 00000011
          a = a ^ b;  // a -> 00000000 00000000 00000000 00000001  -> 1
          b = a ^ b;  // b -> 00000000 00000000 00000000 00000010  -> 2
          a = a ^ b;  // a -> 00000000 00000000 00000000 00000011  -> 3
          // 最后a=3,b=2,实现了交换
          return 0;
      }
      
    • 编写代码实现:求一个整数存储在内存中的二进制中1的个数。

      #include <stdio.h>
      
      int main()
      {
          int a = 15;  // 00000000 00000000 00000000 00001111
          int count = 0;
          while(a)
          {
              // 这里就只写后8位了
              // 第一轮: 00001111 & 00001110 -> 00001110  第二轮: 00001110 & 00001101 -> 00001100
              a = a & (a - 1);
              count += 1;
          }
          printf("%d\n", count);  // 4
          return 0;
      }
      

赋值操作符

可以随意操作变量的值

普通的赋值符 =

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

// 复合赋值符
int a = 10;
a += 10; // 跟 a = a + 10 效果一样
a <<= 10; // 跟 a = a >> 10 效果一样

单目操作符

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

    • // 非0取反就是0,0取反就是1
      
      #include <stdio.h>
      
      int main()
      {
      	printf("%d\n", !6);  // 0
      	printf("%d\n", !0);  // 1
      	return 0;
      }
      
  • -代表负值和+代表正值

  • &取地址

    • // 获取变量的地址
      
      #include <stdio.h>
      
      int main()
      {
      	int num = 66;
      	printf("%p\n", &num); // 这里%p是打印的是地址,输出的是num在内存中的00000048F81CF884
      	return 0;
      }
      
  • sizeof计算操作符的类型长度

    • #include <stdio.h>
      
      int main()
      {
      	int num = 10;
      	printf("%d\n", sizeof(num));  // 4 因为Int类型的字节数就是4
      	printf("%d\n", sizeof num);  // 4 因为sizeof是操作符,不是函数,所以可以这样写
      	return 0;
      }
      
      // 以下是关于sizeof的一个练习,依次输出的数字是什么
      #include <stdio.h>
      
      void test1(int arr1[])
      {
      	printf("%d\n", sizeof(arr1));  // 这里输出的是内存的字节数,64位操作系统,输出8,32位则是4
      }
      
      void test2(char arr2[])
      {
      	printf("%d\n", sizeof(arr2));  // 这里输出的是内存的字节数,64位操作系统,输出8,32位则是4
      }
      
      int main()
      {
      	int arr1[10] = { 0 };
      	char arr2[10] = { 0 };
      	printf("%d\n", sizeof(arr1));  // 这里输出的是10个int类型的字节数,40
      	printf("%d\n", sizeof(arr2));  // 这里输出的是10个char类型的字节数,10
      	test1(arr1);
      	test2(arr2);
      	return 0;
      }
      
      // 所以答案是: 40 10 8 8
      
  • ~操作符

    • // 二进制按位取反
      
      int a = 1;  
      /* 
      1 -> 00000000 00000000 00000000 00000001 
      ~取反 -> 11111111 11111111 11111111 11111110  此时是负数,存的是补码,需要求出原码
      +1获得反码 -> 11111111 11111111 11111111 11111101
      取反获得原码,符号不变 -> 10000000 00000000 00000000 00000010  -> -2
      */
      printf("%d\n", ~a);  // -2
      
  • ++--

    • // ++和-- 原理一致,以下以++为例
      
      // 前置++,就是先++,后引用
      int a = 3;
      int b = ++a;
      // 最后 a -> 4 ; b -> 4
      
      // 后置++,就是先引用,后++
      int a = 3;
      int b = a++;
      // 最后 a -> 4 ; b -> 3
      
  • *间接访问操作符

    • // 一般配合&使用
      #include <stdio.h>
      
      void test(int* num)
      {
          *num = 666;
      }
      
      int main()
      {
          int num = 0;
          // 此时需要一个函数改变num的值
          test(&num);
          printf("%d\n", num);  // 666
          return 0;
      }
      
  • (类型)可以强制类型转换

    • int a = 3.16;  // 当出现将double类型赋值给int类型的变量时,编译的时候会提示3.16是double类型的,使用a来接收的话可能会丢失数据
      int a = (int) 3.16;  // 这样就不会先出警告了
      

逻辑操作符

&& 逻辑与

|| 逻辑或

  • &&逻辑与

    • // 有0则为0,全非0为1
      
      int main()
      {
      	int a = 5;
      	int b = 0;
      	printf("%d\n", a && b);  // 0
          
      	int x = 2;
      	int y = 3;
      	printf("%d\n", x && y);  // 1
      }
      
      
  • ||逻辑或

    • // 只有有非0就为1,全0才为0
      
      int main()
      {
      	int a = 5;
      	int b = 0;
      	printf("%d\n", a || b);  // 1
      
      	int x = 0;
      	int y = 0;
      	printf("%d\n", x || y);  // 0
      }
      
  • 练习题

    • 写出程序输出的结果
      #include <stdio.h>
      
      int main()
      {
      	int i = 0, a = 0, b = 2, c = 3, d = 4;
      	c = a++ && ++b && d++;
      	printf("a = %d\t b = %d\t c = %d\t d = %d\n", a, b, c, d);
      	return 0;
      }
      
      /*
      当执行到c = a++ && ++b && d++;时,此时是a++先引用后++
      c = 0 && ++b && d++;因为0与上任何数都是0,所以后面的++b和d++不会执行
      最后输出 a = 1   b = 2   c= 0   d = 4
      */
      
      // 扩展,以下输出结果是什么
      #include <stdio.h>
      
      int main()
      {
      	int i = 0, a = 0, b = 2, c = 3, d = 4;
      	c = a++ || ++b || d++;
      	printf("a = %d\t b = %d\t c = %d\t d = %d\n", a, b, c, d);
      	return 0;
      }
      
      // 这里输出是a = 1   b = 3   c= 1   d = 4
      

条件操作符

格式: exp1 ? exp2 : exp3

当exp1成立,执行exp2,否则exp3

  • 例子

    • // 请输入一个整数,如果这个整数比10大,输出比10大,反之输出小于等于10
      #include <stdio.h>
      
      int main()
      {
      	int num = 0;
      	scanf("%d", &num);
      	num > 10 ? printf("比10大\n") : printf("小于等于10\n");  // 这里使用的就是条件操作符
      	return 0;
      }
      

逗号表达式

格式: exp1, exp2, exp3, exp4

从左往右依次执行,表达式的结果是最后一个表达式的结果

  • 例子

    • int main()
      {
      	int a = 1;
      	int b = 1;
      	int c = (a++, b += a, a += b);
      	printf("%d\n", c);  // 5
      	return 0;
      }
      
      /*
      解析:
      	先是a++,a=2
      	然后b+=a,b=3
      	最后a+=b,a=5
      	所以c=5
      */
      

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

  • 下标引用操作符[]

    • 格式: 一个数组名 + 一个索引值
      #include <stdio.h>
      
      int main()
      {
      	int arr[5] = { 0 };
      	printf("%d\n", arr[2]);  // 0
      	arr[2] = 10;  // 这里使用下标引用操作符修改了数组里的元素
      	// 2[arr] = 5; 这个其实也能生效,但是不会用,其实底层是*(2+arr) = 5;
      	printf("%d\n", arr[2]);  // 10
      	return 0;
      }
      
  • 函数调用操作符()

    • 格式: 函数名+()
      int test()
      {
          return 1;
      }
      
      int main()
      {
          int num = test();  // 函数后面的()就是函数调用操作符
          return 0;
      }
      
  • 访问一个结构的成员

    • .:结构体.成员名,->:结构指针->成员

      // 定义结构体
      struct Stu
      {
      	char name[10];
      	int age;
      	char sex[5];
      };
      
      // 使用结构指针
      void set_age(struct Stu* pStu)
      {
      	pStu->age = 20;
      }
      
      // 使用结构体
      void print_age(struct Stu stu)
      {
      	printf("%d\n", stu.age);
      }
      
      int main()
      {
      	struct Stu stu;
      	set_age(&stu);
      	print_age(stu);  // 20
      	return 0;
      }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值