取模%
5%2=1;
-9%4=-1;
作用对象必须是整数,无论正负。
右移操作符>>
变量>>右移位数
3>>1
移的是二进制位的补码
算术右移和逻辑右移
算术右移:左边补原符号位(大多数为计算右移)
正数:符号位为0,右移后左边补0
负数:符号位为1,因此右移后补1
-1>>1=-1
逻辑右移:左边补0
当被移数为正数,右移一位有等价于除以二。
4>>1=2
不改变原来的值
b=a<<2
a本身不变
左移操作符<<
左移后,右边都补零。
左移操作符尖端朝左,右移朝右。
按位与&、按位或|、按位异或^、按位取反~
整数的补码二进制位
按位与&:同时为1才为1。
按位或|:都为0才为0。
^按位异或:不进位的加法,相同为0,不同为1
a^0=a;
a^a=0;
*异或用于交换变量可以防止溢出
按位取反~:0变1,1变0。
反操作符!
!(ex1)
!(ex1)结果为假,表达式输出为0。
!(ex1)结果为真,表达式输出为1。(非0,默认1)
&取地址操作符,*解引用操作符
格式:&变量名
//取地址
int a=0;
scanf("%d",&a);
int*p=&a;
//解引用
*p=a;
sizeof:计算变量或数组所占内存空间大小(字节)
sizeof(变量名)/sizeof(数组名)/sizeof(类型)
sizeof(arr);//40
sizeof(int [10]);//40
sizeof(int);//4
计算数组长度:sizeof(arr)/sizeof(arr[0])
变量可以省略括号,类型不行
int a=0;
sizeof a
sizeof(int)
sizeof内表达式不运算,只求类型,表达式的结果不会传递出来。
short b =0;
int a=0;
sizeof(b=a+3);//结果为2
//b=0;
a为整型,a+3为整型但b为short型,结果截断为short型,得出结果为2
打印格式最好要zd%,sizeof的返回类型是sizeof_t,本质上是unsigned int。
条件操作符(三目操作符)
ex1?ex2:ex3;
ex1为真则执行ex2为假则执行ex3
实现选择比较大小效果
a=(a>b?a:b);
如果a大于b则a不变,a小于b则为b。
逗号表达式(ex1,ex2,ex3)
从左到右依次计算,整个表达式的结果是最右表达式结果
表达式为常数则结果为他本身,
表达式为条件判断,结果为0或非0
(2,3,4,5);
//结果为5
(1==1,1==0);
//结果为0
下标引用操作符[]
数组名[下标]
下标内可以是算术表达式
arr[i]=i[arr]=*(arr+i);
本质上arr和i都是操作数,第一种和第二种都会被处理为第三种
函数调用操作符():调用函数,传递参数。
int mian()
{
return 0;
}
操作符.
结构体成员访问:结构体变量.成员名
struct A
{
char b[10];
}i;
printf("%s",i.b);
转换类型()
格式:(转换的类型)变量名
int a=-1;
a=(unsigned int)a;
相当于a直接把二进制的补码变成原码来使用。
时间戳:
srand((unsigned int)time (NULL))
强制转换会改变数据数据的二进制。
赋值操作符=
左值为可修改符号
赋值表达式的值为所赋的值。
if(x=5)等价于if(5)
连续赋值:a=x=10+y
把10+y的值赋到x再赋给a
前置++/--,后置++/--
前置:先++后使用,后置:先使用后++。
b=a++;
//b=a
//a+=1
b=++a;
//a+=1;
//b=a;
whleh和++
while(n--)n次
while(--n)n-1次
关系操作符
判断:==
赋值:=
逻辑操作符
&&:逻辑与,同为真才为真
||:逻辑或,有一个为真就为真
短路原则:如果一个条件为假,则&&后面代码失效,一个条件为真则||后面的代码失效。
用变量接收逻辑操作符的结果,不是0就是1。
运算发生的转换
原码->反码->补码->运算,补码再变成原码计算。
加减乘除,赋值,比较也是一种运算。
整型提升和截断
原则:.字节数小于缺省整型的数据类型相加,先提升到缺省整型(32位变成4字节,64位变成8字节)再运算(补码),再将结果变回原来的类型。
整型提升:补符号位,正数补0,负数补1。
整型提升: 函数传参,算术运算(赋值,比较,运算)
函数调用打印时先整型提升到32位。
证明整形提升的存在
结果:1 4 4
结果:a会整型提升,(a为char)导致条件为假
数据的截断
放弃原来的符号位直接取后8位,并把第一位变成符号位。
整形提升时把第一位当成符号位,并补符号位。
int main()
{
int a = 0x1ff;// 1 11111111
char b = a;
int c = b;
return 0;
}
//a:1 1111 1111
//b:1111 1111
//c:11111111 11111111 11111111 1111
int a=0;
short b=1;
short c=a+b;
short 2个字节先变成4个字节和a相加,再将结果变回两个字节储存在c中。
好处:便于cpu运算,提高速度。
算术转换:多种数据类型计算时:小的先转换为大类型
int a=0;
long long b=1;
long long c=a+b;
a(int)先变成(long long) 再操作。
int a=-1;
unsigned int b=2;
b>a:false
unsigned int 和int比较,int会算术转换成unsigned int,此时-1变成一个极大的正数.
操作符的属性:优先级,结合性和结合顺序
操作符先考虑优先级,优先级高优先执行,优先级相同考虑结合性。
操作符结合性:N/A表示无结合性,R-L表示从左往右,L-R表示从右往左。
操作符结合顺序:大多数操作符为无,&&,||有控制结合顺序:短路原则。
有时仍然无法确定计算路径的代码(如:滥用++时)要尽量避免。不同的编译器结果不一样。