C語言(二)
第二章 資料
- 2.1 資料型別
-
- 2.1.1 資料型別決定
- 1. 資料佔記憶體位元組數
- 2. 資料取值範圍
- 3. 其上可進行的操作
-
- 2.2基本資料型別
- 2.2.1分類 基本型別
-
- 型別 符號 關鍵字 位元組 16位/32位/64位 位數 32位 數的表示範圍 32位
- 整型
- 有
- [signed] int 2/4/4 4*8=32 -2^31 ~ 2^31-1
- [signed] short [int] 2/2/2 2*8=16 -2^15 ~ 2^15-1
- [signed] long [int] 4/4/4 32 -2^31 ~ 2^31-1
- [signed] long long [int] 8/8/8 64 -2^63 ~ 2^63-1
- 無
- unsigned short [int] 2/2/2 16 0 ~ 2^16-1
- unsigned int 2/4/4 32 0 ~ 2^32-1
- unsigned long [int] 4/4/8 32 0 ~ 2^32-1
- unsigned long long [int] 8/8/8 64 0 ~ 2^64-1
- 有
- 實型
- 有 float 4/4/4 32 0&土1.2e土38
- 有 double/longdouble有8有16 8/8/8 64 0&土1.2e土308
- 有 float 4/4/4 32 0&土1.2e土38
- 字元(變數)
- 有 [signed] char 1/1/1 8 -128~127 -2^7 ~ 2^7-1
- 無 unsigned char 1/1/1 8 0~255 0~ 2^8-1
- 字元(常量) /4/ 位元組
- 指標型別
- 指標 無 char*/int*(指標變數) 2/4/8 32
- 整型
- (1)指標大小
- 指標的大小是由記憶體定址空間決定的,即地址匯流排決定。
- char*(即指標變數): 4個位元組(32位的定址空間是2^32,即32個bit,也就是4個位元組。同理64位編譯器)
- 一般32位機定址空間4G,所以指標佔4位元組;
- 一般16位的微控制器定址空間是64k,所以指標佔2位元組。
- (2)字元型符號
- C標準規定為 Implementation Defined(由實作環境決定)
- •arm-linux-gcc規定 char 為 unsigned char
- •vc 編譯器、x86上的 gcc 規定 char 為 signed char
- 預設情況下,編譯器預設資料為signed型別,但是char型別除外。
- 為了程式碼移植,一定不要用 char,用 signed char
- (3)鐵則
- int,long int,short int的寬度都可能隨編譯器而異。
- 但有幾條鐵定的原則(ANSI/ISO制訂的):
- •sizeof(shortint)<=sizeof(int)
- •sizeof(int)<=sizeof(longint)
- •shortint至少應為16位(2位元組)
- •longint至少應為32位。
- 型別 符號 關鍵字 位元組 16位/32位/64位 位數 32位 數的表示範圍 32位
-
- 2.2.2 常量
-
- 在程式執行中,其值不能被改變的量稱為常量。
- 2.2.2.1 分類
- 符號常量:
- 用識別符號代表常量
- 定義格式: #define 符號常量 常量
- 一般用大寫字母
- 是巨集定義預處理命令,不是C語句
- 直接常量:
- 整型常量
- 實型常量
- 字元常量
- 字串常量
- 符號常量
- 符號常量:
- 2.2.2.2 整型常量
- (1)整型常量有3種形式:十進位制整型常量、八進位制整型常量和十六進位制整型常量。
- (注意:c語言中沒有直接表示二進位制的整型常量,在c語言源程式中不會出現二進位制。)
- 整型常量後可以用u或U明確說明為無符號整型;用l或L明確說明為長整型數
- 二進位制:
- 所有數字由0,1構成,逢二進一,二進位制數中不會出現2.。
- 例:110101
- 八進位制:
- 以數字0(注意不是以字母O,o)開頭,所有數字由0~7構成,逢八進一,八進位制數中不會出現8。
- 八進位制整型常量:051 ,-026 ,0773 等
- 十進位制:
- 所有數字由0~9構成,逢十進一,十進位制數中不會出現10。
- 十進位制整型常量:123 , 0 ,-24 , 85L(長整型常量)等
- 十六進位制:以0x或者0X(數字0加字母x)開頭,
- 所有數字由0~9,A~F(或者a~f)構成,逢十六進一
- (其中A、B、C、D、E、F分別代表10、11、12、13、14、15)
- 十六進位制整型常量:0x55 , 0x1101 , 0x , 0x5AC0 , -0xFF。
- 二進位制:
- 2.2.2.3 實型常量
- 實型常量有兩種表示形式:小數形式和指數形式。
- 編碼形式儲存。
- 小數形式:5.4 0.074 -23.0
- 指數形式:5.4e04.3e-3 -3.3e4 -3.3E4 e可大小寫
- (1)小數部分為0的實型常量,可以寫為453.0 或453。
- (2)用小數表示時,小數點的兩邊必須有數,不能寫成“ .453“和“453.“,而應該寫成“0.453“和“453.0“。
- (3)用指數寫法時,e前必須有數字,e後面的指數必須為整數
- (注意:整數階碼可以是正數,負數,也可以是八進位制數、十六進位制數,但必須為整數)。
- 2.2.2.4 字元常量
- 字元常量的標誌是一對單引號‘ ’,c語言中的字元常量有兩類:
- (1) 由一對單引號括起來的一個字元,如‘a ’, ‘r’,‘#’。
- 注意: ′a′ 和 ′A′ 是兩個不同的字元常量。
- '1' 是字元佔一個位元組,"1"是字串佔兩個位元組(含有一個結束符號)。
- '0' 的ASCII數值表示為48,'a' 的ASCII數值是97,'A'的ASCII數值是65。
- 一般考試表示單個字元錯誤的形式:'65' "1"
- 字元是可以進行算術運算的,記住:'0'-0=48
- 大寫字母和小寫字母轉換的方法:'A'+32='a' 相互之間相差32。
- (2)由一對單引號括起來,以反斜槓\開頭,後跟若干數字或者字母,比如‘\n’,其中“\“是轉義的意思,後面跟不同的字元表示不同的意思,這類字元常量叫轉義字元。具體如圖所示 。
- ‘A’ = ‘\101’ = ‘\x41’ = 65
- 在程式中 int a = 0x6d,是把一個十六進位制的數給變數a 注意這裡的0x必須存在。
- 在程式中 int a = 06d, 是一個八進位制的形式。
- 在轉義字元中
- ’\x6d’ 才是合法的,0不能寫,並且x是小寫。
- ‘\141’ 是合法的, 0是不能寫的。
- ‘\108’是非法的,因為不可以出現8。
- 2.2.2.5 字串常量
- C語言中,以雙引號括起來的,由若干個字元組成的序列即為字串常量。
- 例:“nihao” “happy”等等
- 字串的概念
- 簡單而言,字串是若干有效字元的序列,可包含轉義字元、ASCⅡ碼錶中的字元;
- 形式為: 用雙引號括起來的字元序列;
- 例:"I am a student." , "Hello "
- "a[5]="; "%f\n"。
- 字串的結束標誌:‘\0’。
- C語言中,以雙引號括起來的,由若干個字元組成的序列即為字串常量。
- 2.2.2.6 符號常量
- 符號常量是由巨集定義“#define“定義的常量,在C程式中可用識別符號代表一個常量。
- 例:計算圓的面積的c程式。
- #include<stdio.h>
- #define PI 3.14159
- main()
- {
- float r,s;
- r=12.5;
- s=PI*r*r;
- printf("s= %f",s);
- }
- 例:計算圓的面積的c程式。
- 說明:
- #define 是巨集定義,此程式中所有出現PI的地方都代表3.14159,同時PI稱為符號常量。習慣上我們用大寫字母來表示符號常量,小寫字母表示變數,這樣比較容易區別。
- define f(x)(x*x) 和 define f(x) x*x 之間的差別。一定要好好的注意這寫容易錯的地方,替換的時候有括號和沒有括號是很大的區別。
- 符號常量是由巨集定義“#define“定義的常量,在C程式中可用識別符號代表一個常量。
-
- 2.2.3 變數
- 定義
- 變數就是其值可以改變的量。變數要有變數名,在記憶體中佔據一定的儲存單元,儲存單元裡存放的是該變數的值。不同型別的變數其儲存單元的大小不同,變數在使用前必須定義。
- 2.2.3.1 整型變數
- 整型變數分為4種:
- 基本型(int)、
- 短整型(short int 或short)、
- 長整型(long int 或 long)
- 無符號型(unsigned int ,unsigned short,unsigned long)。
- 不同的編譯系統對上述四種整型資料所佔用的位數和數值範圍有不同的規定。
- 說明:
- 單詞signed來說明“有符號”(即有正負數之分),不寫signed也隱含說明為有符號,unsigned用來說明“無符號”(只表示正數)。
- 整型變數分為4種:
- 2.2.3.2 實型變數
- C語言中,實型變數分為單精度型別( float )和雙精度型別( double )兩種。如:
- float a , b ;
- double m ;
- 單精度實數提供7位有效數字,雙精度實數提供15~16位有效數字。
- 實型常量不分float型和double型,一個實型常量可以賦給一個float 型或double型變數,但變數根據其型別擷取實型常量中相應的有效數字。
- 注意:實型變數只能存放實型值,不能用整型變數存放實型值,也不能用實型變數存放整型值。
- C語言中,實型變數分為單精度型別( float )和雙精度型別( double )兩種。如:
- 2.2.3.3 字元變數
- 字元變數用來存放字元常量,定義形式:
- char 變數名;
- 其中關鍵字char定義字元型資料型別,佔用一個位元組的儲存單元。
- 例:char cr1,cr2;
- cr1= ‘A’ , cr2=‘B’ ;
- 將一個字元賦給一個字元變數時,並不是將該字元本身儲存到記憶體中,而是將該字元對應的ASCII碼儲存到記憶體單元中。
- 例如,字元 ′A′ 的ASCII碼為65,在記憶體中的存放形式如下:01000001
- 由於在記憶體中字元以ASCII碼存放,它的儲存形式和整數的儲存形式類似,所以C語言中字元型資料與整型資料之間可以通用,一個字元能用字元的形式輸出,也能用整數的形式輸出,字元資料也能進行算術運算,此時相當於對它們的ASCII碼進行運算。
- 字元變數用來存放字元常量,定義形式:
- 2.2.4.4 型別的自動轉換和強制轉換
- 當同一表示式中各資料的型別不同時,編譯程式會自動把它們轉變成同一型別後再進行計算。轉換優先順序為:
- 即下邊級別“低“的型別向上邊轉換。具體地說,若在表示式中優先順序最高的資料是double型,則此表示式中的其他資料均被轉換成double型,且計算結果也是double型;若在表示式中優先順序最高的資料是float型,則此表示式中的其他資料均被轉換成float型,且計算結果也是float型。
- 在做賦值運算時,若賦值號左右兩邊的型別不同,則賦值號右邊的型別向左邊的型別轉換;當右邊的型別高於左邊的型別時,則在轉換時對右邊的資料進行擷取。
- 除自動轉換外,還有強制轉換,表示形式是:
- 一般形式:(型別說明符)(表示式)
- 功能:把表示式的運算結果強制轉換成型別說明符所表示的型別
- 例:(int)(a+b)
- 一定是 (int)a 不是 int(a),注意型別上一定有括號的。
- 注意(int)(a+b) 和(int)a+b 的區別。 前是把a+b轉型,後是把a轉型再加b。
- 例1表示式(int)((double)(5/2)+2.5)的值是4。
- (int)((double)(5/2)+2.5)
- →(int)((double)2)+2.5)
- →(int)(2.000000+2.5)
- →(int)(4.500000)
- →4。
- 例2:以下程式執行後的輸出結果是(3) 。
- main()
- { int a;
- a=(int)((double)(3/2)+0.5+(int)1.99*2);
- printf("%d\n",a);
- }
- (3/2)=1,
- (double)(3/2)+0.5=1.5,
- (int)1.99*2=2,(double)(3/2)+0.5+(int)1.99*2=3.5,故a=3。
- 三種取整丟小數的情況:
- 1、int a=1.6;
- 2、(int)a;
- 3、1/2; 3/2; //除法
- 當同一表示式中各資料的型別不同時,編譯程式會自動把它們轉變成同一型別後再進行計算。轉換優先順序為:
- 2.2.4.5 全域性變數和區域性變數
- 在C語言中,使用者命名的識別符號都有一個有效的作用域。
- 所謂識別符號的“作用域”就是指程式中的某一部分,在這部分中,該識別符號是有定義的,可以被C編譯和連線程式所識別。
- 我們知道每個變數都有自己的作用域,在一個函式內定義的變數,不能在其他函式中引用。顯然,變數的作用域與其定義語句在程式中出現的位置有直接的關係,據此變數可以劃分為區域性變數和全域性變數。
- 注意“定義”和 “說明”兩個詞的區別。“定義”是指給變數分配確定的儲存單元;“說明”只是說明變數的性質。
- (一)區域性變數
- 在一個函式內部定義的變數,它們只在本函式範圍內有效,即只有本函式才能使用它們,其他函式不能使用這些變數,我們將這些變數稱為“區域性變數”。不同函式中可以使用相同名字的區域性變數,它們代表不同的物件,在記憶體中佔不同的單元,互不干擾。
- (二)全域性變數
- 在函式之外定義的變數稱為外部變數,外部變數是全域性變數。全域性變數可以為本檔案中其他函式所共用,它的有效範圍從定義變數開始到本檔案結束。
- 如果在同一個原始檔中,外部變數與區域性變數同名,則在區域性變數的作用範圍內,外部變數被“遮蔽”,即它不起作用。
- 變數作用域和生存期
- 生存期:什麼時候這個變數開始出現了,到什麼時候消亡了
- 作用域: 在(程式碼的) 什麼範圍內可以訪問這個變數(這個變數可以起作用)
- 對於本地變數,這兩個問題的答案是統一的:大括號內一塊
- 2.2.4.6 變數的儲存類別
- 變數值存在的時間(即生存期)
- 靜態儲存方式和動態儲存方式。
- 所謂靜態儲存方式是指在程式執行期間分配固定的儲存空間的方式,而動態儲存方式是在程式執行期間根據需要動態分配儲存空間的方式
- 在記憶體中供使用者使用的空間可以分為程式區、靜態儲存區和動態儲存區3個部分。資料分別被存放在靜態儲存區和動態儲存區中。靜態儲存區中存放的是全域性變數,在程式開始執行時就給全域性變數分配儲存區。程式執行過程中它們佔據固定的儲存單元,程式執行完畢這些儲存單元就被釋放。
- 每一個變數和函式所具有的屬性是:資料的儲存類別和資料型別(在前面已經介紹過)。所謂的儲存類別指的是資料在記憶體中儲存的方法,其可分為兩類:靜態儲存類和動態儲存類。具體包括自動(auto)、靜態(static)、暫存器(register)和外部(extern),共4種。
- (一)auto變數
- 當在函式內部或複合語句內定義變數時,如果沒有指定儲存類別,或使用了auto說明符,系統就認為所定義的變數具有自動類別。如:
- float a;等價於auto float a;
- auto變數的儲存單元被分配在記憶體的動態儲存區,每當進入函式體(或複合語句)時,系統自動為auto變數分配儲存單元,退出時自動釋放這些儲存單元另做他用。因此,這類區域性變數的作用域是從定義的位置起,到函式體(或複合語句)結束止。
- 所有自動類區域性變數的儲存單元都是在進入這些區域性變數所在的函式體(或複合語句)時生成,退出其所在的函式體(或複合語句)時消失(變為無定義)。這就是自動類區域性變數的“生存期“。當再次進入函式體(或複合語句)時,系統將為它們另行分配儲存單元,因此變數的值不可能被保留。隨著函式的頻繁呼叫,動態儲存區內為某個變數分配的儲存單元位置會隨程式的執行而改變。
- 當在函式內部或複合語句內定義變數時,如果沒有指定儲存類別,或使用了auto說明符,系統就認為所定義的變數具有自動類別。如:
- (二)register變數
- 暫存器變數也是自動類變數。它與auto變數的區別僅在於:用register說明變數是建議編譯程式將變數的值保留在CPU的暫存器中,而不是像一般變數那樣佔用記憶體單元。程式執行時,訪問暫存器內的值要比訪問記憶體中的值快得多。因此,當程式對執行速度有較高要求時,把那些頻繁引用的少數變數,指定為register變數,有助於提高程式執行的效率。
- 說明:
- (1)CPU中暫存器的數目是有限的,因此只能說明少量的暫存器變數。在同一個函式中,允許說明為暫存器變數的數目不僅取決於CPU的型別,也與所用的C編譯程式有關。當沒有足夠的暫存器來存放指定的變數,或編譯程式認為指定的變數不適合放在暫存器中時,將自動按auto變數來處理。因此,register說明只是對編譯程式的一種建議,而不是強制性的。
- (2)由於register變數的值存放在暫存器內而不是存放在記憶體中,所以register變數沒有地址,也就不能對它實行求地址運算。
- (3)register變數的說明應儘量靠近其使用的地方,用完之後儘快釋放,以便提高暫存器的利用效率。
- 說明:
- 暫存器變數也是自動類變數。它與auto變數的區別僅在於:用register說明變數是建議編譯程式將變數的值保留在CPU的暫存器中,而不是像一般變數那樣佔用記憶體單元。程式執行時,訪問暫存器內的值要比訪問記憶體中的值快得多。因此,當程式對執行速度有較高要求時,把那些頻繁引用的少數變數,指定為register變數,有助於提高程式執行的效率。
- (三)靜態儲存類別的區域性變數
- 當函式體(或複合語句)內部用static來說明一個變數時,可以稱該變數為靜態區域性變數。它與auto變數、register變數的本質區別是:
- (1)在整個程式執行期間,靜態區域性變數在記憶體中的靜態儲存區中佔據著永久性的儲存單元。即使退出函式後,下次再進入該函式時,靜態區域性變數仍使用原來的儲存單元。由於不釋放這些儲存單元,這些儲存單元中的值得以保留,因而可以繼續使用儲存單元中原來的值。由此可知,靜態區域性變數的生存期將一直延長到程式執行結束。
- (2)靜態區域性變數的初值是在編譯時賦予的,在程式執行期間不再賦以初值。對未賦值的區域性變數,C語言編譯程式自動給它賦初值為0。
- 當函式體(或複合語句)內部用static來說明一個變數時,可以稱該變數為靜態區域性變數。它與auto變數、register變數的本質區別是:
- (四)用static宣告外部變數
- 有時在程式設計中希望某些外部變數只限於本檔案使用,而不能被其他檔案引用,這時可以在定義外部變數時加一個static宣告。
- 並不是對外部變數加上static才是靜態儲存而不加static的是動態儲存。兩種形式的外部變數都是靜態儲存方式,只是作用範圍不同而已。
- 有時在程式設計中希望某些外部變數只限於本檔案使用,而不能被其他檔案引用,這時可以在定義外部變數時加一個static宣告。
- (五)用extern宣告外部變數
- ① 在一個檔案內宣告外部變數
- 當全域性變數定義在後,引用它的函式在前時,應該在引用它的函式中用extern對此全域性變數進行說明,以便通知編譯程式,該變數是一個已在外部定義了的全域性變數,已經分配了儲存單元,不需要為它另開闢儲存單元。這時其作用域從extern說明處起,延伸到該函式末尾。
- 全域性變數的說明與全域性變數的定義不同。變數的定義(開闢儲存單元)只能出現一次,在定義全域性變數時,不可使用extern說明符;而對全域性變數的說明,則可以多次出現在需要的地方,這時必須用extern進行說明。
- ② 在多檔案的程式中宣告外部變數
- 當一個程式由多個單獨編譯的原始檔組成,並且在每個檔案中均需要引用同一個全域性變數時,若在每個檔案中都定義了所需的同名全域性變數,則在“連線”時將會產生“重複定義”的錯誤。在這種情況下,單獨編譯每個檔案時並無異常,編譯程式將按定義分別給它們開闢儲存空間,而當進行連線時,就會顯示出錯資訊。解決的方法是:在其中一個檔案中定義所有全域性變數,而在其他用到這些全域性變數的檔案中用extern對這些變數進行說明。
- ① 在一個檔案內宣告外部變數
- 定義
- 2.2.1分類 基本型別
- 2.3構造型別
- 2.3.1 陣列
- 2.3.1.1 一維陣列的定義和引用
- (一)陣列的概念
- 陣列是由屬於同一個資料型別的有序資料集構成的。陣列中的每一個數據稱為“元素“。可以用一個統一的陣列名和下標來唯一地標識陣列中的元素。
- (二)一維陣列的定義
- 一維陣列的定義方式為:
- 型別說明符 陣列名[常量表達式];
- 如:
- char c[20];
- c是陣列名,此陣列共有20個元素,並且每個元素的型別都為字元型。
- (三)一維陣列元素的引用
- 陣列元素的表示形式為:
- 陣列名[下標];
- 引用陣列元素時,陣列的下標可以是整型常量,也可以是整型表示式。
- 和變數一樣,陣列必須先定義後使用。陣列元素只能逐個引用而不能把陣列當做一個整體一次引用。
- 陣列名[下標];
- 陣列元素的表示形式為:
- (四)一維陣列的初始化
- 當陣列定義後,系統會為該陣列在記憶體中開闢一串連續的儲存單元,但這些儲存單元中並沒有確定的值。可以在定義陣列時為所包含的陣列元素賦初值,如:
- int a[6]={ 0,1,2,3,4,5 };
- 所賦初值放在一對花括號中,數值型別必須與所說明型別一致。所賦初值之間用逗號隔開,系統將按這些數值的排列順序,從a[0]元素開始依次給a陣列中的元素賦初值。以上語句將a[0]賦值0,a[1]賦值1, …… ,a[5]賦值5。在指定初值時,第一個初值必定賦給下標為0的元素。也就是說陣列元素的下標是從0開始的。同時,不可能跳過前面的元素給後面的元素賦初值,但是允許為前面元素賦值為0。當所賦初值個數少於所定義陣列的元素個數時,將自動給後面的其他元素補以初值0;當所賦初值個數多於所定義陣列的元素個數時,也就是說超出了陣列已經定義的範圍,在編譯時系統將給出出錯資訊。
- C語言規定可以通過賦初值來定義陣列的大小,這時一對方括號中可以不指定陣列大小。
- 當陣列定義後,系統會為該陣列在記憶體中開闢一串連續的儲存單元,但這些儲存單元中並沒有確定的值。可以在定義陣列時為所包含的陣列元素賦初值,如:
- (一)陣列的概念
- 2.3.1.1 一維陣列的定義和引用
- 2.3.1.2 一維陣列與函式
- 一、 一維陣列元素作為實參
- 無論是一維陣列元素或者二維陣列元素,和普通變數的使用沒有任何區別,他們之間僅僅是變數名不同,一維陣列元素作為實參傳遞給形參,形引數據改變不會影響實參變化。
- 二、一維陣列元素地址作為實參
- 一維陣列元素的地址作為實參,對應的形參必須是與實參基型別相同的指標變數。此時可以通過被呼叫函式改變呼叫函式中的資料。
- 例 有以下程式段
- #include<stdio.h>
- voidfun(int x,int *p)
- {
- x*=2;
- p[0]=p[-1]+p[1];
- }
- main()
- {
- int a[10]={1,2,3,4,5,6,7,8,9,10};
- fun(a[2],&a[6]);
- printf("%d %d\n",a[2],a[6]);
- }
- 程式執行後的輸出結果是 3 14
- 本題主函式中有函式呼叫 fun (a[2],&a[6]);
- 第一個傳遞的實參是a[2]的值3,對原數不影響
- 第二個傳遞的實參是&a[6] (a[6]的地址),指標變數p儲存a[6]的地址,根據指標變數加下標表示資料的方法,p[0]儲存的是a[6]的值,p[-1]儲存的是a[5]的值6,p[1]儲存的是a[7]的值8。經過p[0]=p[-1]+p[1]計算;值為14。
- 例 有以下程式段
- 一維陣列元素的地址作為實參,對應的形參必須是與實參基型別相同的指標變數。此時可以通過被呼叫函式改變呼叫函式中的資料。
- 三、一維陣列名作為實參
- 一維陣列名為地址常量,表示陣列的首地址,如果一維陣列名作為實參,對應的形參應該是一個指標變數,此指標變數的基本型別必須與陣列的型別一致。
- 通常被呼叫函式的首部可以有以下3中方式:
- (1)fun(int *a)
- (2)fun(int a[N])
- (3)fun(int a[ ])
- 例 有以下程式段
- #include<stdio.h>
- int fun(int *x,int n)
- {
- int i , sum = 0 ;
- for (i=0;i<n;i++)
- sum=sum+x[i];
- return sum;
- }
- main()
- {
- int a[]={1,2,3,4,5 },s=0;
- s=fun (a,5);
- printf("%d \n",s);
- }
- 程式執行後的輸出結果是15
- 本題main函式中定義了一維陣列a,含有5個int型別的陣列元素,所以地址常量a的基本型別為int型別,對應的形參x的基本型別也是int型別,可以進行引數的傳遞,傳遞後依然用指標變數加下標的方式表示資料。
- 例 有以下程式段
- 一、 一維陣列元素作為實參
- 2.3.1.3 二維陣列的定義和引用
- (一)二維陣列的定義
- 在C語言中,二維陣列中元素排列的順序是:按行存放,即在記憶體中先順序存放第一行的元素,再存放第二行的元素。因此,二維陣列元素的儲存與一維陣列元素儲存相類似,總是佔用一塊連續的記憶體單元。
- 二維陣列的一般形式為:
- 型別說明符 陣列名[常量表達式][常量表達式];
- 如:int c[3][4]; 定義c為3×4 (3行4列)的陣列。
- 注意:不能寫成c[3,4]。C語言對二維陣列採用這樣的定義方式:我們可以把二維陣列當做是一種特殊的一維陣列。
- 例如,可以把c看成是一個一維陣列,它有3個元素c[0]、c[1]、c[2],每個元素又是一個包含4個元素的一維陣列。可以把c[0]、c[1]、c[2]看做是3個一維陣列的名字。
- 注意:不能寫成c[3,4]。C語言對二維陣列採用這樣的定義方式:我們可以把二維陣列當做是一種特殊的一維陣列。
- (二)二維陣列的引用
- 二維陣列的表示形式為:
- 陣列名[下標][下標]
- 陣列的下標可以是整型表示式,如 c[3-1][3×2-2];
- 陣列名[下標][下標]
- 陣列元素可以出現在表示式中,也可以被賦值。
- 定義陣列時用的c[3][4]和引用元素時的c[3][4]的區別:前者用來定義陣列的維數和各維的大小,共有3行4列;後者中的3和4是下標值,c[3][4]代表該陣列中的一個元素。如果a[3][4]是二維陣列中最後一個元素,那麼該陣列共有4行5列。
- 二維陣列的表示形式為:
- (三)二維陣列的初始化
- 可以在定義二維陣列的同時給二維陣列的各元素賦初值。
- 如:
- float m[2][2]={{1.5,3.2},{0.8}};
- 如:
- 全部初值放在一對花括號中,每一行的初值又分別括在一對花括號中,之間用逗號隔開。當某行一對花括號內的初值個數少於該行中元素的個數時,系統將自動地給後面的元素補初值0。同樣,不能跳過每行前面的元素而給後面的元素賦初值。
- 可以在定義二維陣列的同時給二維陣列的各元素賦初值。
- (四)通過賦初值定義二維陣列的大小
- 對於一維陣列,可以在陣列定義語句中省略方括號中的常量表達式,通過所賦初值的個數來確定陣列的大小;對於二維陣列,只可以省略第一個方括號中的常量表達式,而不能省略第二個方括號中的常量表達式。
- 如:
- int a[][3]={{1,2,3},{4,5},{6},{8}};
- a陣列的第一維方括號中的常量表達式省略,在所賦初值中,含有4個花括號,則第一維的大小由花括號的個數來決定。因此,該陣列其實是與a[4][3]等價的。當用以下形式賦初值時:
- int c[][3]={1,2,3,4,5};
- 第一維的大小按以下規則決定:
- (1)當初值的個數能被第二維的常量表達式的值除盡時,所得商數就是第一維的大小。
- (2)當初值的個數不能被第二維的常量表達式的值除盡時,則:
- 第一維的大小 =所得商數 + 1 。
- 因此,按此規則,以上c陣列第一維的大小應該是2,也就是說語句等同於
- int c[2][3]={{1,2,3},{4,5}};。
- 2.3.1.4 二維陣列與函式
- 二維陣列名作為實參
- 二維陣列元素作為實參,與普通變數作為實參沒有任何區別,二維陣列名為行指標常量,如果二維陣列名作為實參,對應的形參必須是一個行指標變數。
- 例如:有以下定義和函式呼叫語句:
- #define M 5
- #define N 3
- main()
- {
- int s[M][N];
- …….
- fun(s);
- …….
- }
- 此時,實參為二維陣列名(即行指標),則fun函式的首部可以是以下3中形式之一:
- (1)fun ( int (*a)[N])
- (2) fun ( int a[ ][N])
- (3) fun ( int a[M][N])
- 注意:行下標可以省略,列下標不可以省略。無論哪種方式,系統都把a看作一個行指標變數。
- 二、指標陣列名作為實參
- 指標陣列名師指向指標的指標常量,因此當指標陣列名作為實參時,對應的形參應該為一個指向指標的指標變數。
- 例如:有以下定義和函式呼叫語句:
- #define M 5
- #define N 3
- main()
- {
- int s[M][N],*p[M];
- …….
- for(i=0;i<M;i++) p[i]=s[i];
- fun(p);
- …….
- }
- 此時,實參為一維陣列名(即行指標),則fun函式的首部可以是以下3中形式之一:
- (2)fun ( int *a[M])
- (2) fun ( int *a[ ])
- (3) fun ( int **a)
- 2.3.1.5 字元陣列
- 注:C語言無字串型別,字串是存放在字元陣列中的。
- (一)字元陣列的定義
- 字元陣列就是陣列中的每個元素都是字元,定義方法同普通陣列的定義相同,即逐個對陣列元素賦值。如:
- char c[11];
- c為該陣列名,該陣列共有11個元素,並且每個元素都為字元型。
- (二)字元陣列的初始化及引用
- 對字元陣列初始化,可逐個元素地賦值,即把字元逐個賦給陣列元素。如:
- char a[9]={ ′T′, ′h′, ′a′, ′n′, ′k′, ′′, ′y′, ′o′,′u′};
- 如果花括號中提供的初值個數(即字元個數)大於陣列長度,則按語法錯誤處理。
- 如果初值個數小於陣列長度,則將這些字元賦給陣列中前面那些元素,其餘的元素自動定為空字元(′\0′)。如:
- char c[6]={′G′,′o′,′o′,′d′};
- 字元陣列的引用形式與其他陣列的引用形式相同,採用下標引用,
- 即 陣列名[下標]。
- 例如:
- #include<stdio.h>
- main()
- { char c[9]={'T','h','a','n','k',',','y','o','u'};
- int i;
- for(i=0; i<9; i++)
- printf(“%c“,c[i]);
- }
- 輸出的結果為Thank,you。
- 即 陣列名[下標]。
- 對字元陣列初始化,可逐個元素地賦值,即把字元逐個賦給陣列元素。如:
- (三)字串和字串結束標誌
- C語言中,將字串作為字元陣列來處理。為了測定字串的實際長度,C語言規定了一個字串結束標誌,以字元'\0'代表。就是說,在遇到字元'\0'時,表示字串結束,由它前面的字元組成字串。
- 系統對字串常量也自動加一個'\0'作為結束符。
- 例如:
- char c[]=“c program“;
- 陣列c共有9個字元,但在記憶體中佔10個位元組,最後一個位元組'\0'是由系統自動加上的。有了結束標誌'\0'後,在程式中往往依靠檢測 '\0'的位置來判定字串是否結束,而不是根據陣列的長度來決定字串長度。
- 說明:'\0'代表ASCII碼為0的字元,是一個“空操作符“,它什麼也不幹。在輸出時也不輸出'\0',它只是一個結束的標誌。
- (四)字元陣列的初始化
- 方法:將字元常量以逗號分隔寫在花括號中
- ①在定義字元陣列時進行初始化
- charch[7]={‘s’,’t’,’u’,’d’,’e’,’n’,’t’};
- ②在對全部元素指定初值時,可省寫陣列長度。
- char ch[]={‘s’,’t’,’u’,’d’,’e’,’n’,’t’};
- ③如果花括弧內提供的初值個數大於陣列長度?
- (五)用字串來直接初始化字元陣列
- 可直接把字串寫在花括號中來初始化字元陣列.
- 如:charch[9]={“student”};
- 系統將雙引號括起來的字元依次賦給字元陣列的各個元素, 並自動在末尾補上字串結束標誌字元'\0'。
-
相關推薦
C語言(二):C語言概述
感覺 用途 計算機 一行 可用 讓其 pan 復合語句 sso 學習筆記: 運算符 函數 一個簡單的C語言程序 整型變量 換行符 註釋 關鍵字 概述:C語言程序是什麽樣
C語言(二)
第二章 資料 2.1 資料型別 2.1.1 資料型別決定 1. 資料佔記憶體位元組數 2. 資料取值範圍 3. 其上可進行的操作
C語言(二 運算子、條件語句、指標)
C運算子 包括算數運算子,邏輯運算子,關係運算符,位運算子,賦值運算子,其他運算子。 算術運算子 就是加減乘除求餘,自增自減等算術。 邏輯運算子 與:&&,或:||,非:! 關係運算符 等於,大於,小於等組合 位運算子 位與:&,位或:|,位左移<<,位右
C語言----(二維陣列,複雜資料型別的判斷)
一、二維陣列的定義賦值1、定義一個三行四列的二維陣列,如下:int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int brr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; //陣列arr與br
C語言(三)---輸入和輸出
而是 abs 空間 精度 保存 括號 ger 原型 parameter 一、輸出 輸入輸出:英文是Input/Output簡稱IO。 C語言標準函數庫中,提供了關於以下介紹的幾種輸出函數,(所有標準輸入輸出函數在調用前,必須先包含頭文件stdio.h) 1.1 簡單
C語言(一):初始C語言
實踐 概念 個數 部分 貝爾 指令集 觸摸 物理學 解釋器 學習筆記: C的歷史和特性 編寫程序的步驟 編譯器和鏈接器的一些知識 C的標準 1.1 C語言
#r語言(二)筆記
查看 控制語句 objects stop 來源 plot 方差 一維數組 環境 #r語言(二)筆記 #早復習 #概述:R是用於統計分析、繪圖的語言和操作環境 #對象: #數據類型--統稱為對象 #向量(vector):用於存儲數值型、字符型或邏輯型數據的一維數組
C語言-(double)int/int
main double ble bsp can class true clas 語言 int main(){ int x, y; scanf("%d %d", &x, &y); double c = (double) x/y; printf("%f
C語言(三)- 結構體
strong 變量初始化 add num ID name oid nbsp clu 一、結構體 1、一般形式 不同類型數據組成的組合型數據結構,即結構體。 結構體類型的一般形式: 1 struct 結構體名{ 2 類型名 成員名1; 3 類型名 成員名2; 4 類型名
C++學習(二)之Visual Studio寫system語句 生成可執行文件
屬性 默認 右鍵 同學 文件夾 開發 源代碼 學習 http system命令 1、首先先介紹一些system命令 windows+tab //切換窗口 windows+R //調出命令窗口 命令: 輸入 calc 打開計算機 輸入 cmd 打開命令窗口 輸入 msp
第一章 程序設計和C語言(筆記)
deb 第一章 bug 總結 warn 標準 war 包含 基本 一、程序和程序語言 程序:完成某項事務所預設的活動方式和活動過程。 程序設計:人們描述計算機要做的工作。 對於工作過程的細節動作描述就是一個“程序”。 在一個程序描述中,總有一批預先假定的“基本動作”,是執行
c++指標(二)---算術運算
c++中的指標可以理解為一個地址的值,這個值是用數值來表示的。 因此可以對其執行算術運算。可以對指標進行四種算術運算:++,--,+,- 遞增一個指標 程式中可以用指標代替陣列,因為變數指標可以遞增,而陣列不能遞增,因為陣列是一個常量指標。下面的程式遞
Java是如何快速煮成C 的 (二) 資料訪問 1
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
大數相乘C語言(轉)
轉自:https://blog.csdn.net/l_liangkk/article/details/51980763 進一步學習來到 了大數乘法,關於大數乘法的思路前面也簡單提過, 其核心就是:兩個大數,從末尾開始逐位相乘。相乘結果儲存在另外一個數組裡面(也從陣列末尾開始依次往前儲存)
Linux C/C++教程(二)-- C++對C的拓展
目錄 一、bool型別關鍵字 二、引用 三、輸入輸出 四、函式引數 五、string類 六、左值 一、bool型別關鍵字 C++在C語言的基礎型別上新增了布林型別(bool),bool可取的值有兩個:true、false,佔
c/c++區別(二)引用
第6個區別:引用 一.引用傳入 變數:記憶體單元的別名 引用:記憶體單元的別名 引用是一個別名 底層處理:C++中和指標處理相同 在用到引用變數的地方 系統會自動解引用 引用開闢記憶體 引用的特點
k-mean實現 C語言(轉載)
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> #define N 12
關於MATLAB轉C++程式碼(二)
有一些遇到過的問錯誤提示 一、“The left-hand side has been constrained to be non-complex, but the right-hand side is complex. To correct this problem, make the r
C++學習(二)
點選開啟連結 CA* pa = &c;這句話是父類指標指向子類物件,呼叫pa->f1()時,因為父類中的f1()是虛擬函式,所以將發生動態繫結,呼叫子類CB中的f1()函式,先輸出CB::f1() 在CB類的f1()函式中,呼叫非虛擬函式f2(),但因為其父類C
C語言(一)
第一章 基礎知識 1.1 基本框架 任何一個c語言程式都必須包括以下格式: int main(int argc, char *argv[] ) { return 0; }
- 可直接把字串寫在花括號中來初始化字元陣列.
- 二維陣列名作為實參
- 2.3.1 陣列