日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C 的16个大坑,你能躲过几个?

發布時間:2023/12/2 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C 的16个大坑,你能躲过几个? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先說下C 和C語言有什么區別?分享一個我在知乎上看見的回答:

  • C ≈ C with classes, C with STL

  • C:面向機器編程

  • C :面向編譯器編程

C 有個很重要的特性叫RAII,個人認為可以多多使用,相當方便。

言歸正傳,下面我一個一個的列出來C 使用過程中常見的坑:

無符號整數的錯誤使用

for?(unsigned?int?i?=?10;?i?>=?0;?--i)?{?...?}

上面這段代碼會發生什么? 會死循環,這里要注意下無符號整數的使用。

容器的size()返回類型是無符號整數

std::vector? vec;vec.push_back(1); for?(auto?idx?=?vec.size();?idx?>=?0;?idx--)?{cout?<<?"=====?\n"; }

這段代碼依舊會出現死循環,原因參考上一條。

STL遍歷刪除時注意迭代器失效問題

void erase(std::vector<int> &vec, int a) { ? ?for (auto iter = vec.begin(); iter != vec.end();) { // 這個正確 ? ? ? ?if (*iter == a) { ? ? ? ? ? ?iter = vec.erase(iter); ? ? ? ?} else { ? ? ? ? ? ? iter; ? ? ? ?} ? ?}for (auto iter = vec.begin(); iter != vec.end(); iter) { ?// error ? ? ? ?if (*iter == a) { ? ? ? ? ? ?vec.erase(iter); // error ? ? ? ?} ? ?}}

std::list排序使用自己的成員方法

一般的容器排序都使用std::sort(),但是list特殊。

int?main()?{std::list?list{1,?2,?3,?2};????list.sort();????//?std::sort(list.begin(),?list.end());????for?(auto?i?:?list)?{std::cout?<<?i?<<?"?";????}????std::cout?<<?"\n";????return?0; }

注釋用/**/,而不是//

注釋用/**/,可能會出問題。原因:utf-8和ANSC(GB2312)編碼混亂后,中文注釋就亂碼了,亂碼中藏著 */,匹配錯了,導致IDE實際注釋的部分并非肉眼所見,定位極其困難,常見于Windows中。

不要返回局部變量的指針或引用

char*?func()?{char?a[3]?=?{'a',?'b',?'c'};????return?a; }

棧內存容易被污染。

浮點數判斷是否相等問題

float?f; if?(f?==?0.2)?{}?//?錯誤用法 if?(abs(f?-?0.2)?<?0.00001)?{}?//?正確用法

vector clear和swap問題

清空某個vector,可以使用swap而不是其clear方法,這樣可以更早的釋放vector內部內存。

vector?vec; vector().swap(vec); vec.clear();

vector問題

盡量不要在vector中存放bool類型,vector為了做優化,它的內部存放的其實不是bool。

條件變量

條件變量的使用有兩大問題:信號丟失和虛假喚醒,相當重要。

類型轉換

在C 中盡量使用C 風格的四種類型轉換,而不要使用C語言風格的強制類型轉換。

std::thread的使用

一定要記得join或這detach,否則會crash。

void?func()?{} int?main()?{std::thread?t(func);????if?(t.joinable())?{t.join();?//?或者t.detach();?????}????return?0; }

enum使用

盡量使用enum class替代enum,enum class 是帶有作用域的枚舉類型。

空指針使用nullptr而不是NULL

void func(char*) { ? ?cout << "char*";}void func(int) { ? ?cout << "int";} int main() { ? ? func(NULL); // 編譯失敗 error: call of overloaded ‘func(NULL)’ is ambiguous ? ?func(nullptr); // char* ? ?return 0;}

std::remove的使用

這個remove其實并沒有真正的刪除元素,需要和erase配合使用,跑一下這段代碼就知道啦。

bool isOdd(int i) { return i & 1; } void print(const std::vector<int>& vec) { ? ?for (const auto& i : vec) { ? ? ? ?std::cout << i << ' '; ? ?} ? ?std::cout << std::endl;} int main() { ? ?std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; ? ?print(v);std::remove(v.begin(), v.end(), 5); ?// error ? ?print(v);v.erase(std::remove(v.begin(), v.end(), 5), v.end()); ? ?print(v);v.erase(std::remove_if(v.begin(), v.end(), isOdd), v.end()); ? ?print(v);}

全局變量初始化問題

不同文件中的全局變量初始化順序不固定,全局變量盡量不要互相依賴,否則由于初始化順序不固定的問題,可能會導致bug產生。

END

聲明:

本文于網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯系我們刪除或授權事宜。

總結

以上是生活随笔為你收集整理的C 的16个大坑,你能躲过几个?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。