算术操作符 + - * / %(取模)
- / 左右操作数都为整数,执行整数除法,只要有一个是浮点数,执行的是浮点型除法。1/2=0, 1.0/2=0.5
举一个例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a = 1;
double b = 2.0;
int c = a / b;
printf("%d\n", c);
system("pause");
return 0;
}
运行结果为0;
但是如果细心,运行时会发现编译时期的一个错误:
即证明操作符两边只要有一个是浮点数,执行的是浮点型除法。
- % (取模) 左右操作符必须为整数 6%2==0, 6%4==2
移位操作符 (二进制移位) <<(左移) >>(右移)
左移(<<):二进制序列向左移动一位,左边丢弃,右边补零。(有乘2的效果)
- 对于正数:
10: 00000000 00000000 00000000 00001010
(0)00000000 00000000 00000000 0001010(0)
左边丢弃,右边补零之后结果为:00000000 00000000 00000000 00010100 20;
- 对于负数:
-1:原码:1 (符号位)0000000 00000000 00000000 00000001
反码:1 (符号位)1111111 11111111 11111111 11111110 补码:1 (符号位)1111111 11111111 11111111 11111111 (原码取反加一)
补码左移一位: (1) 1(符号位)1111111 11111111 11111111 1111111(0)
原码 :(补码减一取反)1(符号位) 0000000 00000000 00000000 00000010 结果为:-2;
右移(>>):(相当于除2)
算数右移:右边丢弃,左边补原符号位。
逻辑右移:右边丢弃,左边补零。
算术右移和逻辑右移由编译器决定。
10: 00000000 00000000 00000000 00001010
00000000 00000000 00000000 0000101(0)
逻辑移位(右边丢弃,左边补零)后的结果为:00000000 00000000 00000000 00000101 --> 5;
位操作符 (二进制) &(按位与) |(按位或) ^(按位异或)
& 二进制序列,有0为0,全1为1; m&1==1,即m的二进制最后一位为1;
| 二进制序列,有1为1,全0为0;
^ 二进制序列,相同为0,相异为1;
赋值操作符
复合赋值符:+=,-=,*=,/=,%=,<<=,>>=,|=,&=,^=
a+=b即a=a+b;其他操作符同理。
单目操作符 !(非) -(负值) +(正值) &(取地址) sizeof (求类型长度) ~(对一个数的二进制按位取反) -- ++ *(间接访问操作符) ()强制类型转换
- !(非) a=10 !a=0; a=0 !a=1;
- &(取地址)
int main()
{
int a = 10;
printf("%p\n", &a);
system("pause");
return 0;
}
运行:
- sizeof()求类型长度,它不是函数
int main()
{
short s = 3;
int a = 10;
printf("%d\n", sizeof(s = a + 3));
printf("%d\n", s);
system("pause");
return 0;
}
运行:
sizeof(s=a+3) 放在sizeof内部的表达式不参与计算,sizeof(s=a+3)的大小由s说了算;
- ~(对一个数的二进制按位取反)
int main()
{
int a = 0;
printf("%d\n", ~a);
system("pause");
return 0;
}
a: 00000000 00000000 00000000 00000000
按位取反 11111111 11111111 11111111 11111111
减一取反 (原码) 10000000 00000000 00000000 00000001
结果为:-1;
- ++,--
b=++a ,b=--a 先将a加(减)1然后赋给b;
b=a++ , b=a-- 先将a赋给b,然后给a加(减)1;
- *(间接访问操作符)
int main()
{
int num = 10;
int * p = #
printf("%d\n", *p);
system("pause");
return 0;
}
p是指针类型,指向num的地址,*p就是num的内容;
- 强制类型转换
(int)3.14=3;
关系操作符 > >= < <= != ==
双等号为等于,单个等号为赋值;
逻辑操作符 && ||
- && 左右操作数同时为真即为真;
- || 左右操作数同时为假即为假;
条件操作符 (exp1)?exp2:exp3
exp1为真执行exp2;exp1为假执行exp3;
逗号表达式
从左向右依次执行,结果为逗号后面的值。
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d\n", c);
system("pause");
return 0;
}
依次计算a>b,a=b+10(12),a ,b=a+1(13);输出为:13
下标引用操作符
int main()
{
int arr[4] = { 1, 2, 3, 4 };
int i;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
printf("%d ", arr[i]); //即下标引用操作符
system("pause");
return 0;
}
函数调用操作符
至少接收一个操作数
eg:test() 一个操作数
test(2) 两个操作数
结构成员访问操作符
结构体在没有调用之前不占内存。
struct Stu
{
char name[20];
int age;
char sex[5];
};
int main()
{
struct Stu s;
s.age = 20;
strcpy(s.name, "zhangsan ");
strcpy(s.sex, "nan");
printf("%d %s %s", s.age, s.name, s.sex);
system("pause");
return 0;
}
struct Stu
{
char name[20];
int age;
char sex[5];
char tele[12];
};
int main()
{
struct Stu s;
struct Stu *ps = &s;
ps->age = 20;
strcpy(ps->name, "zhangsan ");
strcpy(ps->sex, "nan");
printf("%d %s %s", s.age, s.name, s.sex);
system("pause");
return 0;
}
当知道一个结构体变量时,找成员用‘.’的方式;
当知道一个结构体指针时,找成员用‘->’的方式;