c语言中的操作符
记得点击查看
点击查看代码
1.算数操作符
{
a.+ 加号
b.- 减号
c.* 乘号
d./ 除号 { 计算两数相除的商,当 / 的两边都为整形时,计算结果默认为 int 。当 / 两边任意一边出现小数,计算结果为float or double}
e.% 取模 { % 计算的时两数相除后的余数,其两边必须为 int ,整除时结果为 0 }
}
2.移位操作符(只能对于 int 使用,无符号整型这里算作正数//移位操作符移动的位数不能为负数,标准未定义这种写法,所以在不同编译器中有不同结果)
{
a.<< 左移 { 对整数的补码左移一位,左边丢弃,右边补零 }
b.>> 右移 { 对整数的补码右移一位 算数移位:右边丢弃,左边补原符号位 //算数移位和逻辑移位取决于编译器,大部分是算数移位
逻辑移位:右边丢弃,左边补零
}
//整数的二进制表达有三种
(原码,反码,补码)
//对于正整数的三种表达相同,而负整数有不同的表达
//例:
【
7
00000000 00000000 00000000 00000111——32位原码
00000000 00000000 00000000 00000111——32位反码 // 由于 int 类型占据 4 个字节,所以其在内存中以32 bit的 2 进制存储,第一位为字符位,为 1 表示负数,0 为正数 ;
00000000 00000000 00000000 00000111——32位补码
-7
10000000 00000000 00000000 00000111——32位原码
11111111 11111111 11111111 11111000——32位反码 //反码就是将除字符位以外的bit位由 1 变为 0 ,由 0 变为 1 ;
11111111 11111111 11111111 11111001——32位补码 //补码就是在反码的基础上 + 1 ;
int a = 7;
int b = 0;
b = a << 1; //此时输出 b 的结果为 14 —————— 00000000 00000000 00000000 00001110
int c = -7;
b = c << 1; //此时输出 b 的结果为 -14 ————— 11111111 11111111 11111111 11110010补码 —— 11111111 11111111 11111111 11110001反码 —— 10000000 00000000 00000000 00001110原码
】
}
3.位操作符(计算时两边的操作数要为 int)
{
a.& 按位与 //与:对于两个二进制数,&的两边都为1,与的结果为1,两边只要有0,结果为0
b.| 按位或 //或:对于两个二进制数,|的两边都为0,或的结果为0,两边只要有1,结果为1
c.^ 按位异或 //异或:对于两个二进制数,相同结果为0,相异结果为1
按位的含义就是按补码的二进制位,每位单独进行比较
//例1:
int a = 8; //00000000 00000000 00000000 00001000 8的补码
int b = -4; //11111111 11111111 11111111 11111100 -4的补码
a & b = //00000000 00000000 00000000 00001000 结果的补码,由于是正数,所以原码也是这个,结果为8
a | b = //11111111 11111111 11111111 11111100 结果的补码 —— 11111111 11111111 11111111 11111011反码—— 10000000 00000000 00000000 00000100原码,结果为-4
a ^ b = //11111111 11111111 11111111 11110100 补码 —— 11111111 11111111 11111111 11110011反码 —— 10000000 00000000 00000000 00001100原码,结果为-12
//例2:
int main()
{
int a = 10;
int b = 20;
a = a ^ b;//10^20
b = a ^ b;//10^20^20 //不建立新变量,交换两个数值,只适用于int
a = a ^ b;//10^20^10 (20^20=0)
}
}
4.赋值操作符
{
a.= 赋值
赋值操作符可以连续使用
例:
int a = 10;
int b = 20;
int c = 30;
a = b = c + 10;//输出的结果为a=40,b=40
b.复合赋值操作符
+=
-=
*=
/=
%=
^=
&=
|=
<<=
>>=
例:
int a = 0;
a = a + 1;
a +=1; //这两种写法结果是相同的,其他的复合赋值操作符同理
}
5.单目操作符(只有一个操作数)
{
! 逻辑反操作//把真转为假,把假转为真,C语言中一般把0视为假,非零视为真
- 负号
+ 正号
& 取地址(字面意思,取出一个变量的首地址)
sizeof(操作数) 计算操作数的字节长度(所占内存大小,类型,变量,数组等)//sizeof后的括号在某些情况下是可以省略的
~ 对操作数按位取反
{
int a = 10; //00000000 00000000 00000000 00001010 补码
a = ~a; //11111111 11111111 11111111 11110101 结果的补码——11111111 11111111 11111111 11110100反码——10000000 00000000 00000000 00001011原码,结果为-11
a |=(1<<5);
a &=(~(1<<5))//这两个公式算出来的结果相同,这也是这些符号的一些用法,目的是对与a中存储的32位比特的任意一位进行修改
}
++ 自增 前置++:先++再使用 后置++:先使用后++ //++可以看作a = a + 1
-- 自减 前置--:先--再使用 后置--:先使用后-- //--可以看作a = a - **1
//对操作数加一或减一,**对于使用操作数的场景,其放在操作数前后产生效果不同**
* 间接访问操作符(解引用操作符)
{
int a =10;
int* p = &a;
*p = 20;//此时a中的值变为二十,*的作用就是通过p中存放的地址找到a变量,所以*p就等于a
}
(类型) 强制类型转换
{
int a = (int)58.5148951;//a现在等于58,相当于把浮点型强制转换成了整数,后面的小数位丢失了
}
}
6.关系操作符 (不是所有内容都可以用关系操作符比较)
{
> 大于
< 小于
>= 大于等于
<= 小于等于
!= 不等于
== 等于 (一定要注意不要把==写成=,一个是等于,一个是赋值)
}
7.逻辑操作符//只对真假进行判断,结果也只有0或1
{
&& 逻辑与(全真为真,一假则假)//当其左边为假,直接出结果,右边整个过程不进行计算
{
int a = 4;
int b = 3;
int c = 0;
int d = a && b//此时d的值为 1
int e = b && c//此时e的值为 0
}
|| 逻辑或(一真则真,全假为假)//当其左边为真,直接出结果,右边整个过程不进行计算
{
int a = 4;
int b = 3;
int c = 0;
int d = a || b;// 1
int e = b || c;// 1
d = 0;
e = d || c;// 0
}
}
8.条件操作符//三目操作符(从左向右依次计算)
{
表达式1 ? 表达式2 :表达式3
//表达式1如果为真,则计算表达式2,表达式2的结果为整个表达式的结果,表达式3不进行计算
//表达式1如果为假,则计算表达式3,表达式3的结果为整个表达式的结果,表达式2不进行计算
}
9.逗号表达式
{
表达式1,表达式2,表达式3,表达式4,.....,表达式n
//逗号表达式就是用逗号隔开的多个表达式,从左到右依次执行,表达式的结果就是最后一个表达式的结果
例子
{
while(a = get_val(), count_val(a),a > 0 )
{
;
}
//等价于
do
{
a=get_val();
count_val(a);
}while(a>0)
}
}
10.
{
a.下标引用操作符
[]
{
int arr[10] = { 0 };
arr[9]=10;//使用下标引用,两个操作数分别为数组名和下标数9
9[arr]=10;//两者可以交换arr[9] ---> *(arr + 9) ---> *(9 + arr) --->9[arr]
}
b.函数调用操作符
()
{
//函数定义
int ADD(int a, int b)
{
return a + b;
}
int main()
{
int a = 10;
int b = 20;
//函数调用
int c = ADD(a,b);//()就是函数调用操作符,操作数为函数名和参数,至少有一个操作数(函数名)
return 0;
}
}
c.访问结构体成员
-> 结构体指针变量 -> 成员名
. 结构体名 . 成员名
{
#include<stdio.h>
#include<string.h>
struct a
{
char name[20];
int age;
double score;
}
void set_a(struct a* s)
{
strcpy((*s).name,"zhangsan");
(*s).age = 18;
(*s).score = 100.00;
//or strcpy(s->name,"zhangsan");
// s->age = 18;
// s->score = 100.00
}
void print_a(struct a s)
{
printf("%s %d %lf",s.name,s.age,s.score);
}
int main()
{
struct a s = { 0 };
set_a (&s);
print_a(s);
return 0;
}
}
}
总结:操作符的计算顺序呢,是由优先级和结合性来共同决定的