回覆列表
  • 1 # 使用者8068933072948

    編譯器可以根據自身硬體來選擇合適的大小,但是需要滿足約束:short和int型至少為16位,long型至少為32位,並且short型長度不能超過int型,而int型不能超過long型。這即是說各個型別的變數長度是由編譯器來決定的,而當前主流的編譯器中一般是32位機器和64位機器中int型都是4個位元組(例如,GCC)。資料型別佔記憶體的位數實際上與作業系統的位數和編譯器(不同編譯器支援的位數可能有所不同)都有關 ,具體某種資料型別佔位元組數得編譯器根據作業系統位數兩者之間進行協調好後分配記憶體大小。具體在使用的時候如想知道具體佔記憶體的位數透過sizeof(int)可以得到準確的答案。對於0來說,它的原碼和反碼都有兩種(分別為0000 0000,1000 0000,和0000 0000, 1111 1111),但是補碼只有一種(即0000 0000),-0的補碼形式等於對應的正數0的原碼00000000,取反為11111111,加1是00000000,答案仍然是0,溢位了。整數0,小數0的補碼都只有這一種形式。同時也是說,補碼沒有1000 0000這個值(用來幹啥好呢?所以就賦給-128.。。。),其實不是的,-127的原,反,補為:1111 1111, 1000 0000, 1000 0001,因為窮舉法,補碼 1000 0000 為 -128 是不用懷疑的,所以, 8位有符號的整數取值範圍的補碼錶示 1000 0000 到 0000 0000, 再到 0111 1111 即 -128 到 0, 再到 127 最終 -128 ~ +127,中間沒有中斷,一直是往上加1的,只不過到0的時候溢位了。-128沒有原碼,也沒有反碼,都被-0佔了(分別是1000 0000和1111 1111)。一個二進位制數的補碼的補碼就是原碼!!!(2019/3/27 補充一下,一個正數的補碼的補碼是它相對應的負數的補碼,同理,一個負數的補碼的補碼是它相對應的正數的補碼,也就是說,一個正數的原碼就是它相對應的負數的補碼,懂了沒?)列舉型別enum的元素長度根據編譯器而定。在visual c++下,它和int一樣長,是4個位元組,在GCC下它會取儘可能短的長度,例如你這個列舉型別只有3種標識,那麼它是一個位元組。12的平方是int在GCC中的極限平方了,到了13的平方就會溢位,int型陣列建立20萬個沒事,建立100萬個就建立不出了,因此在陣列建立不出來時,儘量讓陣列放在函式之外,因為如果陣列太大,放在函式內有可能會崩潰,在函式之外則不會有這樣的問題。因為在函式外定義屬於全域性變數,全域性變數在靜態儲存區分配記憶體,而區域性變數是在棧上分配記憶體空間的,如果陣列太大,可能會造成棧溢位。使用static_cast可以找回存放在void指標中的值。一般用於malloc,它的返回值正是void,這叫自帶解釋。。double * dptr = static_cast<double*>(vptr);C11增加了一些新特性,and,or,not 何以取代&& || !真方便!for(expression : struct) 完全也可以用普通陣列這個語法糖,但是指標就不行,而且是值傳遞的,也就是不能修改。括號失效:有時你明明以為加了括號可以保證萬無一失,但是還是可能跑偏了,例如int c = ++b * (a+b) 因為有那個自增的運算子,整個表示式異常兇險。。。要注意int的有無符號的問題,如果不注意的話,得出的結果會非常奇怪,例如: int x = 2; char * str = "abcd"; int y = (x - strlen(str) ) / 2; printf("%d\n",y);   結果應該是 -1 但是卻得到:2147483647 。為什麼?因為strlen的返回值型別是size_t,也就是unsigned int ,與 int 混合計算時,int型別被自動轉換為unsigned int了,結果自然出乎意料。。。解決辦法就是強制轉換,變成 int y = (int)(x - strlen(str) ) / 2; 強制向有符號方向轉換(編譯器預設正好相反),所以牽扯到有符號無符號計算的問題,特別是存在討厭的自動轉換時,要倍加小心!(這裡自動轉換時,無論gcc還是cl都不提示!!!) 為了避免這些錯誤,建議,凡是在運算的時候,確保你的變數都是 signed 的。 c編譯器中,僅支援C89規範的編譯器,只支援在作用域起始部分(大括號最開始)定義變數。支援C99或者部分支援C99的編譯器, 區域性變數可以定義在任何位置。基本上絕大多數都支援了,甚至還有一部分支援for(int i),但是並不建議在C語言中用這個。早在C++98標準中就存在了auto關鍵字,那時的auto用於宣告變數為自動變數,自動變數意為擁有自動的生命期,這是多餘的,因為就算不使用auto宣告,變數依舊擁有自動的生命期,C++98中的auto多餘且極少使用,C++11已經刪除了這一用法,取而代之的是全新的auto:變數的自動型別推斷。auto可以在宣告變數的時候根據變數初始值的型別自動為此變數選擇匹配的型別。有時候不引用string標頭檔案仍然可以使用string,那是因為有可能某一個頭檔案裡包括了它自己的,不同平臺可能有不同,在這裡不要偷懶。map的值是按照key升序排列的,也就是說,自動排列。對於輸入輸出,在最後輸出回車還是空格的問題上,聰明人都用三目元表示式(i==n-1)?"\n":" ",但是注意要把表示式全部用括號括起來,為了防止編譯器分析不當,而且這種情況時有發生。如何在類似 for(auto var:set){} 這種語句裡確定var到底是不是最後一個?或者說set怎麼確定其中的值是最後一個?這裡有講究: var == *(--set.end()) 注意是自減而不是-1,--是過載了的,而-沒有過載,所以會報錯的,而且注意是前面自減才對。要用<iostream>而不要用<iostream.h>,後者只是僅僅支援字元流,而前者包含了一系列模板化的I/O類,二者在介面和執行上都是不同的。scanf 函式的返回值反映的是按照指定的格式符正確讀入的資料的個數。也就是說,可以運用while(scanf(“%d”,&x)==1){}來更加簡化沒有確定資料個數時的程式碼段,那麼,這裡只能輸入字母來結束輸入,在scanf中,回車,空格,tab鍵是無關緊要的,也就是輸入多少也不會管,只有按下空格,再按Ctrl+z,然後再按回車,才算結束輸入,這時候scanf接受的是第一個空格之前的字元,在Linux中,按下回車,再按下Ctrl+D即可結束輸入,也就是說,scanf的這種特性基本沒用,只有在ACM中有用。scanf的返回值用在什麼地方呢?用在沒有給出有多少資料,一次性輸入完就算的那種,這麼寫: while(scanf("%d %d",&m,&n)!=EOF){}感覺還方便.gets在C ++中會產生bug,而且在C11標準中 被廢除,因此不建議使用,getline(cin, str)函式只能讀取string型別,不能讀取字元陣列型別,cin.get可以讀取字元陣列型別,並且只會遇到回車而結束。用法為cin.get(ch,長度),另外需要注意的是,這個函式會將換行符留在輸入佇列中,如果連續兩次呼叫,第二次將無法讀入,應加上一個不帶引數的cin.get吃掉換行符,推薦用cin.ignore(),因為看起來自帶註釋的感覺,另外cin>>noskipws也有讀取空格字串的功能。一般的,常會有使用一次cin之後連續多次使用getline,但是,由於cin不讀入空格的特性,getline總會少輸入一行,所以正確姿勢是用cin.get()或者cin.ingnore(),感覺用後者更自帶註釋一些。"\n" 表示內容為一個回車符的字串。std::endl 是流操作子,輸出的作用和輸出 “\n” 類似,但可能略有區別。std::endl 輸出一個換行符,並立即重新整理緩衝區,由於流運算子 << 的過載,對於 ‘\n’ 和 “\n”,輸出效果相同。對於有輸出緩衝的流(例如cout、clog),如果不手動進行緩衝區重新整理操作,將在緩衝區滿後自動重新整理輸出。不過對於 cout 來說(相對於檔案輸出流等),緩衝一般體現得並不明顯。但是必要情況下使用 endl 代替 ‘\n’ 一般是個好習慣。對於無緩衝的流(例如標準錯誤輸出流cerr),重新整理是不必要的,可以直接使用 ‘\n’。fgets(buff,MAXN,fin)將讀取完整的一行存放到buff字元陣列中,而且往往是以\n結尾(除了在檔案結束前沒有遇到\n這種特殊情況)。當一個字元也沒有讀到,函式返回null。同樣有一個標準輸入板的gets(s)函式,裡面只有一個數組引數,風險較大,不建議使用。而在scanf中,是不包括\n的,但是也不能在接受字串中打上\n,回車是一個輸入完成鍵,在scanf與fgets混用時(我為什麼要混用?可能以後再也不會混用了)要注意這個點。對於上下左右和別的一些擴充套件鍵使用getch會先返回一個224,再使用一次getch()這時返回的才是掃描碼。關於memset,只用它來初始化0就行了,初始化其他的,全錯!相信我,memset函式也是以位元組為單位進行賦值的,對於int型,是四個位元組,也就是將這四個位元組設定成0x01010101, 轉換成十進位制就是16843009。memset的作用是來將一段記憶體按自己進行初始化, 並非用來進行變數初始化。值得注意的是,c++的結構體是可以有建構函式的,這也可以說,如果構造一個連結串列結構體的話,那麼就非常有用了是不是,在銷燬的時候順便釋放空間什麼的,結構體中可以包含函式;也可以定義public、private、protected資料成員,結構體定義中預設情況下的成員是public,而類定義中的預設情況下的成員是private的。類中的非static成員函式有this指標,(而struct中沒有是錯誤的,一直被誤導啊,經過測試struct的成員函式一樣具有this指標),類的關鍵字class能作為template模板的關鍵字 即template<class T> class A{}; 而struct不可以。C++中定義結構體變數時可以不加struct關鍵字,也就是說,typedef可以在c++中省掉了。不建議使用全域性物件,因為debug只能從main處進入,而類的初始化在main開始之前,所以根本沒辦法除錯。另外,由於全域性變數建立順序完全不可控,更不要讓全域性變數之間相互依賴。

    額,就先這麼多吧。。

  • 中秋節和大豐收的關聯?
  • 過年要怎樣過才覺得有意思?