2011-05-15 75 views
3

好吧其實我已經研究瞭如何使用循環來提高我的代碼的效率,以便我可以使用特定的應該重複的代碼塊,而不必一遍又一遍地輸入代碼,並且在嘗試之後爲了使用迄今爲止學到的東西來編程,我覺得是時候進入下一章,學習如何使用控制語句來學習如何指導程序做出決定。關於C參數促銷的問題

但事情是,在我向前邁進之前,我仍然有一些問題需要任何專家對以前的東西的幫助。其實它是關於數據類型的。


A.字符類型

  1. 我提取書Ç的Primer Plus第五版如下:

有些奇怪的是,C將字符 的constans類型int而不是 char。例如,ASCII系統 與一個32位int和一個8位char 上,代碼:

char grade = 'B'; 

表示'B'作爲數值存儲在一個32位的單元 66,grade 66個存儲的ub ab 8位 單位。字符 常數的這一特性使得可以將定義 的字符常量(例如'FATE', )與以32位單元存儲的四個單獨的8位ASCII碼 進行定義。然而, 試圖僅在最後8位指定,例如恆定的char可變結果 字符 被使用,所以 可變得到值'E'

  1. 所以我讀這當然是後做的下一件事,遵循什麼它提到,那就是我試圖對一個變量的話FATE存儲與char grade並嘗試編譯,看看它會使用printf()存儲,但不是打印出字符'E',我得到的是'F'

  2. 這是否意味着書中有一些錯誤?或者有什麼我誤解了?

  3. 從上面的句子中,有一行說C將字符常量當作int類型。所以要嘗試一下,我給char類型分配一個大於255(e.x. 356)的數字。

  4. 由於356是32位int(我運行Windows 7)的範圍內,因此,我希望它會打印出356當我使用%d符。

  5. 但不是打印356,它給我100,這是最後的8位值。

  6. 這是爲什麼發生?我以爲char == int == 32-bits? (雖然它在char之前只提到了一個字節)。


B. int和浮動型

  1. 我明白當在可變的數存儲在short類型被傳遞給可變參數函數或任何隱式原型函數,它會自動升級到int類型。

  2. 這也發生在浮點型,當通過與float型浮點數字,它會被轉換爲double類型,這就是爲什麼沒有說明符的float類型,而是有隻%fdouble%Lf對於long double

  3. 但是,爲什麼有一個爲short類型說明符儘管它也有促進作用,但不是float類型?爲什麼他們不給float類型的說明符,並使用類似%hf之類的修飾符?這背後有什麼邏輯或技術?

+0

char始終是1個字節,所以當您存儲的範圍超過該範圍時,它將在未簽名時包裝。對於簽名如果它將包裝或不包裝是依賴於實現,但通常包裝到-ve。我認爲'FATE'問題與機器字節順序有關,可能與實現相關,因爲我將'E'作爲輸出。 – phoxis 2011-05-15 14:07:03

+1

如果按字節表示8位,則不表示不是。 http://www.ibm.com/developerworks/power/library/pa-ctypes1/#N1007D – Joe 2011-05-15 14:12:29

+4

請不要一次詢問10個問題。這不是一個討論論壇等等。 – 2011-05-15 14:26:47

回答

0

爲了答: 3)這是由於大,小端CPU achitectures的不同字節序。您可以在小端(即x86)上獲得第一個字節,並在大端CPU(即PPC)上獲得最後一個字節。實際上,當從char到char的轉換已完成但int中的字符以相反順序存儲時,總會得到最低8位。

7.)一個char只能保存8位,所以在你把int賦給一個char變量並且以後永遠不能從char變量恢復的時候,其他所有的東西都會被截斷。

要B: 3.)有時可能只打印int變量的最低16位,而不管上半部分是什麼。將多個整數值打包在單個變量中以進行某些優化並不罕見。這適用於整數類型,但對於不直接支持按位操作的浮點類型沒有多大意義,這可能是printf中沒有單獨的float類型說明符的原因。

+0

char至少可以容納** 8位。在測試過的機器上,它似乎只有8位,但這不是該語言的要求。 – 2011-05-15 15:33:53

1

首先,char通過定義恰好1個字節寬。然後,標準或多或少說,尺寸應該是:

sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) 

的確切大小各不相同(除了char)通過系統和編譯器,但在32位Windows與GCC和VC的大小是(AFAIK):

sizeof(short) == 2 (byte) 
sizeof(int) == sizeof(long) == 4 (byte) 

你的「F」與在這種情況下,「E」觀察是典型的字節序的問題(小與大尾數,如何存儲在內存中一個「字」)。

現在你的價值會發生什麼變化?你有一個8位寬的變量。您分配一個更大的值('FATE'356),但編譯器知道它只允許存儲8位,因此它會關閉所有其他位。

0

char是1個字節長。一個字節的位長度可以是8,16,32位長。在通用計算機中,通常字符的比特長度是8比特。所以字符可以表示的最大數量取決於字符的位長。要檢查字符檢查limits.h頭文件的位長,它在此文件中定義爲CHAR_BIT

char x = 'FATE'將取決於機器/編譯器將解釋'FATE'的字節順序。所以這取決於系統/編譯器。有人請確認/糾正這一點。

如果你的系統有8位字節,那麼當你做c = 360時,只有360的二進制表示的低8位將被存儲在變量中,因爲char數據總是分配1個字節的存儲空間。所以%d將打印100,因爲當您在變量中賦值時高位被丟失,剩下的只是低8位。

+0

假設C字節是8位。 :-) – 2011-05-15 15:31:51

+0

當然,它是隱含的,我們在通用計算機中以及大部分手持設備中都有字節可尋址內存。 – phoxis 2011-05-15 16:31:44

+0

@phosix - 我的觀點是它**可能會更大,比如16或32位(在嵌入式設備中)。在這種情況下,值360將適合char。 – 2011-05-15 16:39:13

2

很多的一個問題的問題...這裏有答案一對夫婦:

字符常量的這種特性使得它可以定義字符常量,如「FATE」,有四個獨立的8位ASCII碼存儲在一個32位單元中。但是,試圖將這種字符常量分配給char變量只會導致最後8位被使用,所以變量的值爲'E'。

這實際上是實現定義的行爲。所以是的,這本書有一個錯誤。許多關於C的書籍都假設世界上唯一的C編譯器是作者在測試示例時使用的編譯器。

作者使用的編譯器將'FATE'中的字符視爲整數的字節,'F'是最重要的字節,'E'是最不重要的字節。您的編譯器將字面值中的字符視爲交互字節,其中'F'是最不重要的字節,'E'是最重要的字節。例如,第一種方法是MSVC如何處理值,而MinGW(一種針對Windows的GCC編譯器)以第二種方式處理文字。

至於那裏是沒有格式說明printf()一個期望float,對期待double符 - 這是因爲傳遞給printf()格式化的值的變量參數列表的一部分(...printf()的原型) 。沒有鍵入這些參數的信息,所以你提到的,編譯器必須始終弘揚他們(從C99 6.5.2.2/6「函數調用」):

如果表示調用的函數表達式有不包含原型的類型,對每個參數執行整數提升,並將具有float類型的參數提升爲double。這些被稱爲默認參數促銷。

和C99 6.5.2。2/7「函數調用」

函數原型聲明符中的省略號表示會導致參數類型轉換在上次聲明的參數後停止。默認參數促銷是在結尾參數上執行的。

因此,實際上,這是不可能通過一個floatprintf() - 它總是會被提升到一個double。這就是爲什麼浮點值的格式說明符需要double

也因自動升級將被應用到short,我真的不知道,如果h符用於格式化short是嚴格要求(儘管它,如果你想有必要與n符使用寫入到位於short的流中的字符數)。它可能在C語言中,因爲它需要在那裏支持說明符,歷史原因或者我沒有想到的東西。

+0

+1是唯一一個提及具有多於1個字符的整數字符常量的值是實現定義的,如ISO C99§6.4.4.4¶10。 – ninjalj 2011-05-15 23:56:46