<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 練習21:高級數據類型和控制結構 > 原文:[Exercise 21: Advanced Data Types And Flow Control](http://c.learncodethehardway.org/book/ex21.html) > 譯者:[飛龍](https://github.com/wizardforcel) 這個練習是C語言中所有可用的數據類型和控制結構的摘要。它也可以作為一份參考在補完你的知識,并且不含有任何代碼。我會通過創建教學卡片的方式,讓你記住一些信息,所以你會在腦子里記住所有重要的概念。 這個練習非常有用,你應該花至少一周的時間來鞏固內容并且補全這里所沒有的元素。你應學出每個元素是什么意思,以及編寫程序來驗證你得出的結論。 ## 可用的數據類型 `int` 儲存普通的整數,默認為32位大小。 > 譯者注:`int`在32或64位環境下為32位,但它不應該被看作平臺無關的。如果需要用到平臺無關的定長整數,請使用`int(n)_t`。 `double` 儲存稍大的浮點數。 `float` 儲存稍小的浮點數。 `char` 儲存單字節字符。 `void` 表示“無類型”,用于聲明不返回任何東西的函數,或者所指類型不明的指針,例如`void *thing`。 `enum` 枚舉類型,類似于整數,也可轉換為整數,但是通過符號化的名稱訪問或設置。當`switch`語句中沒有覆蓋到所有枚舉的元素時,一些編譯器會發出警告。 ## 類型修飾符 `unsigned` 修改類型,使它不包含任何負數,同時上界變高。 `signed` 可以儲存正數和負數,但是上界會變為(大約)一半,下界變為和上界(大約)等長。 > 譯者注:符號修飾符只對`char`和`*** int`有效。`*** int`默認為`signed`,而`char`根據具體實現,可以默認為`signed`,也可以為`unsigned`。 `long` 對該類型使用較大的空間,使它能存下更大的數,通常使當前大小加倍。 `short` 對該類型使用較小的空間,使它儲存能力變小,但是占據空間也變成一半。 ## 類型限定符 `const` 表示變量在初始化后不能改變。 `volatile` 表示會做最壞的打算,編譯器不會對它做任何優化。通常僅在對變量做一些奇怪的事情時,才會用到它。 `register` 強制讓編譯器將這個變量保存在寄存器中,并且也可以無視它。目前的編譯器更善于處理在哪里存放變量,所以應該只在確定這樣會提升性能時使用它。 ## 類型轉換 C使用了一種“階梯形類型提升”的機制,它會觀察運算符兩邊的變量,并且在運算之前將較小邊的變量轉換為較大邊。這個過程按照如下順序: + long double + double + float + long long + long + int (short, char) > 譯者注:`short`和`char`會在運算之前轉換成`int`。同種類型的`unsigned`和`signed`運算,`signed`保持字節不變轉換成`unsigned`。 ## 類型大小 `stdint.h`為定長的整數類型定義了一些`typedef`,同時也有一些用于這些類型的宏。這比老的`limits.h`更加易于使用,因為它是不變的。這些類型如下: `int8_t` 8位符號整數。 `uint8_t` 8位無符號整數。 `int16_t` 16位符號整數。 `uint16_t` 16位無符號整數。 `int32_t` 32位符號整數。 `uint32_t` 32位無符號整數。 `int64_t` 64位符號整數。 `uint64_t` 64位無符號整數。 > 譯者注:當用于對類型大小有要求的特定平臺時,可以使用這些類型。如果你怕麻煩,不想處理平臺相關類型的今后潛在的擴展的話,也可以使用這些類型。 下面的模式串為`(u)int(BITS)_t`,其中前面的`u`代表`unsigned`,`BITS`是所占位數的大小。這些模式串返回了這些類型的最大(或最小)值。 `INT(N)_MAX` `N`位符號整數的最大正值,例如`INT16_MAX`。 `INT(N)_MIN` `N`位符號整數的最小負值。 `UINT(N)_MAX` `N`位無符號整數的最大正值。為什么不定義其最小值,是因為最小值是0,不可能出現負值。 > 警告 > 要注意,不要從字面上在任何頭文件中去找`INT(N)_MAX`的定義。這里的`N`應該為特定整數,比如8、16、32、64,甚至可能是128。我在這個練習中使用了這個記法,就不需要顯式寫出每一個不同的組合了。 在`stdint.h`中,對于`size_t`類型和足夠存放指針的整數也有一些宏定義,以及其它便捷類型的宏定義。編譯器至少要保證它們為某一大小,并允許它們為更大的大小。 `int_least(N)_t` 至少`N`位的整數。 `uint_least(N)_t` 至少`N`位的無符號整數。 `INT_LEAST(N)_MAX` `int_least(N)_t`類型的最大值。 `INT_LEAST(N)_MIN` `int_least(N)_t`類型的最小值。 `UINT_LEAST(N)_MAX` `uint_least(N)_t`的最大值。 `int_fast(N)_t` 與`int_least(N)_t`相似,但是是至少`N`位的“最快”整數。 `uint_fast(N)_t` 至少`N`位的“最快”無符號整數。 `INT_FAST(N)_MAX` `int_fast(N)_t`的最大值。 `INT_FAST(N)_MIN` `int_fast(N)_t`的最小值。 `UINT_FAST(N)_MAX` `uint_fast(N)_t`的最大值。 `intptr_t` 足夠存放指針的符號整數。 `uintptr_t` 足夠存放指針的無符號整數。 `INTPTR_MAX` `intptr_t`的最大值。 `INTPTR_MIN` `intptr_t`的最小值。 `UINTPTR_MAX` `uintptr_t`的最大值。 `intmax_t` 系統中可能的最大尺寸的整數類型。 `uintmax_t` 系統中可能的最大尺寸的無符號整數類型。 `INTMAX_MAX` `intmax_t`的最大值。 `INTMAX_MIN` `intmax_t`的最小值。 `UINTMAX_MAX` `uintmax_t`的最大值。 `PTRDIFF_MIN` `ptrdiff_t`的最小值。 `PTRDIFF_MAX` `ptrdiff_t`的最大值。 `SIZE_MAX` `size_t`的最大值。 ## 可用的運算符 這是一個全面的列表,關于你可以在C中使用的全部運算符。這個列表中我會標明一些東西: 二元 該運算符有左右兩個操作數:`X + Y`。 一元 該運算符作用于操作數本身`-X`。 前綴 該運算符出現在操作數之前:`++X`。 后綴 通常和前綴版本相似,但是出現在操作數之后,并且意義不同:`X++`。 三元 只有一個三元運算符,意思是“三個操作數”:`X ? Y : Z`。 ## 算數運算符 下面是基本的算數運算符,我將函數調用`()`放入其中因為它更接近“算數”運算。 `()` 函數調用。 二元 `*` 乘法。 `/` 除法。 二元 `+` 加法。 一元 `+` 無變化。 后綴 `++` 讀取變量然后自增。 前綴 `++` 自增變量然后讀取。 后綴 `--` 讀取變量然后自減。 前綴 `--` 自減變量然后讀取。 二元 `-` 減法。 一元 `-` 取反,可用于表示負數。 ## 數據運算 它們用于以不同方式和形式訪問數據。 `->` 結構體指針的成員訪問。一元`*`和`.`運算符的復合。 `.` 結構體值的成員訪問。 `[]` 取數組下標。二元`+`和一元`*`運算符的復合。 `sizeof` 取類型或變量大小。 一元 `&` 取地址。 一元 `*` 取值(提領地址)。 ## 邏輯運算符 它們用于測試變量的等性和不等性。 `!=` 不等于。 `<` 小于。 `<=` 小于等于。 `==` 等于(并不是賦值)。 `>` 大于。 `>=` 大于等于。 ## 位運算符 它們更加高級,用于修改整數的原始位。 二元 `&` 位與。 `<<` 左移。 `>>` 右移。 `^` 位異或。 `|` 位或。 `~` 取補(翻轉所有位)。 ## 布爾運算符。 用于真值測試,仔細學習三元運算符,它非常有用。 `!` 取非。 `&&` 與。 `||` 或。 `?:` 三元真值測試,`X ? Y : Z`讀作“若X則Y否則Z”。 ## 賦值運算符 復合賦值運算符在賦值同時執行運算。大多數上面的運算符都可以組成復合賦值運算符。 `=` 賦值。 `%=` 取余賦值。 `&=` 位與賦值。 `*=` 乘法賦值。 `+=` 加法賦值。 `-=` 減法賦值。 `/=` 除法賦值。 `<<=` 左移賦值。 `>>=` 右移賦值。 `^=` 位異或賦值。 `|=` 位或賦值。 ## 可用的控制結構 下面是一些你沒有接觸過的控制結構: `do-while` `do { ... } while(X);`首先執行花括號中的代碼,之后再跳出前測試`X`表達式。 `break` 放在循環中用于跳出循環。 `continue` 跳到循環尾。 `goto` 跳到你已經放置`label`的位置,你已經在`dbg.h`中看到它了,用于跳到`error`標簽。 ## 附加題 + 閱讀`stdint.h`或它的描述,寫出所有可能出現的大小定義。 + 查詢本練習的每一項,寫出它在代碼中的作用。上網瀏覽資料來研究它如何正確使用。 + 將這些信息做成教學卡片,每天看上15分鐘來記住它們。 + 創建一個程序,打印出每個類型的示例,并驗證你的研究結果是否正確。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看