C 語言基礎教程(我的C之旅開始了)[十]
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ù)組 */ 方括號 [] 表明它們是數(shù)組,[] 里的數(shù)字表明數(shù)組包含的元素數(shù)目。 數(shù)組中的元素是相鄰的,初始化之前,元素的值可能是隨機的。下圖形象地表現(xiàn)了這種相鄰關系。 使用數(shù)組名和下標(subscript number 或 index)就可以訪問特定的元素。下標始于 0,止于 n - 1。例如:c[0] 是數(shù)組 c 的第一個元素,而 c[11] 是它的最后一個元素,也就是第 12 個元素。
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) printf("%d\n", iarr[0]); /* 輸出 0 */ 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) printf("%d\n", iarr[0]); /* 輸出 1 */ 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) return 0; 輸出為: 6 從中可以看出兩點: A. 如果指派初始值后面還有值,則后面的值會被用于初始化后續(xù)的元素。上例中, B. 如果初始化列表中多次出現(xiàn)對某元素的初始化,則以最后一次為準。上例中,
我們可以利用下標給特定的元素賦值。例如: int iarr[5]; C 不允許直接使用數(shù)組對別的數(shù)組進行賦值,也不允許使用初始化列表對數(shù)組進行賦值。例如: int iarr_1[5] = { 1, 2, 3, 4, 5 }; /* 正確 */ iarr_2 = iarr_1; /* 錯誤! */ 最后一個語句發(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) printf("var_1: %d, var_2: %d\n", var_1, var_2); arr[-1] = -1; printf("%d %d\n", arr[-1], arr[5]); return 0; 上述程序使用 Dev-C++ 4.9.9.2 編譯運行的輸出為: var_1: 20, var_2: 40 可見,下標越界可能改變其它變量的值。這是因為 gcc(dev-c++ 使用的 C 編譯器)把 var_2 保存于數(shù)組 arr 之前的內(nèi)存空間,所以對 arr[-1] 賦值正好改變了 var_2 的值。不同的編譯器編譯運行該程序可能會有不同的輸出,也可能會異常退出。 C 語言的哲學是信任程序員,而且不檢測越界程序運行更快。程序編譯時有些下標的值仍然是不可知的,所以如果要檢測下標越界的話,編譯器必須在生成的目標代碼中加入額外的代碼用于程序運行時檢測下標是否越界,這就會導致程序運行速度下降。故而,為了運行效率,C 不檢測下標是否越界。
C99 之前,聲明數(shù)組時,[] 中的值必須是大于零的整數(shù)常量。C99 中,聲明數(shù)組時,[] 中可以是變量。這就是所謂的變長數(shù)組(variable-length array,簡稱 VLA)。聲明 VLA 時,不能對其進行初始化。在后續(xù)的教程中,我會對 VLA 進行詳細講解。 int n = 99; |
相關文章
C++?Qt開發(fā)之關聯(lián)容器類使用方法詳解
當我們談論編程中的數(shù)據(jù)結構時,順序容器是不可忽視的一個重要概念,Qt?中提供了豐富的容器類,用于方便地管理和操作數(shù)據(jù),本章我們將主要學習關聯(lián)容器,主要包括?QMap?,QSet和?QHash,感興趣的朋友跟著小編一起來學習吧2023-12-12聊聊Qt+OpenCV聯(lián)合開發(fā)之圖像的創(chuàng)建與賦值問題
這篇文章主要介紹了Qt+OpenCV聯(lián)合開發(fā)之圖像的創(chuàng)建與賦值問題,給大家介紹了圖像的克隆及拷貝問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-01-01C/C++程序開發(fā)中實現(xiàn)信息隱藏的三種類型
這篇文章主要介紹了C/C++程序開發(fā)中實現(xiàn)信息隱藏的三種類型的相關資料,需要的朋友可以參考下2016-02-02