【c语言初阶】操作符全面知识总结

2024-02-27 1679阅读

温馨提示:这篇文章已超过396天没有更新,请注意相关的内容是否还可用!

操作符详解

  • 操作符种类
    • 算术操作符
    • 移位操作符
    • 位操作符
    • 编程题:两数交换多种解法
    • 编程题:求一个数在内存中二进制数1的个数
    • 赋值操作符
    • 单目操作符
    • 关系操作符
    • 编程题:谁是凶手
    • 逻辑操作符
    • 一道笔试题
    • 条件操作符
    • 逗号表达式
    • 下标引用、函数调用和结构体成员访问操作符
    • 操作符的属性
      • 操作符优先级、结合顺序、是否控制求值顺序
      • 表达式求值
        • 隐式类型转换(整形提升)
        • 算术转换

          铁汁们,今天给大家分享一篇操作符全面知识总结,来吧,开造⛳️

          操作符种类

          算术操作符

          +(加)、-(减)、*(乘)、/(除)、%(求余)

          注意点:

          1.%操作符中的操作数必须都为整数,返回的是除法中余数的部分。

          2./:分为整数除法和小数除法;

          整数除法:操作数都为整数,返回的是除法中商的部分,结果值为整数;

          小数除法:操作数至少有一个为浮点数,返回的是除法运算的具体值,结果值为小数。

          3.其他操作符的两个操作数既可以是整数,也可以是小数。

          4.%几范围:0~几-1。

          【c语言初阶】操作符全面知识总结

          实际应用:%与 / 相互搭配可以得到一个数的每一位(一个几进制数%几就可得到该数的最低位)。

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int n = 1234;
          	while (n)
          	{
          		printf("%d ", n % 10);
          		n /= 10;
          	}
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          移位操作符

          (右移操作符)

          1.左移操作符:移位规则:

          逻辑右移,左边用0补充,右边直接丢弃;

          算术右移:左边用该值的原符号位填充,右边直接丢弃。

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int i = -2;
          	printf("%d\n", i >>2 );
          	printf("%d\n", i);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          C语言没有明确规定到底是算术右移还是逻辑右移,一般编译器下采用的是算术右移。(此处博主是使用VS2019编译器,右移时为算术右移)

          注意点:

          1.操作数只能是整数。

          2.移动的是二进制数(移动的是补码)。

          3.不会改变操作数的值,改变的是含操作符的表达式值,eg:见上图。

          4.一般来说,左移相当于乘2的实际效果,右移相当于除2的实际效果。

          5.对移位运算符,不能移动负数位,这个是标准未定义的(语言标准支持,取决于编译器)。

          实际应用:让二进制中的某一位来到自己所想到达的那一位上,在一定的范围内。最多只能移动31位(移位操作符只可以操作数值位,不能操作符号位,若移动32位,则数值位全部被清空了,只剩下符号位了,则运算无意义)。

          位操作符

          &(按位与)、|(按位或)、^(按位异或)

          &:两操作数同为1才为1,有一个0则为0,全0则为0。

          |:两操作数有一个1则为1,全1则为1,全0才为0。

          ^:两操作数对应位数字相同则为0,相异则为1

          注意点:

          1.操作数必须为整数。

          2.操作的对象为二进制数(操作的是补码)。

          按位异或的两个重要结论:

          a.按位异或符合交换律;

          b.一个数与它本身按位异或结果为0,一个数与0按位异或结果为它本身;

          【c语言初阶】操作符全面知识总结

          编程题:两数交换多种解法

          方法一:创建临时变量(效率高)

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int a = 0;
          	int b = 0;
          	scanf("%d %d", &a, &b);
          	printf("交换前a=%d ,b=%d\n", a, b);
          	int tmp = a;
          	a = b;
          	b = tmp;
          	printf("交换后a=%d ,b=%d\n", a, b);
          	return 0;
          }
          

          方法二:

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int a = 0;
          	int b = 0;
          	scanf("%d %d", &a, &b);
          	printf("交换前a=%d ,b=%d\n", a, b);
          	a = a + b;
          	b = a - b;
          	a = a - b;
          	printf("交换后a=%d ,b=%d\n", a, b);
          	return 0;
          }
          

          缺点:此处会造成数据溢出现象,当a和b的值均很大但都未超过整形最大范围数,a+b的值可能超过32位,数据溢出,发生截断现象,使得结果错误。

          截断:在C语言中,截断是从高位开始截断,当将一个整型数截断为较小的整型数时,将从高位开始截取,即只保留低位部分,高位部分会被丢弃。例如,将一个32位整型数截断为16位整型数,只会保留低16位,并丢弃高16位。

          方法三:利用按位异或的两个重要结论

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int a = 0;
          	int b = 0;
          	scanf("%d %d", &a, &b);
          	printf("交换前a=%d ,b=%d\n", a, b);
          	a = a ^ b;  
          	b = a ^ b;  //等价于a^b^b=a
          	a = a ^ b;  //等价于a^b^a=b
          	printf("交换后a=%d ,b=%d\n", a, b);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          编程题:求一个数在内存中二进制数1的个数

          方法一:根据%10、/10相互搭配使用,可以得到十进制数的每一位,从而%2、/2相互搭配使用就可以得到二进制的每一位

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int a = 0;
          	int count = 0;
          	scanf("%d", &a);
          	while (a)
          	{
          		if (a % 2 == 1)
          		{
          			count++;
          		}
          		a /= 2;
          	}
          	printf("count=%d", count);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          【c语言初阶】操作符全面知识总结

          缺点:仅适用于求正数中二进制数1的个数,不适用于负数。

          方法二:一个整数&1可以获得该整数的二进制序列最低位

          思路:先获得二进制序列的每一位、在判断该位是否为1、为1计数器加1

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int a = 0;
          	int count = 0;
          	scanf("%d", &a);
          	int i = 0;
          	for (i = 0; i > i) & 1== 1)  //获取二进制数序列的每一位
          		{
          			count++;
          		}
          	}
          	printf("count=%d", count);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          不足:此处需要循环32次,效率低

          方法3:最优解a&(a-1)

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int a = 0;
          	int count = 0;
          	scanf("%d", &a);
          	while (a)
          	{
          		a = a & (a - 1);   //每进行一次此操作,二进制数序列最右边的1会丢掉,变为0
          		count++;
          	}
          	printf("count=%d", count);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          赋值操作符

          赋值操作符: =

          意义:可以让你改掉之前不满意的初值,重新给其赋值。、

          一般赋值操作符可以连续使用,但在变量初始化时,不可以连续使用。

          【c语言初阶】操作符全面知识总结

          错误结果:

          【c语言初阶】操作符全面知识总结

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	int a = 10;
          	int b = 20;
          	int c = 30;
          	a = b = c = 10;
          	printf("a=%d b=%d c=%d", a, b, c);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

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

          意义:可以达到复合的效果。eg:a+=b; 等价于a=a+b。

          单目操作符

          【c语言初阶】操作符全面知识总结

          注意:sizeof 与strlen的区别:

          1.sizeof是操作符、strlen是库函数。

          2.sizeof计算的是类型或者变量所占内存空间的大小,单位是字节,适用于任何类型,不关注具体存放在内存中的数据内容。

          3.strlen是求字符串长度,只能针对于字符串,计算是 在 '\0’之前字符的个数,关注具体存放在内存中的数据内容。

          #define _CRT_SECURE_NO_WARNINGS 1
          #include 
          void test1(int arr[])  //首元素的地址
          {
          	printf("%d\n", sizeof(arr));     //(4) 此处arr为首元素的地址
          }
          void test2(char ch[])  //首元素的地址
          {
          	printf("%d\n", sizeof(ch));    //(5) 此处ch为首元素的地址
          }
          int main()
          {
          	int arr[10] = { 0 };
          	char ch[10] = { 0 };
          	printf("%d\n", sizeof(arr));         //(1) 此处arr为整个数组
          	printf("%d\n", sizeof(ch));         //(2) 此处ch为整个数组
          	printf("%d\n", sizeof(int [10]));  //(3) 此处int [10]为数组的类型
          	test1(arr); 
          	test2(ch);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          关系操作符

          、==(等于)、=(大于等于)、!=(不相等)

          只能适用于适合的类型,对于字符串、结构体类型比较大小不适用

          关系操作符"逻辑"意义,满足比较关系,则值为1,否则值为假,常用if进行搭配使用。

          编程题:谁是凶手

          【c语言初阶】操作符全面知识总结

          思路:if与关系操作符相互搭配使用,不符合比较关系,值为0,符合关系比较,值为1

          #define _CRT_SECURE_NO_WARNINGS 1
          #include
          int main()
          {
          	char killer = 0;
          	for (killer = 'A'; killer 
          		if ((killer != 'A ') + (killer == 'C') + (killer == 'D') +( killer != 'D') == 3)
          		{
          			printf("killer=%c", killer);
          			break;
          		}
          	}
          	return 0;
          }
          
          	int i = 0, a = 0, b = 2, c = 3, d = 4,j=0,e=0,f=2,g=3,h=4;
          	i = a++ && ++b && d++;
          	j = e++||++f||h++;
          	printf("a = %d  b = %d  c = %d  d = %d\n", a, b, c, d);
          	printf("e = %d  f = %d  g = %d  h = %d\n", e, f, g, h);
          	return 0;
          }
          
          	int a = 1, b = 0, c = 0;
          	c = (a  b, a = a + b, a++, b = a++);
          	printf("c=%d\n", c);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          #include
          int main()
          {
              a = get_val();
              count_val(a);
              while (a > 0)
             {
               a = get_val();
               count_val(a);
             }
             return 0;
          }
          

          改写成逗号表达式,避免了数据冗余

          #include
          int main()
          {
             while(a = get_val(),count_val(a),a>0)  //逗号表达式,从左到右,依次进行计算
             {
                 ;
             }
             return 0;
          }
          

          下标引用、函数调用和结构体成员访问操作符

          [ ](下标引用操作符)

          常用于数组和指针中,操作数有两个,一个为数组名、另一个下标值,[ ]通过操作数来访问下标所对应的元素值。

          #define _CRT_SECURE_NO_WARNINGS 1
          #include 
          int main()
          {
          	int arr[4][3] = { { 1,2,3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10,11,12 } };
          	int i = 0;
          	for (i = 0; i  
          

          【c语言初阶】操作符全面知识总结

          注意点:

          下标值只能从0开始,下标值的范围为0到数组大小-1;

          指针变量[整数]==*(指针变量+/-整数)。

          ()(函数调用操作符)

          常用于函数调用中,操作数有一个或多个,函数名、函数参数(但有些函数参数为无参void)。

          ->和 .( 结构体成员变量访问操作符)

          结构体指针变量->结构体成员变量名

          结构体变量.结构体成员变量名

          结构体指针用来存储结构体变量的地址,通过该操作符,对变量中的成员进行访问,可以拿到那个变量中成员变量的值。

          #define _CRT_SECURE_NO_WARNINGS 1
          #include 
          struct Stu
          {
          	char name[10];
          	int age;
          	char sex[5];
          	double score;
          };
          void set_age1(struct Stu stu) 
          {
          	stu.age = 16;
          }
          void set_age2(struct Stu* pStu)
          {
              pStu->age = 18;//结构成员访问
          }
          int main()
          {
          	struct Stu stu;
          	struct Stu* pStu = &stu;//结构成员访问
              stu.age = 20;//结构成员访问
          	set_age1(stu);  //传值调用
          	set_age2(pStu);  //传址调用
          	printf("%d %d", stu.age, pStu->age);
          	return 0;
          }
          

          【c语言初阶】操作符全面知识总结

          操作符的属性

          操作符优先级、结合顺序、是否控制求值顺序

          如下图:

          【c语言初阶】操作符全面知识总结

          表达式求值

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

          两个相邻的操作符执行先后顺序:首先看优先级、如果优先级相同时,其次再看结合性。

          一些问题表达式:表达式求值时不能通过操作符的3个属性确定唯一计算路径

          #define _CRT_SECURE_NO_WARNINGS 1
          #include 
          int fun()
          {
          	static int count = 1;
          	return ++count;
          }
          int main()
          {
          	int answer;
          	answer = fun() - fun() * fun();
          	printf("%d\n", answer);
          	return 0;
          }
          

          此处只能通过操作符优先级确定乘法比减法先计算,但无法确定乘法两边的函数谁先调用,函数调用顺序不同,则计算的结果也不同

          【c语言初阶】操作符全面知识总结

          隐式类型转换(整形提升)

          整形提升的概念:在c语言中,整形算术运算总是以默认的整形类型的精度进行计算,为了获得这个精度,对于表达式中的字符和短整型操作数在进行整形运算时,就被转化为普通整形int类型。

          整形提升的意义:在计算机中,表达式的运算都是在cpu中相关运算器中执行计算,cpu中整形运算器的操作数规定为int字节长度,同时该长度也是cpu通用寄存器的长度,对于两个char或者short类型进行整形相关运算时,都需要先转化为cpu内整形运算器标准长度,才能被送进cpu内被执行运算。

          整形提升发生条件:对于字节数小于int类型的char、unsigned char、short、unsigned short适用。

          注意一个数发生整形提升时:

          a.首先看其自己的类型,若为char、short型,为有符号位,整形提升时看最高位,提升的是符号位.。

          b.其次看在打印时,看是以什么格式进行打印,%d是打印有符号位十进制整数(将该数看成有符号数,补码转化为原码在进行打印),%u是打印无符号十进制整数(将该数看成整数,直接转化为十进制进行打印)。

          #define _CRT_SECURE_NO_WARNINGS 1
          #include 
          int main()
          {
          	char c1 = 5;
          	char c2 = 124;
          	char c3 = c1 + c2;
          	printf("%d\n", c3);
          	return 0;
          }
          

          解析如下图:

          【c语言初阶】操作符全面知识总结

          【c语言初阶】操作符全面知识总结

          算术转换

          对于大于等于Int类型数据,若某个操作符的两操作数的类型不一致,除非发生一个类型转化为另一个类型,否则就无法进行该操作。

          寻常算术转换图:

          【c语言初阶】操作符全面知识总结

          强制类型转换:

          对于浮点数转化为整形时,无需四舍五入,直接取整数部分。eg:floae a=3.5,int b=(int)a=3。

          铁铁们,操作符全面知识总结就到此结束啦,若博主有不好的地方,请指正,欢迎铁铁们留言,请动动你们的手给作者点个👍鼓励吧,你们的鼓励就是我的动力✨

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]