1.不使用判断语句,得出两个int型变量的大值,小值。
#include "stdafx.h"
#include <iostream>
using namespace std ;
#define BIT_SIZE (sizeof(int) * 8)
int max_same(int a, int b)
{
int hash[2] = {a, b} ;
int index = (a - b) >> (BIT_SIZE-1) & 1 ; // The 31-th bit is 0 if a >= b,
// is 1 if a < b in 2'comlement.
return hash[index] ;
}
int max_diff(int a, int b)
{
// One is non-gegative while other is negative.
// Of course non-negative is bigger than negative one.
int hash[2] = {a, b} ;
int index = a >> (BIT_SIZE - 1) & 1 ; // sign bit of a : index
// 0 : 0
// 1 : 1
return hash[index] ;
}
int max(int a, int b)
{
int hash[2] = {a, b} ;
int (*fun[2])(int a, int b) = {max_same, max_diff} ;
int index = (a ^ b) >> (BIT_SIZE - 1) & 1 ; // Is 1 if 'a' & 'b' are same sign,
// otherwise is 0.
return fun[index](a, b) ;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout <<"max_same: " <<max_same(2000000000, -2000000000) <<endl ; // 溢出
cout <<"max_diff: " <<max_diff(2000000000, -2000000000) <<endl ;
cout <<"max: " <<max(2000000000, -2000000000) <<endl ; // 根据不同符号情况, 调用正确处理过程
cout <<"max: " <<max(2000000000, 0) <<endl ; // 根据相同符号情况, 调用正确处理过程
return 0;
}
对于函数 max_same 不做过多解释, 请看第一个 简单的示例.
对于函数 max_diff, 在逻辑上也是十分简单的: 一个负数和一个非负数比大小, 结果显然是非负数一定大于负数. 因此, 只要两个变量异号, 则凡是符号位是 1 的变量, 必定小于另一个 . 因为 没有减法操作 , 从而 避免了溢出的问题 .
对于最终的函数 max, 则是通过 异或运算判断两个变量是同号还是异号 . 根据不同的情况调用相对应的 max_XXXX 函数, 得到正确的结果.
2.以0开头的8进制,0x是16进制。
a>b>c;表达式优先级左到右,结果是布尔值。
3.判断x是否为2的幂。
只需要判断x中1的个数是1或0;
(i&(i-1))?false:true;
4.前置声明
结论:
前置声明只能作为指针或引用,不能定义类的对象,自然也就不能调用对象中的方法了。
而且需要注意,如果将类A的成员变量B* b;改写成B& b;的话,必须要将b在A类的构造函数中,采用初始化列表的方式初始化,否则也会出错。关于这点,详见:特殊数据类型成员变量的初始化
http://patmusing.blog.163.com/blog/static/13583496020101814811570/转自网易博客。
5.逗号表达式
优先级最低,从左到右,最后的值为表达式值。
int a[3][2]={(1,3),(2,5),(0,0)};
由于是逗号表达式,(1,3)结果为3,(2,5)结果为5.
6.\n,\r,\t
\n是换行,换到下一行,不会移到这一行的开头
\r是回车,会回到这一行的开头,不会到下一行。
\t 8个字符的空格。
1、\n 软回车:
在Windows 中表示换行且回到下一行的最开始位置。相当于Mac OS 里的 \r 的效果。
在Linux、unix 中只表示换行,但不会回到下一行的开始位置。
2、\r 软空格:
在Linux、unix 中表示返回到当行的最开始位置。
在Mac OS 中表示换行且返回到下一行的最开始位置,相当于Windows 里的 \n 的效果。
7.不用变量实现strlen
int strlen(const char* i){
return (i==NULL)?0:1+strlen(i+1);
}
8.负数的求余数操作
要注意:负数除法,求余数操作,符号与被除数符号相同。