一、移位操作符
1.1左移操作
左边丢弃,右边补0
1.2右移操作
算数右移:右边丢弃,左边补原符号位
逻辑右移:右边丢弃,左边补0
int main()
{int a = -1;int b = a >> 1;printf("b=%d\n",b);return 0;
}
原码:10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
右移一位,左边补符号位1,仍然为11111111 11111111 11111111 11111111
输出:b=-1
说明输出采用的是算数右移,a的值本身不发生变化。没有移动负数位
二、编程题
2.1 不能创建临时变量,实现两个变量的交换
方法1:(缺陷:数值太大的时候容易溢出)
int a = 3;
int b = 5;
a = a + b; //存放a与b的和
b = a - b; //(a+b)-b=a
a = a - b; // (a+b)-a
方法2:
int a = 3;
int b = 5;
a = a^b;
b = a^b; //b = (a^b)^b=a
a =a^b; //a = (a^b)^a=b
补充:
0与任意数异或都为他本身 a^0=a;
任意数与他本身异或都为0 a^a=0;
三、单目运算符
!、-、+、&、sizeof、~、++、--、*、(类型)
3.1 sizeof(字节为单位)
sizeof返回的是一个无符号整数
%d打印的是有符号整数,%u打印的是无符号整数
int a = 10;
int arr[10] = {0};
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(int [10])); //40printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof a); //sizeof是操作符,不是函数
printf("%d\n", sizeof int); //err
3.2 sizeof(s = a+2)
short s = 5;
int a = 2;
printf("%d\n", sizeof(s = a+2));
printf("%d\n", s);
//sizeof括号中的表达式不参与运算
sizeof(s = a+2)在编译时就已经完成,计算的就是s的大小;s = a+2在运行时计算,所以到运行时 没有s = a+2
3.3 ~按位取反
int main()
{int a = 0;printf("%d",~a);return 0;
}
整型数据在计算机中是以补码的形式存在的,按位取反是对补码进行取反
0的原码、反码、补码
0+:00000000 00000000 00000000
0-:10000000 11111111 00000000
0+和0-的补码都是00000000
a的大小为4个字节,共32位
// 0的补码: 00000000 00000000 00000000 00000000
//~0的补码: 11111111 11111111 11111111 11111111
//~0的反码: 11111111 11111111 11111111 11111110
//~0的原码: 10000000 00000000 00000000 00000001 = -1
四、逻辑操作符
int main()
{int i = 0, a = 0, b = 2, c = 3, d = 4;i = a++ && ++b && d++;printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);return 0;
}
输出: a = 1
b = 2
c = 3
d = 4分析: i = a++ && ++b && d++; 0&&()结果一定为0,所以后面的式子不在进行运算
a的值先为0与后面的式子&&,在+1,b,d的值不发生变化
五、逗号表达式
从左向右依次计算,但整个表达式的结果是最后一个表达式的结果
int a = 3;
int b = 5;
int c = 0;
int d = (c = 5, a = c + 3, b = a - 4, c += 5);
printf("%d\n", d); //10
a = get_val();
count_val(a);
while(a>0)
{//业务处理a = get_val();count_val(a);
}while( a = get_val(),count_val(a),a>0)
{//业务处理
}