学习干货速进,小白都能看懂的C语言操作符详解
Posted 小赵小赵福星高照~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习干货速进,小白都能看懂的C语言操作符详解相关的知识,希望对你有一定的参考价值。
操作符详解
分类:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
算数操作符
+ - * / %
#include<stdio.h>
int main()
{
//int a = 6 / 5;
//printf("%d\\n", a);//1
//float a = 6 / 5;
//printf("%f\\n", a);//1.00000
float a = 6.0 / 5;
printf("%f\\n", a);//1.2
return 0;
}
6/5算的结果就是商–1,所以把a改为float也没用,只能将6/5改为6.0/5或6/5.0或者6.0/5.0。
int main()
{
int a = 7 % 3;
printf("%d\\n", a);//1
return 0;
}
1.除了%外,其他都能对整形或者浮点数进行运算
2.对于/操作符如果两个操作数都为整数,则执行整数除法,只要里面有浮点数则进行的是浮点数除法
3.%操作符的两操作数必须为整数,返回的是余数
求一个整数存储在内存中的二进制中1的个数
移位操作符
<< 左移操作符
>> 右移操作符
左移操作符:
左边抛弃、右边补0
int main()
{
int a = 2;
//把a的二进制位向左移动一位,最左边丢弃,右边加0
//00000000000000000000000000000010
//00000000000000000000000000000100---4
int b = a << 1;
printf("%d\\n", b);//4
return 0;
}
右移操作符:
首先右移运算分两种:
- 逻辑移位 左边用0填充,右边丢弃
- 算术移位 左边用原该值的符号位填充,右边丢弃
int main()
{
int a = 10;
//把a的二进制数向右移动一位
//00000000000000000000000000001010
//1.逻辑移位 左边用0填充,右边丢弃
//00000000000000000000000000000101---5
//2.算术移位 左边用符号位填充,右边丢弃
//00000000000000000000000000000101---5
int b = a >> 1;
printf("%d\\n", b);//5
return 0;
}
负数可以测试出是算术移位还是逻辑移位
int main()
{
int a = -1;
//把a的二进制数向右移动一位
//11111111111111111111111111111111
//逻辑右移
//01111111111111111111111111111111
//00000000000000000000000000000001----1 原码
//算术右移
//11111111111111111111111111111111
//10000000000000000000000000000001----- -1 原码
int b = a >> 1;
printf("%d\\n", b);//-1 可以看出用的是算术右移
return 0;
}
可以看出采用的是算术右移。
注意:对于移位运算符,不要移动负数位,这个是标准未定义的。
位操作符
& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。
按位与
int main()
{
int a = 3;
int b = 5;
//& - 按(二进制)位与
int c = a & b;
//00000000000000000000000000000011
//00000000000000000000000000000101
//00000000000000000000000000000001 -- 1
printf("%d\\n", c);
return 0;
}
按位或
int main()
{
int a = 3;
int b = 5;
//& - 按(二进制)位与
int c = a | b;
//00000000000000000000000000000011--a
//00000000000000000000000000000101--b
//每一位进行或
//00000000000000000000000000000111 -- 7
printf("%d\\n", c);
return 0;
}
按位异或
int main()
{
int a = 3;
int b = 5;
//& - 按(二进制)位与
int c = a ^ b;
//00000000000000000000000000000011--a
//00000000000000000000000000000101--b
//每一位进行异或--相同为0,不同为1
//00000000000000000000000000000110 --6
printf("%d\\n", c);//6
return 0;
}
一道面试题:
不借助临时变量将两个变量的值交换
int main()
{
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;
return 0;
}
求一个整数存储在内存中的二进制中1的个数
//int a=7;
//00000000000000000000000000000110
//123
//123%10 得到3
//123/10=12 去掉3
// %10 /10
int count_one(int n)
{
int count=0;
while(n)//n如果不是0,二进制序列一定有1
{
if(n%2==1)
{
count++;
}
n=n/2;
}
return count;
}
int main()
{
int a=6;
int ret=count_one(a);
printf("%d\\n",ret);
return 0;
}
这个代码有问题的,如果a=-1时,编译的1的个数为0,
int count_one(int n)
{
int count=0;
int i=0;
for(i=0;i<32;i++)
{
if(((n>>i)&1)==1)
{
count++;
}
}
return count;
}
int main()
{
int a=-1;
//原码:10000000000000000000000001
//反码:11111111111111111111111110
//补码:11111111111111111111111111
//内存中存的是补码
//让这个数字和1按位与
//11111111111111111111111111111111
//00000000000000000000000000000001
//00000000000000000000000000000001
//最后一位为1得到1,最后一位为0得到0
int ret=count_one(a);
printf("%d\\n",ret);
return 0;
}
上面的代码一定会循环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-n
int count_one(int n)
{
int count=0;
while(n)
{
n=n&(n-1);
count++;
}
return count;
}
int main()
{
int a=-1;
int ret=count_one(a);
printf("%d\\n",ret);
return 0;
}
赋值操作符
int main()
{
int a=0;
a=3;//赋值操作符
//与==容易混淆,判断是否相等
}
赋值操作符可以连续赋值,但是不建议
int main()
{
int a=10;
int x=0;
int y=20;
a=x=y+1;
return 0;
}
复合赋值符
int main()
{
int a=0;
a=a+3;
a+=3;//简单明了
a=a-10;
a-=10;
a=a>>1;
a>>=1;
a=a&1;
a&=1;
}
单目操作符
int main()
{
3+5;//+ 有两个操作数 双目操作符
//单目操作符-只有一个操作数的操作符
return 0;
}
!逻辑反操作
int main()
{
int a=10;//10-非零-真
printf("%d\\n",!a);//0
//把真变成假,假变成真
int flag=1;
if(!flag)//flag为假时进来
{
}
}
-负值操作符
int main()
{
int a=-10;
a=-a;
a=+a;//正号可以省略
}
&取地址操作符
int main()
{
int a=10;//4个字节空间
int* pa=&a;//拿到了a的地址,指针变量
printf("%p\\n",&a);//&-取地址操作符
return 0;
}
*解引用操作符
int main()
{
int a=10;//4个字节空间
int* pa=&a;//拿到了a的地址,指针变量
*pa=20;//*解引用操作符,拿到a
return 0;
}
sizeof操作符
操作数的类型长度(单位是字节)
int main()
{
int a=10;
int arr[10]={0};
printf("%d\\n",sizeof(arr));//计算数组的总大小
printf("%d\\n",sizeof(int[10]));
printf("%d\\n",sizeof(a));//4
printf("%d\\n",sizeof(int));//4
return 0;
}
int main()
{
short s = 5;
int a = 10;
printf("%d\\n", sizeof(s = a + 2));//2 这里没有参与运算,没有整形提升
printf("%d\\n", s);//5
return 0;
}
sizeof括号中放的表达式是不参与运算的!
a+2的结果不一定会放入s里面,但是如果放进去,这个表达式的类型s说了算。
#include <stdio.h>
void test1(int arr[])
{
printf("%d\\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
printf("%d\\n", sizeof(ch));//(4)
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\\n", sizeof(arr));//(1)
printf("%d\\n", sizeof(ch));//(3)
test1(arr);
test2(ch);
return 0;
}
问:
(1)、(2)两个地方分别输出多少?
(3)、(4)两个地方分别输出多少?
我们将数组名进行传参时,传过去的是首元素的地址,地址得用指针来接收,其实函数参数本质上是个指针,大小是4(32位)或者8(64位)。
~操作符
对一个二进制位按位取反
int main()
{
int a=0;
printf("%d\\n",~a);
//00000000000000000000000000000000
//按位取反
//11111111111111111111111111111111补码
//%d打印的是原码
//11111111111111111111111111111110反码
//10000000000000000000000000000001原码
//-1
return 0;
}
int main()
{
int a=14;
a|=(1<<4);
printf("%d\\n",a);
a&=(~(1 << 4));
printf("%d\\n",a);
//00000000000000000000000000001110 将第五位变为1
//00000000000000000000000000010000
//按位或
//00000000000000000000000000011110 将第五位再变回0
//11111111111111111111111111101111
//按位与则将第五位变回0,其他位不变
return 0;
}
++ --操作符
int main()
{
//a++是表达式
int a=10; //a++表达式先使用a的值,a再++
int b=a++;//后置++ //先使用a,再++
printf("a=%d b=%d\\n",a,b);//11 10
int b=++a;//前置++ 先++,后使用a
printf("a=%d b=%d\\n",a,b);//11 11
return 0;
int a=10;
int b=a--;//后置-- //先使用a,再--
printf("a=%d b=%d\\n",a,b);//
int a=10;
int b=--a;//前置-- //先--,再使用a
printf("a=%d b=%d\\n",a,b);//
int a=10;
printf("%d\\n",a++);
}
int main()
{
int a=1;
int b=(++a)+(++a)+(++a)
printf("%d\\n",b);
return 0;
}
错误代码,vs环境编译为12,Linux环境编译为10。
(类型)强制类型转换
int main()
{
int a=3.14;
printf("%d\\n",a);
return 0;
}
会出现警告,不想出现警告,可以这样做
int main()
{
int a=(int)3.14;
printf("%d\\n",a);
return 0;
}
关系操作符
>
>=
<
<=
!=
==
在编程中小心==和=不小心写错导致错误
一些关系不能用关系操作符比较的:
例如字符串的比较
逻辑操作符
&&逻辑与
||逻辑或
逻辑与和逻辑或只看真假
int main()
{
int a=3;
int b=5;
//a&b;//按二进制位与
//a&&b;//逻辑与
int c=a&&b;//a,b都为真,c才为真
printf("%d\\n",c);
return 0;
}
int main()
{
int a=0;
int b=5;
int c=a||b;//只要有一个真则为真
printf("%d\\n",c);
return 0;
}
int main()
{
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 4
return 0;
}
注意:对于&&操作符,左边如果为零,编译器就不会计算右边了
对于||操作符,左边如果为1,右边就不计算了
条件操作符
三目操作符-三个操作数
表达式1?表达式2:表达式3
表达式1为真,算的是表达式2的结果,否则为表达式3的值
int main()
{
int a=10;
int b=20;
int max=0;
max=a>b?a:b;
return 0;
}
逗号表达式
逗号表达式,就是用逗号隔开的多个表达式。逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int a=1;
int b=2;
int c=(a>b,a=b+10,a,b=a+1);//逗号表达式
下标引用、函数调用、和结构成员
下标引用
int main以上是关于学习干货速进,小白都能看懂的C语言操作符详解的主要内容,如果未能解决你的问题,请参考以下文章