主要来源是自己多年工程经验以及审查代码的总结,一些和常见的网上资料原理相同,但是实际场景经常比看起来复杂,一个疏忽就中了。
以下这个代码,都不是基于冷门语法刻意考查基本功的,真正解决起来要靠警觉,就好比熟练的司机更容易出车祸一样。
bool less(char* s1, char* s2)
{
reutrn s1 == s2; //不要小看这个问题,看都看见,但是写个模板,看不到类型时,容易疏忽
}
void percent(float cur, float base)
{
if(base == 0)
printf("error\n");
else
printf("%.2f", cur * 100 / base); //溢出风险很大,先除后乘
}
struct node
{
int data;
struct node2 d2;
};
struct node2
{
int data;
struct node d1; //循环引用初级问题,看题都可以答对,但面对大型工程,大量头文件,特别大的结构体,查起来麻烦的很,要养成经常用指针的习惯
};
typedef struct node_s
{
...
struct node_s* next;
} node_t;
void free_list(node_t& head) //head是哨兵,记了设置head.next = null
{
for(node_t* ptr = head.next; ptr; ptr = ptr->next)
free(ptr);
}
#define NewLine printf(“\n”); //宏分号导致下文的else语法错误,而且查起来麻烦。规范操作是不能加;
int rst = Deal();
if(rst == 1) //这里也可以规范化一下统一加{},但这会让代码变长,自由取舍,如果不加,建议备注下宏改变可能导致错误
NewLine;
else
printf(“line continue”);
typedef map<int, int> IntMap;
IntMap::iterator itr = m_data.find(K);
itr->first = K2; //关联容器是有序的(c++11提供了无序的unordered_map),这样破坏了结构,正确做法移除再添加进去
typedef map<int, int> IntMap;
IntMap::iterator itr;
for(itr = m_data.begin(); itr != m_data.end(); itr++)
{
if(itr->second <v)
m_data.erase(itr); //关联容器删除之后自增失效
}
正确写法
typedef map
IntMap;
IntMap::iterator itr;
for(itr = m_data.begin(); itr != m_data.end();)
{
if(itr->second <v)
m_data.erase(itr++);
else
itr++;
}
unsigned int i = 9; //这个经常被人意识到
size_t i = 9; //size_t是无符号的,而且是stl的标准大小类型,这个常有人犯
while(i>=0) //无符号减不出负值
{
//do something
i--;
}
string str = “hello”;
printf(“%s\n”, str); //看题都容易找出来,但实际工作中,尤其是模板等,还是容易遇到的,标准做法是将格式化统一到一处函数内
cout << str << endl;
int i;
for(i = 0; i < 10; i++)
{
if(str[i] == ‘\0’)
break;
}
if(str[i] == ‘\0’) //是初级问题没错,但是溢出经常还是有效的内存并且是0,逻辑测试通过
printf(“yes”); //借助工具倒是容易查出来但如果是自定义内存管理,经常要头疼的去查问题了
else
printf(“no”);