C语言入门Part8--操作符篇

C语言入门Part8–操作符篇

关键字: 各种操作符的介绍, 表达式求值(整型提升,算术转换)

操作符
算数操作符

算数操作符包含+ - * / %,主要分析 / 和%

/ 除法运算符
printf("%f\n", 5 / 2);//结果为0.000000
printf("%d\n", 5 / 2);//结果为2
printf("%f\n", (flout)5 / 2);//结果为2.500000
printf("%f\n", 5 / (flout)2);//结果为2.500000
printf("%f\n", (flout)(5 / 2));//结果为2.000000
% 求模运算符

对应的两个操作数都必须是整型,不能是浮点数

       printf("%d\n", 10%3);//1

       printf("%d\n", -10 % 3);//-1

       printf("%d\n", 10 % -3);//1

       printf("%d\n", -10 % -3);//-1
% / 总结
  1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
  2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。只要有浮点数执行的就是浮点数除法。
  3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
移位操作符

移位操作符包括左移<<,右移>>

  • 对正数而言左移相当于乘法,右移相当于除法
    11
    0000 1011
    左移
    11<<1
    0001 0110 , 22 , 11* 2^1
    11<<2
    0010 1100 , 44 , 11 * 2^2
    右移
    11>>1
    0000 0101 , 5
    11>>2
    0000 0010 , 2
    跟负数无关
    -1 1111 1111
    -1>>1 1111 1111
  • 计算机中位运算速度远大于+ - * /
位操作符
  • &按位与
    11 0000 1011
    13 0000 1101
    ret 0000 1001
  • |按位或
    11 0000 1011
    13 0000 1101
    ret 0000 1111
  • ^按位异或 不一样的时候进行或运算,一样的时候取0
    11 0000 1011
    13 0000 1101
    ret 0000 0110
  • 连续的数字异或可以消除重复
    A^A = 0
    (AA)B(CC) = B
位操作符的应用实例

实例一:不使用(a + b) / 2这种方式,求两个数的平均值。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int add(int m, int n)//实现两数的相加
{
	int ret = m ^ n;//1,0或0,1相加还为1
	int flag = m & n;//flag为进位标志  1,1相加会有进位
	while (flag != 0)//若flag不为0,则说明有进位  flag左移一位将进的1和ret再进行位运算,循环值无进位为止
	{
		flag = flag << 1;
		ret = ret ^ flag;
		flag = ret & flag;
	}
	return ret;
}
int div(int a, int b)//实现两数的平均值计算
{
	int ret;
	int m = ((a^b)>>1);//0,1或1,0相加求平均值时直接右移一位(二进制中右移一位相当于除以2)
	int n = a&b;//1,1相加求平均值还是原位放1,不用移位
	ret=add(m, n);//所以m+n就是求a,b平均值
	return ret;
}
int main()
{
	int a = 100;
	int b = 20;
	printf("a,b平均值为%d\n",div(a, b));
	return 0;
}

实例二:编程实现:一组数据中只有一个数字出现了一次。
其他所有数字都是成对出现的。请找出这个数字。

//用位运算求非成对出现的数字
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int arr[5] = {1,2,3,2,1};
	int len = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 1; i < len; i++)
	{
		arr[0] = arr[0] ^ arr[i];//连续的异或可以消除重复的元素 a^b^a=b  因为a^a=0,0^b=b
	}
	printf("只出现了一次的数字是%d\n", arr[0]);
	return 0;
}

实例三:求二进制1的个数

int NumberOf1(unsigned int num)

{

       int count = 0;

       while (num != 0)

       {

              if ((num & 1) != 0)

              {

                      count++;

              }

              num=num >> 1;

       }

       return count;

}

int NumberOf1(int num)

{

       int count = 0;

       while ( num!= 0)

       {

                      count++;

                      num = (num & (num - 1));

       }

       return count;

}
赋值操作符 =

还有些符合赋值操作符,如+=,-=,*=,/=,%=,>>=,<<=,
&=,|=,^=

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

<,>,>=,<=,==,!=
注意不要把 == 和 =混淆

逻辑操作符

&& 逻辑与 也称短路与
|| 逻辑或 也称短路或
注意

  • 表达式1&&表达式2
    两表达式都为真才为真,表达式1为真表达式2才执行,若表达式1为假,则表达式2不执行
  • 表达式1 || 表达式2
    若表达式1为真,则后面不再执行,表达式1为假时,才执行表达式2
#include <stdio.h>
int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++ && ++b && d++;//最终执行结果 1 2 3 4
    //i = a++||++b||d++;//最终执行结果1 3 3 4
    printf("%d %d %d %d\n", a, b, c, d);
    return 0; 
}

注意“=”是赋值符号,“==”判断相等,所以 i = a++ 为假, i = a++ && ++b && d++;表达式1为假后面不执行i = a++||++b||d++;表达式1为假,执行++b,不为零所以表达式2为真,表达式3不执行

条件操作符

exp1 ? exp2 : exp3
表达式1是否为真,为真返回表达式2,假返回表达式3
应用:不能使用if for 大于 等于等语句,比较两个数的大小。大于返回1 小于返回-1 等于返回0

int Max(int a,int b)
{
	//return a > b ? a : b;//不能用<,>所以继续转变
	return (a-b)>>31 ? -1 : (a-b ? 1 : 0);//a,b都为int类型,(a-b)>>31判断符号位,为1(即为负数),说明a<b,返回-1;为0则说明a>=b,所以要继续判断a-b的值,不为0(a>b)返回1,为0(a=b)返回0
}
逗号表达式

逗号表达式每一个都要执行,但以最后一个表达式结果作为最终结果

下标引用、函数调用和结构成员
  • 下标引用[] 和 函数调用()常用就不再赘述
  • 访问一个结构的成员
    .结构体.成员名
    ->结构体指针->成员名
struct Student
{
    char name[10];
    int age;
}stu={"caocao",99};//stu是一个全局变量
//结构体和数组都属于聚合类型 变量一旦定义,不可改变,整体初始化只有一次机会,所以不推荐定义stu

或
struct Student
{
    char name[10];
    int age;
};
在main函数中
struct Student stu2={"caocao",99};//这样的话后续改年龄或者其他信息就可以直接改
stu2.age=199;//修改年龄

或者
struct Student *pstu=NULL;
pstu->   //->指向符
表达式求值
  • CPU运算的时候都是4个字节4个字节操作的 所以CPU运算的时候会进行整型提升(即表达式中各种长度小于四个字节的类型都要先转换为int类型或unsigned int类型)
  • 整型提升无论正负高位都补符号位
    无符号数高位补0

隐形整型提升例题

char a=0xb6;
short b=0xb600;
int c=0xb6000000;
if(a==0xb6)
	printf("a");//a要进行整型提升,提升后是负数
if(b==0xb600)
	printf("b");//b要进行整型提升,提升后是负数
if(c==0xb6000000)
	printf("c");//c不需要整型提升,所以结果为真,打印c
算术转换 尽可能转换为当前表达式中最大的类型

long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛应用于计算机科学和软件开发的编程语言。它具有强大的功能和灵活性,适用于开发各种类型的应用程序。 C语言专题精讲是一个对C语言进行深入学习和讲解的系列文章或课程。它汇总了C语言相关的重要知识点和技巧,旨在帮助学习者更好地理解和运用C语言。 这个专题中的笔记涵盖了C语言的各个方面,包括基本语法、数据类型、运算符、流程控制、函数、数组、指针、结构体、文件操作等。通过系统性的学习和总结,这些笔记可以帮助学习者逐步掌握C语言的核心概念和常用技巧。 在这个专题中,学习者可以学到如何编写简单的C程序,如何使用变量和运算符进行计算,如何使用条件和循环语句控制程序流程,如何使用函数进行代码的模块化,如何使用数组和指针进行数据的处理,如何使用结构体组织复杂数据,如何进行文件的读写等等。 C语言专题精讲的目的是帮助学习者全面、深入地了解C语言的各个方面,并能够独立编写和调试简单到中等难度的C程序。通过反复实践和练习,学习者可以逐渐提高自己的编程能力,并为进一步学习更高级的编程语言打下坚实的基础。 总之,C语言专题精讲的笔记汇总是一份重要的学习资料,可以帮助学习者系统地学习和掌握C语言的基础知识和常用技巧,为他们未来的编程之路打下坚实的基石。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值