学习干货速进,小白都能看懂的C语言操作符详解

2022年8月29日12:15:24

操作符详解

分类:

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

算数操作符

+-*/%
#include<stdio.h>intmain(){//int a = 6 / 5;//printf("%d\n", a);//1//float a = 6 / 5;//printf("%f\n", a);//1.00000float a=6.0/5;printf("%f\n", a);//1.2return0;}

6/5算的结果就是商–1,所以把a改为float也没用,只能将6/5改为6.0/5或6/5.0或者6.0/5.0。

intmain(){int a=7%3;printf("%d\n", a);//1return0;}

1.除了%外,其他都能对整形或者浮点数进行运算

2.对于/操作符如果两个操作数都为整数,则执行整数除法,只要里面有浮点数则进行的是浮点数除法

3.%操作符的两操作数必须为整数,返回的是余数

求一个整数存储在内存中的二进制中1的个数

移位操作符

<< 左移操作符>> 右移操作符

左移操作符:

左边抛弃、右边补0

intmain(){int a=2;//把a的二进制位向左移动一位,最左边丢弃,右边加0//00000000000000000000000000000010//00000000000000000000000000000100---4int b= a<<1;printf("%d\n", b);//4return0;}

学习干货速进,小白都能看懂的C语言操作符详解

右移操作符:

首先右移运算分两种:

  1. 逻辑移位 左边用0填充,右边丢弃
  2. 算术移位 左边用原该值的符号位填充,右边丢弃
intmain(){int a=10;//把a的二进制数向右移动一位//00000000000000000000000000001010//1.逻辑移位 左边用0填充,右边丢弃//00000000000000000000000000000101---5//2.算术移位 左边用符号位填充,右边丢弃//00000000000000000000000000000101---5int b= a>>1;printf("%d\n", b);//5return0;}

学习干货速进,小白都能看懂的C语言操作符详解

负数可以测试出是算术移位还是逻辑移位

intmain(){int a=-1;//把a的二进制数向右移动一位//11111111111111111111111111111111//逻辑右移//01111111111111111111111111111111//00000000000000000000000000000001----1 原码//算术右移//11111111111111111111111111111111//10000000000000000000000000000001-----  -1 原码int b= a>>1;printf("%d\n", b);//-1  可以看出用的是算术右移return0;}

学习干货速进,小白都能看懂的C语言操作符详解

可以看出采用的是算术右移。

注意:对于移位运算符,不要移动负数位,这个是标准未定义的。

位操作符

&//按位与|//按位或^//按位异或
注:他们的操作数必须是整数。

按位与

intmain(){int a=3;int b=5;//& - 按(二进制)位与int c= a& b;//00000000000000000000000000000011//00000000000000000000000000000101//00000000000000000000000000000001  -- 1printf("%d\n", c);return0;}

学习干货速进,小白都能看懂的C语言操作符详解

按位或

intmain(){int a=3;int b=5;//& - 按(二进制)位与int c= a| b;//00000000000000000000000000000011--a//00000000000000000000000000000101--b//每一位进行或//00000000000000000000000000000111  -- 7printf("%d\n", c);return0;}

学习干货速进,小白都能看懂的C语言操作符详解

按位异或

intmain(){int a=3;int b=5;//& - 按(二进制)位与int c= a^ b;//00000000000000000000000000000011--a//00000000000000000000000000000101--b//每一位进行异或--相同为0,不同为1//00000000000000000000000000000110  --6printf("%d\n", c);//6return0;}

学习干货速进,小白都能看懂的C语言操作符详解

一道面试题:

不借助临时变量将两个变量的值交换

intmain(){int a=3;int b=5;printf("a=%d b=%d",a,b);
    
    a=a^b;//a^b^b=a  a^b^a=b
    b=a^b;
    a=a^b;return0;}

求一个整数存储在内存中的二进制中1的个数

//int a=7;//00000000000000000000000000000110//123//123%10  得到3//123/10=12 去掉3// %10 /10
intcount_one(int n){int count=0;while(n)//n如果不是0,二进制序列一定有1{if(n%2==1){
            count++;}
        n=n/2;}return count;}intmain(){int a=6;int ret=count_one(a);printf("%d\n",ret);return0;}

这个代码有问题的,如果a=-1时,编译的1的个数为0,

intcount_one(int n){int count=0;int i=0;for(i=0;i<32;i++){if(((n>>i)&1)==1){
            count++;}}return count;}intmain(){int a=-1;//原码:10000000000000000000000001//反码:11111111111111111111111110//补码:11111111111111111111111111//内存中存的是补码//让这个数字和1按位与//11111111111111111111111111111111//00000000000000000000000000000001//00000000000000000000000000000001//最后一位为1得到1,最后一位为0得到0int ret=count_one(a);printf("%d\n",ret);return0;}

上面的代码一定会循环32次,下面这个代码更高效

//n=n&(n-1)//每一次都让二进制序列中最右边的1消失//在n变成0之前,让n=n&(n-1),这个操作执行一次count++//n=7//111-n//110//110-n//101//100-n//011//000-nintcount_one(int n){int count=0;while(n){
        n=n&(n-1);
        count++;}return count;}intmain(){int a=-1;int ret=count_one(a);printf("%d\n",ret);return0;}

赋值操作符

intmain(){int a=0;
    a=3;//赋值操作符//与==容易混淆,判断是否相等}

赋值操作符可以连续赋值,但是不建议

intmain(){int a=10;int x=0;int y=20;
    a=x=y+1;return0;}

复合赋值符

intmain(){int a=0;
    a=a+3;
    a+=3;//简单明了
    
    a=a-10;
    a-=10;
    
    a=a>>1;
    a>>=1;
    
    a=a&1;
    a&=1;}

单目操作符

intmain(){3+5;//+ 有两个操作数 双目操作符//单目操作符-只有一个操作数的操作符return0;}

!逻辑反操作

intmain(){int a=10;//10-非零-真printf("%d\n",!a);//0//把真变成假,假变成真int flag=1;if(!flag)//flag为假时进来{}}

-负值操作符

intmain(){int a=-10;
    a=-a;
    a=+a;//正号可以省略}

&取地址操作符

intmain(){int a=10;//4个字节空间int* pa=&a;//拿到了a的地址,指针变量printf("%p\n",&a);//&-取地址操作符return0;}

*解引用操作符

intmain(){int a=10;//4个字节空间int* pa=&a;//拿到了a的地址,指针变量*pa=20;//*解引用操作符,拿到areturn0;}

sizeof操作符

操作数的类型长度(单位是字节)

intmain(){int a=10;int arr[10]={0};printf("%d\n",sizeof(arr));//计算数组的总大小printf("%d\n",sizeof(int[10]));printf("%d\n",sizeof(a));//4printf("%d\n",sizeof(int));//4return0;}
intmain(){short s=5;int a=10;printf("%d\n",sizeof(s= a+2));//2 这里没有参与运算,没有整形提升printf("%d\n", s);//5return0;}

学习干货速进,小白都能看懂的C语言操作符详解

sizeof括号中放的表达式是不参与运算的!

a+2的结果不一定会放入s里面,但是如果放进去,这个表达式的类型s说了算。

#include<stdio.h>voidtest1(int arr[]){printf("%d\n",sizeof(arr));//(2)}voidtest2(char ch[]){printf("%d\n",sizeof(ch));//(4)}intmain(){int arr[10]={0};char ch[10]={0};printf("%d\n",sizeof(arr));//(1)printf("%d\n",sizeof(ch));//(3)test1(arr);test2(ch);return0;}
问:
(1)、(2)两个地方分别输出多少?
(3)、(4)两个地方分别输出多少?

学习干货速进,小白都能看懂的C语言操作符详解

我们将数组名进行传参时,传过去的是首元素的地址,地址得用指针来接收,其实函数参数本质上是个指针,大小是4(32位)或者8(64位)。

~操作符

对一个二进制位按位取反

intmain(){int a=0;printf("%d\n",~a);//00000000000000000000000000000000//按位取反//11111111111111111111111111111111补码//%d打印的是原码//11111111111111111111111111111110反码//10000000000000000000000000000001原码//-1return0;}
intmain(){int a=14;
    a|=(1<<4);printf("%d\n",a);
    
    a&=(~(1<<4));printf("%d\n",a);//00000000000000000000000000001110 将第五位变为1//00000000000000000000000000010000//按位或//00000000000000000000000000011110 将第五位再变回0//11111111111111111111111111101111//按位与则将第五位变回0,其他位不变return0;}

++ --操作符

intmain(){//a++是表达式int a=10;//a++表达式先使用a的值,a再++int b=a++;//后置++   //先使用a,再++printf("a=%d b=%d\n",a,b);//11 10int b=++a;//前置++   先++,后使用aprintf("a=%d b=%d\n",a,b);//11 11return0;int a=10;int b=a--;//后置--   //先使用a,再--printf("a=%d b=%d\n",a,b);//int a=10;int b=--a;//前置--   //先--,再使用aprintf("a=%d b=%d\n",a,b);//int a=10;printf("%d\n",a++);}
intmain(){int a=1;int b=(++a)+(++a)+(++a)printf("%d\n",b);return0;}

错误代码,vs环境编译为12,Linux环境编译为10。

(类型)强制类型转换

intmain(){int a=3.14;printf("%d\n",a);return0;}

会出现警告,不想出现警告,可以这样做

intmain(){int a=(int)3.14;printf("%d\n",a);return0;}

关系操作符

>>=<<=!===

在编程中小心==和=不小心写错导致错误

一些关系不能用关系操作符比较的:

例如字符串的比较

逻辑操作符

&&逻辑与

||逻辑或

逻辑与和逻辑或只看真假

intmain(){int a=3;int b=5;//a&b;//按二进制位与//a&&b;//逻辑与int c=a&&b;//a,b都为真,c才为真printf("%d\n",c);return0;}
intmain(){int a=0;int b=5;int c=a||b;//只要有一个真则为真printf("%d\n",c);return0;}
intmain(){int i=0,a=0,b=2,c=3,d=4;
    i= a++&&++b&& d++;printf("a=%d b=%d c=%d d=%d",a,b,c,d);//1 2 3 4return0;}

注意:对于&&操作符,左边如果为零,编译器就不会计算右边了

对于||操作符,左边如果为1,右边就不计算了

条件操作符

三目操作符-三个操作数

表达式1?表达式2:表达式3

表达式1为真,算的是表达式2的结果,否则为表达式3的值

intmain(){int a=10;int b=20;int max=0;
    max=a>b?a:b;return0;}

逗号表达式

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

int a=1;int b=2;int c=(a>b,a=b+10,a,b=a+1);//逗号表达式

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

下标引用

intmain(){int arr[10]={1,2,3,4,5,6,7,8,9,10};//arr+4printf
  • 作者:小赵小赵福星高照~
  • 原文链接:https://blog.csdn.net/attemptendeavor/article/details/116591770
    更新时间:2022年8月29日12:15:24 ,共 6018 字。