欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C 語言基礎教程(我的C之旅開始了)[十]

 更新時間:2007年02月25日 00:00:00   作者:  

27. 表達式(Expression)

   表達式由運算符和操作數(shù)組成。單獨一個操作數(shù)是最簡單的表達式。請看以下例子:

                     9
                    -4
                    +5
                 3 + 6
       a * ( b/c - d )
             e = 9 / 3
           f = ++e % 3

表達式中的表達式稱為子表達式。例如:b/c 是 a * ( b/c - d ) 的子表達式。

    每個表達式都有一個值,這是 C 語言的一個重要屬性。顯而易見的,9 和 -4 的值就是 9 和 -4,3 + 6 的值就是 9 。e = 9 / 3 的值是 3 ,也就是是 = 號左邊的變量 e 被賦予的值。我們再來看看下面這個表達式:

        8 - (a = 2 * 3)

想想看,它的值是多少?沒錯,就是 2 。但是,不推薦使用這種表達式,因為可讀性太差。

28. 數(shù)組基礎(上)
 

1. 數(shù)組簡介

    數(shù)組(Array)由一系列同種數(shù)據(jù)類型的元素組成。編譯器可以從數(shù)組聲明中知道數(shù)組中元素的數(shù)目,以及這些元素的數(shù)據(jù)類型。例如:

       double dbl[20];        /* 包含 20 個 double 類型元素的數(shù)組 */
       int      c[12];        /* 包含 12 個 int 型元素的數(shù)組      */
       char    ch[40];        /* 包含 40 個 char 型元素的數(shù)組     */

方括號 [] 表明它們是數(shù)組,[] 里的數(shù)字表明數(shù)組包含的元素數(shù)目。

    數(shù)組中的元素是相鄰的,初始化之前,元素的值可能是隨機的。下圖形象地表現(xiàn)了這種相鄰關系。

       

使用數(shù)組名和下標(subscript number 或 index)就可以訪問特定的元素。下標始于 0,止于 n - 1。例如:c[0] 是數(shù)組 c 的第一個元素,而 c[11] 是它的最后一個元素,也就是第 12 個元素。

 


2. 初始化

        int c[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

如上所示,我們使用大括號中一系列逗號分隔的值來初始化數(shù)組。我們把這個稱之為初始化列表。大括號是必須的!逗號和值之間的空格可有可無。初始化后,數(shù)組 c 的第一個元素 c[0] 的值為 0,以此類推。

    下面的小程序輸出數(shù)組 iarr 中所有元素的值。

        #include <stdio.h>

        int main(void)
        {
            int iarr[4] = { 0, 1, 2, 3 };
            int i = 2;

            printf("%d\n", iarr[0]);    /* 輸出 0 */
            printf("%d\n", iarr[1]);    /* 輸出 1 */
            printf("%d\n", iarr[i]);    /* 輸出 2 */
            printf("%d\n", iarr[1+2]);  /* 輸出 3 */

            return 0;
        }

如上所示,訪問數(shù)組元素時,[] 里的可以是常量,可以是變量,也可以是表達式。[] 里還可以是返回值為整型的函數(shù)調(diào)用??傊?,只要 [] 里的值是整數(shù)類型都可以。

    注意,上面的程序,如果把 int iarr[4] = { 0, 1, 2, 3 }; 改成 int iarr[4];(即沒有初始化),則它里面的元素的值是隨機的,也就是本來就存在于那段內(nèi)存空間的值。如果改成 int iarr[4]; 后再把它放在 int main(void) 之前,則它里面的元素的值都是 0。具體原因我在后續(xù)的教程會說明。

    如果初始化列表中的值的個數(shù)少于數(shù)組元素個數(shù),則余下的元素都會被初始化為 0。例如:

        int iarr[4] = { 0, 1 };

iarr[0] 和 iarr[1] 分別為 0 和 1;iarr[2] 和 iarr[3] 都被初始化為 0。注意,初始化列表中的值的個數(shù)可以少于數(shù)組元素個數(shù),但是超過數(shù)組元素個數(shù)卻是不對的!

    初始化數(shù)組時,[] 里可以留空。例如:

        int iarr[] = { 1, 2, 3 };

編譯器會算出初始化列表中的值的個數(shù),然后構造包含那么多個元素的數(shù)組。如上例,編譯器會算出列表中一共有 3 個值,然后把 iarr 構造成包含 3 個元素的數(shù)組。例如:

        #include <stdio.h>

        int main(void)
        {
            int iarr[] = { 1, 2, 3 };

            printf("%d\n", iarr[0]);    /* 輸出 1 */
            printf("%d\n", iarr[1]);    /* 輸出 2 */
            printf("%d\n", iarr[2]);    /* 輸出 3 */

            return 0;
        }

我們可以用以下表達式算出 iarr 中元素的個數(shù):

        sizeof iarr / sizeof iarr[0]

其中,sizeof iarr 算出數(shù)組 iarr 占用的內(nèi)存大小,sizeof iarr[0] 算出 iarr[0] 占用的內(nèi)存大小(也就是數(shù)組 iarr 中每個元素占用的內(nèi)存大小),它們相除就得出 iarr 的元素個數(shù)。sizeof 是一個運算符,具體用法我以后會說。

29. 數(shù)組基礎(下)
 

1. 指派初始值(Designated Initializers)

    指派初始值這個特性是 C99 增加的,它允許我們直接初始化數(shù)組中特定的元素。C99 以前,如果我們要初始化數(shù)組中的某個元素,如第三個元素,必須同時初始化它之前的元素。例如:

        int iarr[10] = { 0, 0, 300 };

而 C99 中,我們可以這樣初始化特定的元素:

        int iarr[10] = { [2] = 300 };  /* 指派初始化 iarr[2] 為 300 */

其余的元素都會被初始化為 0 。下面我們來看一個小程序。

        #include <stdio.h>

        int main(void)
        {
            int iarr[5] = { 6, 3, [3] = 1, 5, [1] = 8};

            printf("%d\n", iarr[0]);
            printf("%d\n", iarr[1]);
            printf("%d\n", iarr[2]);
            printf("%d\n", iarr[3]);
            printf("%d\n", iarr[4]);

            return 0;
        }

輸出為:

        6
        8
        0
        1
        5

從中可以看出兩點:

    A. 如果指派初始值后面還有值,則后面的值會被用于初始化后續(xù)的元素。上例中,
       iarr[3] 被初始化為 1 ,它后續(xù)的元素 iarr[4] 被初始化為 5。

    B. 如果初始化列表中多次出現(xiàn)對某元素的初始化,則以最后一次為準。上例中,
       iarr[1] 先被初始化為 3,然后被 [1] = 8 指派初始化為 8。


2. 給數(shù)組元素賦值

    我們可以利用下標給特定的元素賦值。例如:

        int iarr[5];
        iarr[0] = 100;  /* 賦值給第一個元素 */
        iarr[4] = 120;  /* 賦值給第五個元素 */
        iarr[2] = 180;  /* 賦值給第三個元素 */

C 不允許直接使用數(shù)組對別的數(shù)組進行賦值,也不允許使用初始化列表對數(shù)組進行賦值。例如:

        int iarr_1[5] = { 1, 2, 3, 4, 5 };   /* 正確 */
        int iarr_2[5];

        iarr_2 = iarr_1;                     /* 錯誤! */
        iarr_2[5] = { 3, 4, 5, 6, 7 };       /* 錯誤! */
        iarr_2[5] = iarr_1[5];               /* 越界! */

最后一個語句發(fā)生了越界!因為這兩個數(shù)組都只有 5 個元素,而使用下標 5 訪問的是第六個元素!

 

3. 數(shù)組界限(array bounds)

    使用下標時,我們必須確保下標沒有越界。例如:

        int iarr[46];

這個數(shù)組的下標范圍是 0 到 45,確保下標沒有超出這個范圍是我們的責任,因為編譯器不會對下標越界進行檢測!

    C 標準沒有定義下標越界的后果,也就是說,當我們寫的程序中出現(xiàn)下標越界的問題,程序可能正常工作,也可能異常退出,還有可能出現(xiàn)其它奇怪的情況。

        #include <stdio.h>

        int main(void)
        {
            int var_1 = 20;
            int arr[5];
            int var_2 = 40;

            printf("var_1: %d, var_2: %d\n", var_1, var_2);

            arr[-1] = -1;
            arr[5]  =  5;

            printf("%d  %d\n", arr[-1], arr[5]);
            printf("var_1: %d, var_2: %d\n", var_1, var_2);

            return 0;
        }

上述程序使用 Dev-C++ 4.9.9.2 編譯運行的輸出為:

        var_1: 20, var_2: 40
        -1  5
        var_1: 20, var_2: -1

可見,下標越界可能改變其它變量的值。這是因為 gcc(dev-c++ 使用的 C 編譯器)把 var_2 保存于數(shù)組 arr 之前的內(nèi)存空間,所以對 arr[-1] 賦值正好改變了 var_2 的值。不同的編譯器編譯運行該程序可能會有不同的輸出,也可能會異常退出。

    C 語言的哲學是信任程序員,而且不檢測越界程序運行更快。程序編譯時有些下標的值仍然是不可知的,所以如果要檢測下標越界的話,編譯器必須在生成的目標代碼中加入額外的代碼用于程序運行時檢測下標是否越界,這就會導致程序運行速度下降。故而,為了運行效率,C 不檢測下標是否越界。


4. 指定數(shù)組元素數(shù)目

    C99 之前,聲明數(shù)組時,[] 中的值必須是大于零的整數(shù)常量。C99 中,聲明數(shù)組時,[] 中可以是變量。這就是所謂的變長數(shù)組(variable-length array,簡稱 VLA)。聲明 VLA 時,不能對其進行初始化。在后續(xù)的教程中,我會對 VLA 進行詳細講解。

        int n = 99;
        double dbl_1[4];          /* 正確 */
        double dbl_2[8/2 + 4];    /* 正確 */
        int    iar_1[-5];         /* 錯![] 中的值必須大于 0 */
        int    iar_2[0];          /* 錯![] 中的值必須大于 0 */
        int    iar_3[9.2];        /* 錯![] 中的值必須是整數(shù)類型 */
        char   ch[n];             /* C99 之前不支持! */

相關文章

  • Qt無邊框窗口拖拽和陰影的實現(xiàn)

    Qt無邊框窗口拖拽和陰影的實現(xiàn)

    自定義窗口控件的無邊框,窗口事件由于沒有系統(tǒng)自帶邊框,無法實現(xiàn)拖拽拉伸等事件的處理,本文主要介紹了Qt無邊框窗口拖拽和陰影的實現(xiàn),感興趣的可以了解一下
    2024-01-01
  • C++中拷貝構造函數(shù)的使用

    C++中拷貝構造函數(shù)的使用

    大家好,本篇文章主要講的是C++中拷貝構造函數(shù)的使用,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • C++?Qt開發(fā)之關聯(lián)容器類使用方法詳解

    C++?Qt開發(fā)之關聯(lián)容器類使用方法詳解

    當我們談論編程中的數(shù)據(jù)結構時,順序容器是不可忽視的一個重要概念,Qt?中提供了豐富的容器類,用于方便地管理和操作數(shù)據(jù),本章我們將主要學習關聯(lián)容器,主要包括?QMap?,QSet和?QHash,感興趣的朋友跟著小編一起來學習吧
    2023-12-12
  • C++實現(xiàn)讀取特定路徑下文件夾及文件名的方法

    C++實現(xiàn)讀取特定路徑下文件夾及文件名的方法

    這篇文章主要介紹了C++實現(xiàn)讀取特定路徑下文件夾及文件名的方法,需要的朋友可以參考下
    2014-07-07
  • 超詳細解析C++實現(xiàn)快速排序算法的方法

    超詳細解析C++實現(xiàn)快速排序算法的方法

    快速排序是比較快的排序方法。它的基本思想是通過一組排序?qū)⒁判虻臄?shù)據(jù)分割成獨立的兩部分,本文將用C++實現(xiàn)快速排序算法,需要的可以參考一下
    2022-09-09
  • 聊聊Qt+OpenCV聯(lián)合開發(fā)之圖像的創(chuàng)建與賦值問題

    聊聊Qt+OpenCV聯(lián)合開發(fā)之圖像的創(chuàng)建與賦值問題

    這篇文章主要介紹了Qt+OpenCV聯(lián)合開發(fā)之圖像的創(chuàng)建與賦值問題,給大家介紹了圖像的克隆及拷貝問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • C/C++程序開發(fā)中實現(xiàn)信息隱藏的三種類型

    C/C++程序開發(fā)中實現(xiàn)信息隱藏的三種類型

    這篇文章主要介紹了C/C++程序開發(fā)中實現(xiàn)信息隱藏的三種類型的相關資料,需要的朋友可以參考下
    2016-02-02
  • C++ Strassen算法代碼的實現(xiàn)

    C++ Strassen算法代碼的實現(xiàn)

    這篇文章主要介紹了C++ Strassen算法代碼的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • C++ 互斥鎖原理以及實際使用介紹

    C++ 互斥鎖原理以及實際使用介紹

    本文主要聊一聊如何使用互斥鎖以及都有哪幾種方式實現(xiàn)互斥鎖。實現(xiàn)互斥,可以有以下幾種方式:互斥量(Mutex)、遞歸互斥量(Recursive Mutex)、讀寫鎖(Read-Write Lock)、條件變量(Condition Variable)。感興趣的同學可以參考一下
    2023-04-04
  • C++ continue和break語句

    C++ continue和break語句

    這篇文章主要介紹了C++ continue和break語句,文章圍繞continue和break語句的相關資料展開詳細內(nèi)容,需要的朋友可以參考一下,希望對大家有所幫助
    2021-11-11

最新評論