目录
1.算术操作符
+ - * / %
1. + - * / 可以作用于整数和浮点数。
2. % 操作符的两个操作数必须为整数,返回的是整除之后的余数。
3. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除
法。
操作符也就是运算符,操作符两边的数就是操作数。
例子
除了%之外的算术操作符,要有浮点数执行的就是浮点数除法,结果才可以出浮点数类型。
2.移位操作符
<< 左移操作符
>> 右移操作符
移位操作符,操作数只能是整数,并且移位是在2进制上操作的
按照一个数的正负直接写出的二进制表示的形式得到的就是原码,但是移位操作符应该作用在补码上,补码才是内存中的形式。
正数的原码、反码、补码是相同的;负数的原码、反码、补码是要经过计算的,反码的符号位不变,其他位按位取反,就是反码;补码就是反码+1。
以整型32位为例,
左移操作符 移位规则:左边抛弃、右边补0
右移操作符 移位规则:
首先右移运算分两种:
1. 逻辑移位 左边用0填充,右边丢弃
2. 算术移位 左边用原该值的符号位填充,右边丢弃
注意
1.对于移位运算符,不要移动负数位,这个是标准未定义的。 例如:
int num = 10;
num>>-1;//error
2.左移操作一位就是将整数扩大2倍
3.a<<1的结果是位移之后的效果,但是a的大小是不改变的。
3.位操作符
& 按位与
| 按位或
^ 按位异或
他们的操作数必须是整数。
& 按位与 在补码的基础上进行与的操作,全1为1,有0为0
int main()
{
int a = 3;
//补码 00000000000000000000000000000011
int b = -5;
//原码 10000000000000000000000000000101
// 11111111111111111111111111111010
// 11111111111111111111111111111011
int c = a & b;
//补码 00000000000000000000000000000011
// 11111111111111111111111111111011
// 00000000000000000000000000000011
printf("%d", c);
return 0;
}
| 按位或 在补码上二进位有1取1,两个同时为0则为0;
int main()
{
int a = 3;
//补码 00000000000000000000000000000011
int b = -5;
//原码 10000000000000000000000000000101
// 11111111111111111111111111111010
// 11111111111111111111111111111011
int c = a | b;
//补码 00000000000000000000000000000011
// 11111111111111111111111111111011
//计算 11111111111111111111111111111011
//反码 10000000000000000000000000000100
//原码 10000000000000000000000000000101
printf("%d", c);
return 0;
}
^ 按位异或,在补码上二进位相同为0,相异为1
int main()
{
int a = 3;
//补码 00000000000000000000000000000011
int b = -5;
//原码 10000000000000000000000000000101
// 11111111111111111111111111111010
// 11111111111111111111111111111011
int c = a ^ b;
//补码 00000000000000000000000000000011
// 11111111111111111111111111111011
//计算 11111111111111111111111111111000
// 10000000000000000000000000000111
//原码 10000000000000000000000000001000
printf("%d", c);
return 0;
}
4.赋值操作符
可以给变量进行修改赋值。
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;//复合赋值
其他复合赋值操作符不在赘述,使用方法和+=形式一样
5.单目操作符
单目操作符只有一个操作数,操作数就是数字,例如!1就是只有一个操作数,1+2就是两个操作数
! 逻辑取反
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
逻辑取反!在C语言中0为假,其余数字为真
int main()
{
int a = 1;
int b = !a;
printf("%d %d",a, b);
return 0;
}
上述条件为b=0。
- + 负值 正值
int a = +1;//+在程序中没有什么作用
int b = -1;
& 取地址*解引用
int main()
{
int a = 10;
printf("%p\n", &a);
int* pa = &a;//取出变量a的地址放在整型指针变量pa里面
printf("%p\n", pa);
return 0;
}
两者经常配合使用
特殊的情况就是字符串的命名和数组名,两者不用取地址符号,使用打印%p就可以输出数组或者字符串首个元素的首地址。
sizeof 操作数的类型长度(以字节为单位)
int a = 10;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof a);//可以省略括号
printf("%d\n", sizeof(int));//数据类型的括号不可以省去
int arr[10] = { 0 };
printf("%d\n", sizeof arr);//计算一个数组的大小
printf("%d\n", sizeof (arr));
printf("%d\n", sizeof(int[0]));//数组一个元素的大小
~ 对一个数的二进制按位取反
int a = 10;
// 补码 00000000000000000000000000001010
// 取反 11111111111111111111111111110101
// 反码 10000000000000000000000000001010
// 原码 10000000000000000000000000001011 -11
int b = ~a;
printf("%d", b);
前置++,前置--,先操作,后使用
int a = 10;
int b = ++a; //a=11,b=11
int a = 10;
int b = --a; //a=9,b=9
后置++,后置--,先使用,后操作
int a = 10;
int b = a++; //a=11,b=10
int a = 10;
int b = a--; //a=9,b=10
上述的++ --是带有副作用的,变量的值会发生改变。
( )类型的强制转换
float a = 10.0f;
int b = 0;
b = (int)a; // a=10
int a = (int)3.14;//a=3
不常用的
6.关系操作符
> 大于
>= 大于等于
< 小于
<= 小于等于
!= 用于测试“不相等”
== 用于测试“相等”
需要注意的
1.=和==不可以混淆,=是赋值,==是判断是否相等。
7.逻辑操作符
&& 逻辑与
|| 逻辑或判断两个表达式出现的结果
例如 a&&b
a | b | a&&b |
真 | 真 | 真 |
假 | 真 | 假 |
真 | 假 | 假 |
假 | 假 | 假 |
再看a||b
a | b | a||b |
真 | 真 | 真 |
假 | 真 | 真 |
真 | 假 | 真 |
假 | 假 | 假 |
例子
1.
int main()
{
int a = 1;
int b = 0;
if (a || b)
{
printf("hehe");
}
return 0;
}
2.判断闰年
int main()
{
int a = 1;
scanf("%d", &a);
if (((a % 4 == 0) && (a % 100 != 0)) || (a % 400 == 0))
{
printf("闰年");
}
return 0;
}
8.条件操作符(三目操作符)
exp1 ? exp2 : exp3
翻译:如果exp1成立就执行exp2式子,否则执行exp3式子。
exp1 | exp2 | exp3 |
真 | 计算 | 不计算 |
假 | 不计算 | 计算 |
例子
//代码1
int a = 10;
int b = 20;
int m = 0;
if (a > b)
m = a;
else
m = b;
//代码2
m = (a > b ? a : b);
//上述两者等价
9.逗号表达式
exp1, exp2, exp3, …expN
逗号表达式,就是用逗号隔开的多个表达式。 逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);//逗号表达式
//c是多少? c=13
if (a = b + 1, c = a / 2, d > 0)
//决定if真假的是d>0是否成立
10.下标引用、函数调用和结构成员
1.[ ] 下标引用操作符
两个操作数:一个数组名 + 一个索引值
int arr[10] = {1,2,3,4,5};
printf("%d", arr[3]);//操作数是 arr 4
2.函数调用
()函数调用操作符
函数调用操作符接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
例
int arr[10] = {1,2,3,4,5};
printf("%d", arr[3]);//()函数调用 两个操作数
int len = strlen(arr); //()函数调用 两个操作数
test() //()函数调用,没有参数,一个操作数
3.访问一个结构的成员
. 结构体. 成员名
-> 结构体指针-> 成员名
//生活中有些对象要被描述的话,不能简单使用单个内置类型
struct Book
{
char name[20];
char author[30];
int price;
};
void print1(struct Book* p)
{
printf("《%s》%s %d\n", (*p).name, (*p).author, (*p).price);
printf("《%s》%s %d\n", p->name, p->author, p->price);
//结构体指针->成员名
}
int main()
{
struct Book b1 = { "盘龙","我吃西红柿",0 };
struct Book b2 = { "超神机械师","齐佩甲",0 };
printf("《%s》%s %d\n", b1.name, b1.author, b1.price);
printf("《%s》%s %d\n", b2.name, b2.author, b2.price);
//结构体变量.成员名
print1(&b2);
//构造函数
return 0;
}