算数左移和逻辑左移是一样的,只是右移不一样,而且只有操作数是负数时才不一样,移位运算符的两个操作数都必须是整型类型。
判断1的个数:
int count(unsignex value)
{
for(int ones=0;value!=0;value>>1)//value!0不是指单独一位不为0,而是整个value不为0,当value中所以数都右移移位了之后,value为0(右移左边补0)
{
if(valu%2!=0)
{
ones++;
}
}}
位操作符:&,|,^分别是与,或,异或
下面例子把value的bitvalue位置1(从右往左数,第一位为第0位)
value=value|1<<bitnumber;//将1左移bitnumber位,然后和1进行或运算
把指定位置0:
value=value&~(1<<bitnumber);
测试第bivalue位是否为1:
value&1<<bitvalue
赋值:赋值表达式的值就是做操作符的新值。
a=x=y+3;等效于x=y+3;a=x;x不可以为char,否则会被截断以存储
r=s+(t=u-v)/3;等效于t=u-v;r=s+t/3注意表达式的值为左边的值
下面这个语句:
char ch;
while((ch=getchar())!=EOF){}
不能将ch定义为char,因为EOF比char所能提供的位数还要多,这也是getchar返回一个int不是char的原因。然而,上面的getchar返回值先存储于ch将导致它被截断。
单目运算符:*为间接访问操作符,例如用于指针的指向的值的访问
sizeof用于计算它的操作数的类型的长度,以字节为单位显示,它的操作数可以是类型,如int,此时计算int类型的字节数;也可以是单个变量,此时计算变量占用的字节数。
注意sizeof判断长度的函数不需要对表达式进行求值,例如sizeof(a=b+1)并没有为a赋值,它仅仅计算a占用字节数。
int c=++a;
int d=a++;
注意前缀和后缀的增值操作符都是复制后面的变量的一份拷贝给左边的值,前缀操作符是在复制之前增加变量的值,后缀操作符是复制后才增加变量的值。这些操作符的结果不是被它们所修改的变量,而是变量值的拷贝。
++a=10;这句是错误的,因为++a的结果是a增加了之后的一个拷贝值,而不是a本身,你无法向一个值进行赋值,只可以向一个变量赋值。
逻辑操作符:位操作符&,|与逻辑操作符&&,||的区别:
1,&&,||有短路原则,而&,|没有。
2,逻辑运算符用于厕所零值和非零值,而位操作符用于测比较它们对应的位。
if(a<b&&c>d)
if(a<b&c>d)
关系操作符<、>产生的值为0或者1,而&&只有全为1才为真,而&也是两个全为1才为真,所以此时这两句是等价的,但是,如果a为1,b为2,下一句语句就会有不同结果
if(a&&b)
if(a&b)
a,b都是非零值,所以第一句为真,而第二句中a,b的所有位不一定相同,每一位进行与运算后不一定为1,所以两句不相同。
逗号操作符:多用逗号分别分开多个表达式,则整个逗号表达式的值是最后那个式子的值。
if(b+1,c/2,d>0)泽判断取决于d是否大于0。
使用逗号表达式的意义:
a=getValue();
count(a);
while(a>0){
a=getValue();
count(a);
}
则可以写成:
while(a=getValue(),count(a),a>0){}
即用于将重复出现的放在一起。
如下面:
while(a<10)
b+=x,
x+=1;
这样便省略了while子句的一个大括号。注意b+=x为逗号不是分号。
访问操作符:.和->都用雨访问一个结构的成员。若果s是结构变量s.a就是访问s中a的值。但当你拥有一个指向结构的指针而不是结构本身,且欲访问它的成员时,你应该使用->而不是.
布尔值:c没有布尔值,使用整数来代替,0是假,非零都是真。一般使用下面的方法:
#define FALSE 0
#define TRUE 1
if(flag==FALSE)--1
if(!flag)--2
if(flag==TRUE)--1
if(flag)--2
注意如果flag是任意的整数值,那么第一句与第二句是不一样的,因为实际上c没有bool值,上面的值中若flag为2,那么TRUE的第一句就是错的,所以只有flag为TRUE或FALSE时才可以第一二句才等价。
左值和右值:左值就是能够出现在赋值符号左边的东西,右值是能够出现在赋值符号右边的东西。
优先级和求值得顺序:
c+--c;//这句的值并不知道,因为我们不知道加法操作数的左操作数是在自减运算符之前还是之后进行,如先自减,则第一个c的值也变化,若之后,则第一个c的值是之前的值,所以未知。
非法表达式:x,y均为有符号整型变量
x+y+1;如果x+y的结果大于整型所能容纳的值它就会产生溢出。
if(x+y+1)的结果取决于先计算x+y还是先计算y+1,因为在这两种情况下溢出的地点不同。
f()+g()+h();f要求在g之前进行(比如执行一些I/O操作或修改全局变量,g不能先于f,但编译器对于加法调用的顺序并没有限制,所以可能产生错误,因此可以将它们分开,分别进行,并用一个临时变量保存结果:
temp=f();
temp+=g();
temp+=h();