操作符--小小操作符功能却很强大
作者:互联网
文章目录
算术操作符:
+ - * / %
\1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数
% 操作符的两个操作数必须为整数。返回的是整除之后的余数
%操作符的被除数不能是0,否则就会报错
#include <stdio.h>
int main()
{
printf("%d", -99 % 0);
return 0;
}
2、对于 / 操作符如果两个操作数都为整数,执行整数除法.而只要有浮点数执行的就是浮点数除法
#include <stdio.h>
int main()
{
printf("%d", 3/2);//打印出来的结果为1,因为是整型除法所以要用%d打印,%f打印出来为0.0000000
return 0;
}
#include <stdio.h>
int main()
{
printf("%f", 3.0/2);//或3/2.0或3.0/2.0,结果为1.500000,默认精度为6位
//因为是浮点数除法所以用的是%f,如果用%d打印结果为0
return 0;
}
移位操作符:
<< 左移操作符
>> 右移操作符注:移位操作符的操作数只能是整数,移动的是二进制位
原码反码补码
首先我们了解一个知识点
计算机中内部存储数字用的是补码
**一个整数的二进制表示有3种:**原码,反码,补码
我们规定正数的原反补码三码合一,都是一样的
对于负数的原反补码
假如int a = -1;int为四个字节
原码:直接根据数值写出的二进制序列
00000000000000000000000000000001
反码:原码的符号位不变,其他位按位取反
011111111111111111111111111111111110
补码:反码+1
011111111111111111111111111111111111
<< 左移操作符(移动的是补码)
左边丢弃,右边补0
#include <stdio.h>
int main()
int a = 1;
printf("%d", a << 2);
//00000000000000000000000000000001
//00000000000000000000000000000100
//左边丢失,右边补0,向右移2位,所以打印出来结果为4
return 0;
}
>> 右移操作符(移动的是补码)
右移操作符有两种位移方式
1、算数位移
右边丢弃,左边补原符号位的数字
2、逻辑位移
右移丢失,左边补0
#include <stdio.h>
int main()
{
int a = -1;
printf("%d", a >> 2);
//打印出来结果还是-1
//说明在这个编译器进行的是算数位移
return 0;
}
注:在a是有符号整型的负数时,位移运算的结果因编译器而异,在许多编译器会进行逻辑运算或者算数运算,不要对负数位移,无论采用哪种方式都会降低程序的可移植性
注:a<<-5标准未定义,会产生未知结果,所以要写成a>>5
位操作符:
& 按位与 按(补码二进制)位与
| 按位或 按(补码二进制)位与
^ 按位异或 按(补码二进制)位与注:他们的操作数必须是整数
& //按位与
规则:1与1为1,1与0和0与0都为0
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = a & b;
printf("%d", c);//打印结果为0
return 0;
}
//a的二进制位00000000000000000000000000000001
//b的二进制位00000000000000000000000000000010
//c的二进制位00000000000000000000000000000000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RjuxfyfD-1639971909492)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
| 按位或
规则:1与1和1与0为1,0与0为0
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = a | b;
printf("%d", c);//打印的结果为3
return 0;
}
//a的二进制位00000000000000000000000000000001
//b的二进制位00000000000000000000000000000010
//c的二进制位00000000000000000000000000000011
^ 按位异或
规则:1与1和0与0为0,只有1与0为1
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = a ^ b;
printf("%d", c);//打印的结果是3
return 0;
}
//a的二进制位00000000000000000000000000000001
//b的二进制位00000000000000000000000000000010
//c的二进制位00000000000000000000000000000011
赋值操作符:
= (+= -= *= /= %= >>= <<= &= |= ^=)复合赋值赋
赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值
int a = 1;
a=20;//将a赋值
赋值操作符可以连续使用:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
//将y+1的值赋给x,再将x赋给a
不过为了方便调试我们一般把赋值拆开来写
int a = 10;
int x = 0;
int y = 20;
x = y+1;
a = x;//这样代码看着简洁很多
复合赋值符+=,其余效果差不多,不做过多介绍
int x = 10;
x = x+10;
x += 10;//使代码看着更加简洁
单目操作符:
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
– 前置、后置–
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
! 逻辑反操作
将真(非0)变成假(0),假(0)的变成真(非0,默认为1)
#include <stdio.h>
int main()
{
int a = !0;
printf("%d", a);//结果为1
return 0;
}
#include <stdio.h>
int main()
{
int a = !1;
printf("%d", a);//结果为0
return 0;
}
-,+负值,正值
-1的话为负数,+1为正数,通常将正负省略
& 取地址和* 间接访问操作符(解引用操作符)
#include <stdio.h>
int main()
{
int a = 10;
printf("%p\n", &a);//%p打印的是地址,&a是获取a的地址,打印出来的是a的地址
int* pa = &a;相当于int*pa; pa=&a;这里的*是指针的定义,是一个双目操作符
//意思是定义一个int类型指针,然后用a的地址给p赋值;
*pa = 20;//*pa的*为解引用操作符,通过*pa找到a的地址,然后将它赋值为20
printf("%d", *pa);//打印出来为20
return 0;
}
sizeof 操作数的类型长度(以字节为单位)
它的返回类型是无符号整型
#include <stdio.h>
int main()
{
int a;
printf("%d\n", sizeof a);//计算操作数的大小时候可以不用括号,打印结果为4
printf("%d\n", sizeof(int));//计算数据类型大小时候必须要用括号,打印结果是4
return 0;
}//这正能说明sizeof不是函数
我们再来深度了解一下sizeof操作符
#include <stdio.h>
void test1(int arr[])
{
printf("%d\n", sizeof(arr));//结果是4或者8,因为数组传参相当于传递了数组首元素的地址
}//相当于传递了一个指针int*arr,所以是4或者8
void test2(char ch[])
{
printf("%d\n", sizeof(ch));//结果是4或者8
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\n", sizeof(arr));//结果是40,因为int类型为4个字节,元素为10个,所以数组大小为40
printf("%d\n", sizeof(ch));//结果是10,因为char类型为1个字节,元素为10个,所以数组大小为10
test1(arr);
test2(ch);
return 0;
}
~ 对一个数的二进制按位取反(补码的二进制位)
全部位按位取反,包括符号位
#include <stdio.h>
int main()
{
int a = 1;
int b = ~a;
printf("%d\n",b);//结果为-2,
//a的补码为00000000000000000000000000000001
//取反后b为11111111111111111111111111111110
//得到b的原码的值为10000000000000000000000000000010
printf("%d\n", a);//结果为1,说明取反不改变a的值
return 0;
}
– 前置、后置–
++ 前置、后置++
前置是先自加1(或者自减1)再使用,后置是先使用再自加1(或者自减1)
#include <stdio.h>
int main()
{
int a = 1;
int b = 1;
printf("%d\n", ++a);//结果为2,因为前置++是先自加1再使用
a = 1;//将a赋值为1,因为++会改变a的值
printf("%d\n", a++);//结果为1,因为后置++是先使用后自加
printf("%d\n", --b);//结果为0,因为前置--是先自减1再使用
b = 1;//将a赋值为1,因为--会改变a的值
printf("%d\n", b--);//结果为1,因为后置--是先使用手自减1
return 0;
}
**注:**该操作符会改变操作数的值
(类型) 强制类型转换
#include <stdio.h>
int main()
{
int a = 3.14;
printf("%d\n", a);//结果为3,虽然可以进行正常编译但是会出现警告
return 0;
}
当我们使用int a = (int)3.14;
虽然结果还是3,但是警告会消失
关系操作符:
> >= < <= != ==
比较两个操作数的大小
注:在编程时候要注意不要将==与=写反了
逻辑操作符:
&& 逻辑与
|| 逻辑或
&& 逻辑与
必须操作符两边的操作数都是真,结果才是真
#include <stdio.h>
int main()
{
printf("%d\n", 1&&0);//结果为0
return 0;
}
#include <stdio.h>
int main()
{
printf("%d\n", 1&&2);//结果为1
return 0;
}
它可以控制求值顺序
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//打印的结果为1,2,3,4
return 0;
}
这是因为a++&++b的时候,a已经为0了,后面的指令就没有继续执行了
|| 逻辑或
只要有一边为真结果就是真,只有当两边都是假才为假
#include <stdio.h>
int main()
{
printf("%d\n", 1||0);//结果为1
return 0;
}
#include <stdio.h>
int main()
{
printf("%d\n", 0||0);//结果为0
return 0;
}
它也可以控制求值顺序
#include <stdio.h>
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++||++b||d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//打印结果是2,2,3,4
return 0;
}
当前a++||++b的时候,a++为真,后面的指令就没有执行了
条件操作符:
exp1 ? exp2 : exp3(也成为三目操作符)
当exp1为真时执行exp2,否则执行exp3
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
printf("%d\n",a>b?a:b);//结果为2,因为a>b为假,所以执行b
return 0;
}
逗号表达式:
exp1, exp2, exp3, …expN
逗号表达式,就是用逗号隔开的多个表达式
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a += a, b += a, c = a + b);
printf("%d\n", c);//结果为6,结果为c=a+b的结果
return 0;
}
下标引用、函数调用和结构成员:
[ ] 下标引用操作符
( ) 函数调用操作符
访问一个结构的成员:
**. 结构体.**成员名
**-> 结构体指针->**成员名
[ ] 下标引用操作符
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", arr[1]);//两个[]不是一个意思
//第一个是创建数组时候的分隔符,第二个是下表引用操作符,用来通过数组的下标找到数组的元素
//[]的操作数有两个,数组名和下标
return 0;
}
( ) 函数调用操作符
接受一个或者多个操作数,第一个操作数是函数名,剩余的操作数就是传递给函数的参数
printf("%d",10);//printf为第一个操作数函数名
访问一个结构的成员:
. 结构体.成员名
#include <stdio.h>
struct person
{
char name[20];
int age;
float weight;
//name,age,weight为结构体成员名(结构体变量)
};//创建一个结构体
int main()
{
struct person jake = { "jake",25,65.5 };//jake为结构体变量名
printf("%s %d %.1f", jake.name, jake.age, jake.weight);
//通过结构体变量名.结构体成员名来进行访问
//打印出来的结果为jake 25 65.5
return 0;
}
->结构体指针->成员名
#include <stdio.h>
struct person
{
char name[20];
int age;
float weight;
};//创建一个结构体
int main()
{
struct person jake = { "jake",25,65.5 };
struct person* p = &jake;//创建一个结构体指针,将结构体jake的地址存入p中
printf("%s %d %.1f", p->name, p->age, p->weight);//p指向的对象的name,age,weight
//打印出来的结果为jake 25 65.5
return 0;
}
标签:小小,main,return,--,int,操作符,printf,include 来源: https://blog.csdn.net/qq_45358642/article/details/122038160