主要來源是自己多年工程經驗以及審查代碼的總結,一些和常見的網上資料原理相同,但是實際場景經常比看起來複雜,一個疏忽就中了。
以下這個代碼,都不是基於冷門語法刻意考查基本功的,真正解決起來要靠警覺,就好比熟練的司機更容易出車禍一樣。
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”);