目录
前言
一、操作符分类
二、算数操作符
+:加
-:减
*:乘
/:除
%:取余
#include<stdio.h>
// 算数操作符示例代码:
int main()
{
int a = 10;
int b = 3;
printf("加法:%d\n", a + b);
printf("减法:%d\n", a - b);
printf("除法:%d\n", a / b);
printf("取余法:%d\n", a % b);
return 0;
}
三、移位操作符
<<:左移
>>:右移
四、位操作符
&:按位与
|:按位或
^:按位异或
注:他们的操作数必须是整数
//位操作符
int main()
{
int num1 = 2;
int num2 = 3;
int num3 = num1 & num2;
int num4 = num1 | num2;
int num5 = num1 ^ num2;
printf("&:%d\n", num3);
printf("|:%d\n", num4);
printf("^:%d\n", num5);
return 0;
}
五、赋值操作符
int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值。
赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
这样的代码感觉怎么样?
那同样的语义,你看看:
x = y+1;
a = x;
这样的写法是不是更加清晰爽朗而且易于调试。
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
int x = 10;
x = x+10;
x += 10;//复合赋值
//其他运算符一样的道理。这样写更加简洁。
六、单目操作符
!:逻辑反操作
-:负值
+:正值
&:取地址
sizeof:操作数的类型长度(以字节为单位)
~:对一个数的二进制按位取反
--:前置、后置--
++:前置、后置++
*:间接访问操作符(解引用操作符)
(类型):强制类型转换
6.1 逻辑反操作
//逻辑反操作
int main()
{
int a = 0;
if (!a) //当a为假时执行
{
;
}
return 0;
}
6.2 负值与正值
//正、负值
int main()
{
//将a变为-数
int a = 2;
int a = -a;
return 0;
}
6.3 取地址
//&取地址
int main()
{
//查看a的地址
int a = 2;
int* p = &a;
printf("%p\n", p);
return 0;
}
6.4 sizeof
#include <stdio.h>
int main()
{
int a = -10;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof a);//这样写行不行?
printf("%d\n", sizeof int);//这样写行不行?
return 0;
}
6.5 取反操作符
int a = 2;
a: 010
~a: 101
while(~scanf("%d", &n))
6.6 --和++操作符
//++和--运算符
//前置++和--
#include <stdio.h>
int main()
{
int a = 10;
int x = ++a;
//先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。
int y = --a;
//先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10;
return 0;
}
//后置++和--
#include <stdio.h>
int main()
{
int a = 10;
int x = a++;
//先对a先使用,再增加,这样x的值是10;之后a变成11;
int y = a--;
//先对a先使用,再自减,这样y的值是11;之后a变成10;
return 0;
}
int a = 1;
int b = (++a) + (++a) + (++a)
6.7 间接访问操作符(解引用操作符)
//*简接引用操作符
int main()
{
int a = 2;
//定义指针变量P
int* p = &a;
//访问a的值
printf("%d\n", *p);
return 0;
}
6.8 强制类型转换
//强制类型转换
int main()
{
float b = 3.0f;
int res = (int)b;
printf("%d\n", res);
return 0;
}
七、关系操作符
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
八、逻辑操作符
&&:逻辑与(并且)
||:逻辑或(或者)
九、条件操作符
//条件操作符(三目运算符)
exp1 ? exp2 : exp3
if (a > 5)
b = 3;
else
b = -3;
转换成条件表达式,是什么样?
int a = 2;
int b = 0;
int res = a>5 ? b=3 : b-3
res值为-3.
b的值为-3.
//使用条件表达式实现找两个数中较大值。
int main()
{
int a = 10;
int b = 20;
int max = a > b ? a : b;
printf("max: %d\n", max);
return 0;
}
十、逗号表达式
exp1, exp2, exp3,....expN
//代码1
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式
c是多少?
//代码2
if (a =b + 1, c=a / 2, d > 0)
//代码3
a = get_val();
count_val(a);
while (a > 0)
{
//业务处理
a = get_val();
count_val(a);
}
如果使用逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)
{
//业务处理
}
十一、下标引用、函数调用和结构成员
11.1 [] 下标引用操作符
int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
[ ]的两个操作数是arr和9。
11.2 () 函数调用操作符
#include <stdio.h>
void test1()
{
printf("hehe\n");
}
void test2(const char *str)
{
printf("%s\n", str);
}
int main()
{
test1(); //实用()作为函数调用操作符。
test2("hello bit.");//实用()作为函数调用操作符。
return 0;
}
11.3 访问结构成员操作符
. : 结构体变量.结构成员名
-> : 结构体指针->结构成员名
//结构体变量.结构体成员名
struct S
{
int a;
};
int main()
{
struct S s = { 20 };
printf("%d", s.a);
return 0;
}
struct S
{
int a;
}s;
void test(struct S* p)
{
//当然,也可以写成结构体变量.结构体成员名形式
printf("%d\n", (*p).a);
//结构体指针.结构体成员名,更加方便
printf("%d\n", p->a);
}
int main()
{
test(&s);
return 0;
}
十二、表达式求值
12.1 隐式类型转换
char a = 3;
char b = 127;
char c = a+ b;
//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0
//实例1
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if(a==0xb6)
printf("a");
if(b==0xb600)
printf("b");
if(c==0xb6000000)
printf("c");
return 0;
}
//实例2
int main()
{
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(-c));
return 0;
}
12.2 算数转换
long double
double
float
unsigned long int
long int
unsigned int
int
float f = 3.14;
int num = f;//隐式转换,会有精度丢失
num最终为3,丢失掉了0.14
12.3 操作符的属性
操作符 | 描述 | 用法示例 | 结构类型 | 结合性 | 是否控制求值顺序 |
() | 聚组 | (表达式) | 与表达 式同 | N/A | 否 |
() | 函数调用 | rexp(rexp,...,rexp) | rexp | L-R | 否 |
[ ] | 下标引用 | rexp[rexp] | lexp | L-R | 否 |
. | 访问结构成员 | lexp.member_name | lexp | L-R | 否 |
-> | 访问结构指针成员 | rexp->member_name | lexp | L-R | 否 |
++ | 后缀自增 | lexp ++ | rexp | L-R | 否 |
-- | 后缀自减 | lexp -- | rexp | L-R | 否 |
! | 逻辑反 | ! rexp | rexp | R-L | 否 |
~ | 按位取反 | ~ rexp | rexp | R-L | 否 |
+ | 单目,表示正值 | + rexp | rexp | R-L | 否 |
- | 单目,表示负值 | - rexp | rexp | R-L | 否 |
++ | 前缀自增 | ++ lexp | rexp | R-L | 否 |
-- | 前缀自减 | -- lexp | rexp | R-L | 否 |
* | 间接访问 | * rexp | lexp | R-L | 否 |
& | 取地址 | & lexp | rexp | R-L | 否 |
sizeof | 取其长度,以字节 表示 | sizeof rexp sizeof(类型) | rexp | R-L | 否 |
(类 型) | 类型转换 | (类型) rexp | rexp | R-L | 否 |
* | 乘法 | rexp * rexp | rexp | L-R | 否 |
/ | 除法 | rexp / rexp | rexp | L-R | 否 |
% | 整数取余 | rexp % rexp | rexp | L-R | 否 |
+ | 加法 | rexp + rexp | rexp | L-R | 否 |
- | 减法 | rexp - rexp | rexp | L-R | 否 |
<< | 左移位 | rexp << rexp | rexp | L-R | 否 |
>> | 右移位 | rexp >> rexp | rexp | L-R | 否 |
> | 大于 | rexp > rexp | rexp | L-R | 否 |
>= | 大于等于 | rexp >= rexp | rexp | L-R | 否 |
< | 小于 | rexp < rexp | rexp | L-R | 否 |
<= | 小于等于 | rexp <= rexp | rexp | L-R | 否 |
== | 等于 | rexp == rexp | rexp | L-R | 否 |
!= | 不等于 | rexp != rexp | rexp | L-R | 否 |
& | 位与 | rexp & rexp | rexp | L-R | 否 |
^ | 位异或 | rexp ^ rexp | rexp | L-R | 否 |
| | 位或 | rexp | rexp | rexp | L-R | 否 |
&& | 逻辑与 | rexp && rexp | rexp | L-R | 是 |
|| | 逻辑或 | rexp || rexp | rexp | L-R | 是 |
? : | 条件操作符 | rexp ? rexp : rexp | rexp | N/A | 是 |
= | 赋值 | lexp = rexp | rexp | R-L | 否 |
+= | 以...加 | lexp += rexp | rexp | R-L | 否 |
-= | 以...减 | lexp -= rexp | rexp | R-L | 否 |
*= | 以...乘 | lexp *= rexp | rexp | R-L | 否 |
/= | 以...除 | lexp /= rexp | rexp | R-L | 否 |
%= | 以...取模 | lexp %= rexp | rexp | R-L | 否 |
<<= | 以...左移 | lexp <<= rexp | rexp | R-L | 否 |
>>= | 以...右移 | lexp >>= rexp | rexp | R-L | 否 |
&= | 以...与 | lexp &= rexp | rexp | R-L | 否 |
^= | 以...异或 | lexp ^= rexp | rexp | R-L | 否 |
|= | 以...或 | lexp |= rexp | rexp | R-L | 否 |
, | 逗号 | rexp,rexp | rexp | L-R | 是 |
//表达式1
a*b + c*d + e*f
a*b
c*d
a*b + c*d
e*f
a*b + c*d + e*f
或者:
a*b
c*d
e*f
a*b + c*d
a*b + c*d + e*f
//表达式2
c + --c;
//代码3-非法表达式
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
//代码4
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer;
answer = fun() - fun() * fun();
printf( "%d\n", answer);//输出多少?
return 0;
}
//代码5
#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}