赋值操作
1.
1 #include<iostream> 2 using namespace std; 3 4 int main() 5 { 6 int x = 2, y, z; 7 x*=( y = z = 5); cout << x << endl; // What is the x value ? 8 9 z =3; 10 x ==( y = z); cout << x <<endl; 11 x = (y==z); cout << x <<endl; 12 x = (y&z); cout << x <<endl; 13 x = (y&&z); cout << x <<endl; 14 15 y=4; 16 x = (y|z); cout << x <<endl; 17 x = (y||z); cout << x <<endl; 18 return 0; 19 }
上面的x的结果分别输出是多少?
10,10,1,3,1,7,1
2. what are the results?
1 #include <iostream> 2 using namespace std; 3 4 int Value = 3; 5 int main() 6 { 7 int Value = 10; 8 ::Value++; 9 cout << ::Value << endl; 10 cout << Value << endl; 11 return 0; 12 }
第4行的Value为全局变量。::Value表示的为全局变量。所以,结果为 4 10。
3. i++ and ++i
1 #include <iostream> 2 using namespace std; 3 4 void main() 5 { 6 int a, x; 7 for(a = 0, x= 0; a<= 1 && !x++; a++) 8 { 9 a++; 10 } 11 cout << a <<" "<< x <<endl; 12 };
第6行,初始化 a , x
第7行,a = 0, x=0 ,判定 a<=1 && !x++, 首先 a 符合条件,然后执行!x =1 满足条件。然后x++,x=1。
第9行,执行a++, a=1.
第7行,执行最后的a++, a =2。
第7行,判定a<=1, 不满足。停止执行后边的!x++。退出for循环。
第11行,打印结果为a =2, x =1 。
#include <iostream> using namespace std; void main() { int a, x; for(a = 0, x= 0; a<= 1 && !x++;) { a++; } cout << a <<" "<< x <<endl; };
同上类似,唯一不同是:
1. a = 0, x =0; 判定 a <=1 && !x++; 首先 a 符合条件,然后执行!x =1 满足条件。然后x++,x=1。
2. 循环中a++, a =1.
3. 判定a <=1 && !x++; a满足条件,执行!x++, !x=0,不符合条件。但是仍执行x++, x =2;退出循环。
4.打印a =1, x =2;
总之,要注意i++,++i的执行顺序。
4. i++和*
#include <stdio.h> void main() { int pArray[] = {6,7,8,9,10}; int *ptr = pArray; *(ptr++)+=100; printf("%d,%d \n",*ptr,*(++ptr)); }
其中,*(ptr++)+=100,执行顺序为 *ptr+=*ptr+100; ptr++ 。结果为第一元素+100。ptr指向第二个元素。当执行printf时候,参数由右向左执行。*(++ptr)为第三个元素。如果此时为*(ptr++),则为第二个元素。所以最后的输出为“8 8”。
5. 类型转换
unsigned char a = 0xA5; unsigned char b = ~a>>4; printf("b = %d\n",a);
这里a占用8个bit, 为10100101。~和>>,先执行>>4,然后~。执行结果为10100101>>4为1010,取~后,11110101,得到的结果为245。
float a = 1.0f; std::cout << (int)a <<std::endl; std::cout <<(int&)a <<std::endl;
浮点数a=1.0f 在内存中表示为,占用32个bit, 4个byte. 其中32位的描述为
符号位:0为正数,1为负数。
| 符号位(1) | 阶码(8) | 尾数(23) |
首先,把1.0f转化成二进制数,表示为1.0 x 20,其中阶码转换要0+127 =127。尾数为0。
最后的内存表示为
| 0 | 0111 1111 | 0000 0000 0000 0000 000 |
变成16进制表示为 3F80 0000, 把内存的数值强行按照(int&)进行读取为int, 则变成10进制为1065353216,即为(int&)a的结果。
从unsigned int到unsigned char的转换问题
系统将对高位进行舍去,只保留低8个bit位。
例如:
unsigned int a = 0xfffffff7; unsigned char i = (unsigned char )a; char* b = (char*)&a; printf("%08x, %08x ", i, *b);
unsigned char i, 保留的a的低8位bit的结果为f7。
对于b指针,强行识别a成char*, 保留低位结果为0xf7。当利用printf打印的时候,b被转换为int。转换的过程应该保持值不变。*b的值为0xf7,表示整数-9。
-9的补码为 0xf7, (其中9的原码为 00001001, -9的补码为9的反码+1,为11110111,为f7)。当要%08x输出负数时,符号扩展不改变其值。其中,正数扩展前面添加0,负数扩展前面添加1。
与非或问题
1. 利用表达式判定这个数是否是2N次方,不用循环语句。例如,2,4,8,16…表示为 10,100,1000,10000…, 可让X-1 变成1, 11, 111, 1111,然后作X&(X-1),如果结果是0,则是整除。最后的结果为!(X&(X-1))。
2. 考虑下面程序的计算结果
#include<iostream> void main() { int count =0; int m = 9999; while(m) { count++; m = m&(m-1); } std::cout << count <<std::endl; }
m-1 = 0010 0111 0000 1110, 则m&(m-1) = 0010 0111 0000 1110;
第二次为 m-1 = 0010 0111 0000 1101, 则m&(m-1) = 0010 0111 0000 1100…
…最后相当于查m中1的个数。答案为8。
a和b数值交换
a和b中的最大值可以通过int max = ((a+b) + abs(a-b))/2;
a和b的数值交换可以采用位异或操作。
a = a^b
b = a^b
a = a^b
关于二进制的布尔代码如下: & (and 与) | (or 或) ^(exclusive or 异或) ~(not 非)
| 0110 | 0110 | 0110 | |
| & 1100 | | 1100 | ^1100 | ~ 1100 |
| 0100 | 1110 | 1000 | 0011 |
浙公网安备 33010602011771号