目录
?算数操作符
?移位操作符?
?位操作符?
?赋值操作符
?单目操作符?
?关系操作符
?逻辑操作符
?条件操作符(三目操作符)?
?逗号表达式?
?下标引用、函数调用和结构成员
?结构成员访问操作符
算数操作符
? ?+? ?-? ?*? ?/? ?%
加号、减号、乘号、除号 均为我们所常见的符号。
对于 / 操作符,如果两个操作数中有一个为浮点数,则执行浮点数除法。
%(取模操作符)举例:5 / 2 = 2····1? 商为 2,余数为 1,则 5%2的值便为1。
注意:%操作符的两个操作数都需为整数。
示例:
?
移位操作符?
右操作符 >>
注意:右移操作符分为两种情况
a:算数右移(右边丢弃,左边补原符号位)
b:逻辑右移(右边丢弃,左边补0)
举例:(我们右移负数 -1)(我们来尝试了解vs编译器为那种右移方法)
负数在内存中储存的为补码? ?正数的 原码 反码 补码 相等
? ?(直接根据数值写出的二进制序列为原码)? (二进制的最左边为符号位,为1则负,为0则正)
(-1)二进制原码: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1?
? ? ? ? ? ? ? ? ? ? ? ? ? ? (原码的符号位不变,其他位对照取反为反码)
(-1)二进制反码:?1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(在反码的基础上加1,就为补码)
(-1)二进制补码: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1?
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = -1;
int b= a >> 1 ;
// 算数右移 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
// 逻辑右移 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
printf("%d", b);
return 0;
}
输出结果为:?
?
由此可见我们vs编译器进行的是算数右移。
左操作符 <<
(把 整数 的二进制位向左移动一位)(规则:左边抛弃,右边补0)
举例 :
?
位操作符?
&? 按?位 与? ?(两数二进制一一对应,0为假,1为真,有假为假,两个都为真则为真)?
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 3 ;
int b = 5 ;
int c = a & b;
// a的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
// b的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
// c的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
printf("%d", c);
return 0;
}
结果为:
?
|? 按?位 或?(两数二进制一一对应,0为假,1为真,有真为真,两个都为假则为假)
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 3 ;
int b = 5 ;
int c = a | b;
// a的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
// b的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
// c的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
printf("%d", c);
return 0;
}
结果为:?
?
^? 按?位 异 或??? ?(两数二进制一一对应,两数相同为0,两数不同1)
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 3 ;
int b = 5 ;
int c = a ^ b;
// a的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
// b的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
// c的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
printf("%d", c);
return 0;
}
结果为:
?
?赋值操作符
(?= )?为赋值? ? ?(==)为判断相等? ? ?我们要注意区分开来?
复合赋值符:??+=? ? -=? ? *=? ? /=? ? >>=? ? <<=? ? %=? ?&=? ?^=? ?|=
举例:?
?
单目操作符?
?!? 逻辑反操作
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int flag = 5;
printf("!flag=%d\n", !flag);
if (flag)
{
printf("he\n");
}
//本来flag =5 ,不为0,为真, ! flag 逻辑取反,则 ! flag 为假
if (!flag)
{
printf("yeah\n");
}
return 0;
}
结果为:
?
-? 负值? ?+? 正值? ?& 取地址?? ??(十分常见)
举例:( scanf 的基本格式)
int a=0;
scanf("%d", &a);
sizeof??(计算变量、数组、类型的大小—单位是字节—操作符)
举例1:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
char arr4[] = "abcdef";
// "abcdef\0"
printf("%d\n", sizeof (arr4) );
return 0;
}
打印结果为:
?
sizeof (“a b c d e f \0”)一共七个元素—— 7*1=7
举例2:(int 类型的大小为4,short类型的大小为2)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
short s = 5;
int a = 10;
printf("%d\n", sizeof (s = a + 2));
printf("%d\n", s);
return 0;
}
?结果为:
?
我们发现就算我们放进一个 int 类型的值进去计算,s 的空间也不会变大,其大小仍然为2。
而且我们最后打印出来s的值并未发生改变,从而sizeof括号中放的表达式是不参与运算的。
?~? ? 按?位 取反
举例:
int a = -1;
int b= ~a;
(-1)二进制原码: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1?
(-1)二进制反码:?1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
(-1)二进制补码: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1?
? ?~? ?按位取反 b=?: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
? ? ? ? ? ?结果注意:? ? ? ? b的值为0,而且a的值不改变。
? --? ? ?前置、后置 --? ? ??? ?++? ? ? 前置、后置++? ? ? ?
? ? 注意:前置 和 后置? 是不同的!?
? ?int b = a++(--);? 后置++或--,先使用,再++或--
? ?int b = --(++)a;? ? 前置++或--,先++或--,再使用
举例1:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 10;
int b = a++; // 后置++
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
结果为:
?
?举例2:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 10;
int b = ++a; // 后置++
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
结果为:
?
*? ?间接访问操作符(解引用操作符)
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 10;
printf("%p\n", &a); // & 为取地址操作符
int* pa = &a; // 这里的 * 代表 pa 为指针变量,pa是用来存放 a 的地址
*pa = 20; // *?间接访问操作符(解引用操作符) pa 根据 a 的地址将 a 的值进行改变
printf("%d\n", a);
return 0;
}
结果为:
?
(类型) 强制类型转换
举例1:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = (int)3.14; //将浮点型强制转化为整型
printf("%d\n", a);
return 0;
}
结果为:
??
?关系操作符
?? >? ? ? ??>=? ? ? ? ? ? ?<? ? ? ? ?<=? ?
(大于 大于等于? ? 小于??小于等于? ?)
? ? ? ? !=? ? ? ? ? ? ? ==
(判断不等? ? ? 判断等于? )
? 十分简单明了 不做过多解释
逻辑操作符
注意:逻辑操作符仅用来判断真假,真为1,假为0。
?&&? ? 逻辑与?? ? ??? (两数有一个为 0(假),便为0(假))
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 1 ;
int b = 2;
int c = a && b; // 逻辑与
int d = a & b; // 按位与 我们要注意区分
printf("%d\n", c);
printf("%d\n", d);
return 0;
}
? 结果为:
?
?我们可以看到 c 的结果为1,代表两数都为真(都不为0)。
? ||? ? ? 逻辑或? ??? ? ?(两数有一个不为0 (真),便为1(真))
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 2 ;
int b = 0 ;
int c = a || b; // 逻辑或
int d = a | b; // 按位或 我们要注意区分
printf("%d\n", c);
printf("%d\n", d);
return 0;
}
结果为:
?
?我们可以看到 c 的结果为1,代表两数中有一个为真,则结果为真。
例题:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf(" a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d);
return 0;
}
结果为:
?
?我们发现仅有a的值发生了改变+1,b和d 的值并未改变。
我们可以得出结论:
当从左到右执行的过程中,a++为后置++,先使用后++,但是逻辑与&&的判定为有0则为假,a最初的值便为0,所以先使用a的值,发现为假,从而直接结束执行,输出为假,导致第一个 && 后面的 b和d 都未执行就判定完了,从而输出的结果只有a的值加了1。
( ||? ?逻辑或 ,同样也遵守该原则,从左到右,如果出现不为0的数,结束执行,输出为真)
条件操作符(三目操作符)?
?exp1 ?exp2 :exp3? ? ( 书写形式 )
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 3;
int b = 0;
if (a > 5)
b = 1;
else
b = -1;
printf("%d\n", b);
// 上面代码运用三目操作符来写便为:
b= a > 5 ? 1 : -1; // 从左到右,先a是否大于5,如果大于 则b的值为1,否则为-1
printf("%d\n", b);
return 0;
}
结果为:?
?
逗号表达式?
exp1,exp2,exp3, ....expN
逗号表达式,就是用逗号隔开多个表达式。逗号表达式,从左到右依次执行。整个表达式的结果是最后一个表达式的结果。
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = 0;
int d = (c = 5, a = c + 3, b = a - 4, c += 5);
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
printf("%d\n", d);
return 0;
}
结果为:
?
下标引用、函数调用和结构成员
? ?[?]? ?下标引用操作符
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", arr[4]); //下标引用操作符
// 操作数为2个 arr和4
return 0;
}
结果为:
?
?( )函数引用操作符
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int ADD(int x,int y)
{
return x + y;
}
int main()
{
int a = 10;
int b = 20;
//函数调用
int ret = ADD(a, b); //() 函数调用操作符
printf("%d\n", ret);
return 0;
}
结果为:
?
结构成员访问操作符
? 我们可以使用该操作符来访问我们自己所创建的自定义类型
.? ? ? ?结构体变量 . 成员名? ?
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct Book
{
char name[20];
char id [20];
int price;
};
int main()
{
struct Book b = { "c语言", "c20211214", 55 };
printf("书名:%s\n", b.name);
printf("书号:%s\n", b.id);
printf("定价:%d\n", b.price);
return 0;
}
结果为:
?
->? ? ? ? ?结构体指针->成员名? ? ?
举例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct Book
{
char name[20];
char id [20];
int price;
};
int main()
{
struct Book b = { "c语言", "c20211214", 55 };
struct Book* p = &b; // 我们取 b 的地址
printf("书名:%s\n", p->name); // 指针 指向我们的对象 效果相同
printf("书号:%s\n", p->id);
printf("定价:%d\n", p->price);
return 0;
}
结果为:
?
以上便是关于 操作符详解?的全部内容了, 博主创作不易? ? 喜欢可点个赞或收藏 激励博主哦!
谢谢浏览!(如有问题,请各位大神即使指出,我会及时纠正!)
|