陣列是一組有序資料的集合。陣列中各資料的排列有一定規律,下標代表資料在陣列中的序號
用一個陣列名和下標來唯一的確定陣列中的元素
陣列中的每一個元素都屬於同一個資料型別。不能把不同型別的資料放在同一個陣列中
將陣列和迴圈結合起來,可以有效的處理大批次的資料
怎樣定義和引用一維陣列
一維陣列是陣列中最簡單的,它的元素只需要用陣列名加一個下標,就能唯一的確定
怎樣定義一維陣列
要使用陣列,必須在程式中先定義陣列,即通知計算機:由哪些資料組成陣列,陣列中有多少元素,屬於哪個資料型別。否則計算機不會自動的把這一批資料作為陣列處理。
定義一維陣列的一般形式:型別符 陣列名[常量表示式]
陣列名的命名規則和變數名相同,遵循識別符號命名規則
在定義陣列時,需要指定陣列中元素的個數,方括號中的常量表示式用來表示元素的個數,即陣列長度
常量表示式中可以包括常量和符號常量,不能包含變數。也就是說C語言不允許對陣列的大小作動態定義,即陣列的大小不依賴於程式執行過程中變數的值。
//如果在被呼叫的函式(不包括主函式)中定義陣列,其長度可以是變數或非常量表示式,如:
void func (int n)
{
int a[2 * n]; //合法,n 的值從實參傳來
}
//在呼叫 func 函式時,形參 n 從實參得到值。這種情況稱為“可變長陣列”,允許在每次呼叫 func 函式時,n 有不同的值
//但是在執行函式時,n 的值是不可變的,陣列長度是固定的
//如果指定陣列為靜態(static)儲存方式,則不能用“可變長陣列”
怎樣引用一維陣列元素
在定義陣列並對其中各元素賦值後,就可以引用陣列中的元素。只能引用陣列元素而不能一次整體呼叫整個陣列全部元素的值
引用陣列元素的表示形式:陣列名[下標]
“下標”可以是整型常量或整形表示式
//定義陣列時用到的“陣列名[常量表示式]”和引用陣列元素時用的“陣列名[下標]”形式相同,但是含義不同
int a[10]; //定義陣列時指定陣列包含10個元素
t = a[6]; //a陣列中序號為6的元素
例:對10個陣列元素依次賦值為0,1,2,3,4,5,6,7,8,9,要求按逆序輸出
//對10個陣列元素依次賦值為0,1,2,3,4,5,6,7,8,9,要求按逆序輸出
#include <stdio.h>
int main(void)
{
int arr[10];
for (int i = 0; i < 10; i++)
arr[i] = i;
for (int i = 9; i >= 0; i--)
printf("%d\t", arr[i]);
printf("\n");
return 0;
}
執行結果:
陣列元素的下標是從0開始的
一維陣列的初始化
為了使程式簡潔,常在定義陣列的同時,給各陣列元素賦值,這稱為陣列的初始化。可以用“初始化列表”方法實現陣列的初始化
- 在定義陣列時,對全部陣列元素賦予初值
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
將陣列中元素的初值順序放在一堆花括號內,資料間用逗號分隔 。花括號內的資料就稱為“初始化列表” - 可以只給陣列中的一部分元素賦值
int a[10] = { 0, 1, 2, 3, 4 }
定義陣列有10個元素,但括號內只提供5個初值,這表示只給前面5個元素賦初值,系統自動給後面5個元素賦初值為0 - 如果想使一個陣列中全部元素值為0,可以寫成
int a[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
或者int a[10] = { 0 } //未賦值的部分元素自動設為0
- 在對全部陣列元素賦初值時,由於資料的個數已經確定,因此可以不指定陣列長度
int a[5] = { 1, 2, 3, 4, 5 }
可以寫成int a[] = { 1, 2, 3, 4, 5 }
如果陣列長度與提供初值的個數不一致時,則方括號中的陣列長度不能省略
如果在定義數值型陣列時,指定了陣列的長度並對之初始化,凡未被“初始化列表”指定初始化的陣列元素,系統會自動把它們初始化為0(如果是字元型陣列,則初始化為‘\0’,如果是指標型陣列,則初始化為NULL,即空指標)
怎樣定義和引用二維陣列
二維陣列通常稱為矩陣。把二維陣列寫成行和列的排列形式,可以有助於形象化的理解二維陣列的邏輯結構
怎樣定義二維陣列
二維陣列定義的一般形式為:型別說明符 陣列名[常量表示式][常量表示式];
C語言對二維陣列採用這樣的定義方式,使得二維陣列可以被看作是一種特殊的一維陣列:它的元素又是一個一維陣列。
C語言中,二維陣列中元素排列的順序是按行存放的,即在記憶體中先順序存放第一行的元素,接著再存放第二行的元素...
用矩陣形式表示二維陣列,是邏輯上的概念,能形象的表示出行列關係。而在記憶體中,各元素是連續存放的,不是二維的,是線性的。
C語言還允許使用多維陣列,多維陣列元素在記憶體中排列的順序為:第一維的下標變化最慢,最右邊的下標變化最快
怎樣引用二維陣列的元素
二維陣列元素的表示形式:陣列名[下標][下標]
下標應是整型表示式
陣列元素可以出現在表示式中,也可以被賦值
在引用陣列元素中,下標值應在已定義的陣列大小的範圍內。
二維陣列的初始化
可以用“初始化列表”對二維陣列初始化
- 分行給二維陣列賦初值:
int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }};
這種賦初值方法比較直觀,把第一個花括號內的資料給第一行的元素,第二個花括號內的資料給第二行的元素...即按行賦值 - 可以將所有資料寫在一個花括號內,按陣列元素在記憶體中的排列順序對各元素賦初值:
int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
效果和第一種方法相同,但是這種不直觀,容易遺漏,不易檢查 - 可以對部分元素賦初值:
int a[3][4] = { { 1 }, { 5 }, { 9 } };
未賦值元素自動賦0,對非0元素少時方便 - 如果對全部元素都賦初值(即提供全部初始資料),則定義陣列時對第1維度的長度可以不指定,但是第2維度的長度不能省
int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
可以寫成int a[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
- 在定義時也可以只對部分元素賦初值而省略第1維長度,但應分行賦初值
int a[][4] = { { 1, 2, 3, 4 }, {}, { 9, 10, 11, 12 }};
C語言在定義陣列和表示陣列時採用 a[][] 這種兩個方括號的方式,對陣列初始化時十分有用,概念清楚,使用方便,不易出錯
二維陣列程式舉例
例:將一個二維陣列行和列的元素互換,存到另一個二維陣列中
//將一個二維陣列行和列的元素互換,存到另一個二維陣列中
#include <stdio.h>
int main(void)
{
int arr_a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
int arr_b[3][2] = { 0 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
arr_b[i][j] = arr_a[j][i];
}
printf("arr_a\n");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
printf("%d\t", arr_a[i][j]);
printf("\n");
}
printf("\narr_b\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
printf("%d\t", arr_b[i][j]);
printf("\n");
}
return 0;
}
執行結果:
例:有一個 3 * 4 的矩陣,要求程式設計序求出其中值最大的那個元素的值,以及其所在的行號和列號
//有一個 3 * 4 的矩陣,要求程式設計序求出其中值最大的那個元素的值,以及其所在的行號和列號
#include <stdio.h>
int main(void)
{
int arr[3][4] = { { 1, 2, 3, 4 }, {9, 8, 7, 6 }, { -10, 10, -5, 2 } };
int iMax = arr[0][0], iCol = 0, iRow = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
(iMax > arr[i][j]) ? (iMax = iMax) : (iMax = arr[i][j], iRow = i, iCol = j);
}
printf("iMax = %d\niRow = %d\niCol = %d\n", iMax, iRow, iCol);
return 0;
}
執行結果:
字元陣列
字元型資料是以字元的ASCII程式碼儲存在儲存單元中的,一般佔一個位元組
由於ASCII程式碼也屬於整數形式,因此在C99標準中,把字元型別歸納為整型型別中的一種
C語言沒有字串型別,字串是存放在字元型陣列中
怎樣定義字元陣列
用來存放字元資料的陣列是字元陣列
字元陣列中的一個元素存放一個字元
定義字元陣列的方法與定義數值型陣列的方法類似
由於字元型資料是以整數形式(ASCII程式碼)存放的,因此可以用整型陣列它存放字元資料
字元陣列的初始化
對字元陣列初始化,最容易理解的方式是用“初始化列表”,把各個字元依次賦值給陣列中各元素char c[10] = { 'I', ' ', 'a', 'm', ' ', 'h', 'a', 'p', 'p', 'y' };
如果在定義字元陣列時不進行初始化,則陣列中各元素的值是不可預料的。
如果花括號中提供的初值個數(即字元個數)大於陣列長度,則出現語法錯誤。
如果初值個數小於陣列長度,則只將這些字元賦給陣列中前面那些元素,其餘的元素自動定位空字元(即'\0'
)
如果提供的初值個數與預定的陣列長度相同,在定義時可以省略陣列長度,系統會自動根據初值個數確定陣列長度
怎樣引用字元陣列中的元素
可以引用字元陣列中的一個元素,得到一個字元
例:輸出一個已知的字串
//輸出一個已知的字串
#include <stdio.h>
int main(void)
{
char arrCh[] = { 'I', ' ', 'a', 'm', ' ', 'a', ' ', 's', 't', 'u', 'd', 'e', 'n', 't', '.' };
for (int i = 0; i < 15; i++)
printf("%c", arrCh[i]);
printf("\n");
return 0;
}
執行結果:
字串和字串結束標誌
在C語言中,是將字串作為字元陣列來處理的
C語言規定了一個“字串結束標誌”,以字元'\0'
作為結束標誌,在遇到字元'\0'
時,表示字串結束,把它前面的字元組成一個字串
C系統在用字元陣列儲存字串常量時會自動加一個'\0'
作為結束符
有了結束標誌'\0'
後,字元陣列的長度就顯得不那麼重要了。在程式中往往依靠檢測'\0'
的位置來判定字串是否結束,而不是根據陣列的長度來決定字串長度。
如果在一個字元陣列中先後存放多個不同長度的字串,則應使陣列長度大於最長的字串的長度
'\0'
代表ASCII碼為 0 的字元,從ASCII碼錶中可以查到,ASCII碼為 0 的字元不是一個可以顯示的字元,而是一個“空運算子”,即它什麼也不做。用它來作為字串結束標誌不會產生附加的操作或增加有效字元,只起一個供辨別的標誌
可以用字串常量來使字元陣列初始化char c[] = { "I am happy" };
等價於char c[] = "I am happy";
等價於char c[] = { 'I', ' ', 'a', 'm', ' ', 'h', 'a', 'p', 'p', 'y', '\0' };
字元陣列並不要求它的最後一個字元為'\0'
,甚至可以不包含'\0'
,是否需要加'\0'
完全根據需要決定
由於系統在處理字串常量儲存時會自動加一個'\0'
,因此為了使處理方法一致,便於測定字串的實際上度,以及在程式中作相應的處理,在處理字元陣列中也常常人為的加上一個'\0'
字元陣列的輸入和輸出
字元陣列的輸入輸出可以有兩種方法:
- 逐個字元輸入輸出,用格式符
"%c"
輸入或輸出一個字元 - 將整個字串一次輸入輸出,用
"%s"
格式符,意思是對字串的輸入輸出
輸出的字元中不包括結束符'\0'
用"%s"
格式符輸出字串時,printf 函式中的輸出項是字串陣列名,而不是陣列元素名
如果陣列長度大於字串的實際長度,也只輸出到遇'\0'
結束
如果一個字串陣列中包含一個以上'\0'
則遇到第一個'\0'
時輸出結束
可以用 scanf 函式輸入一個字串scanf("%s", c);
c 是已定義的字元陣列名,輸入的字串應短於已定義的字元陣列的長度
//如果利用一個 scanf 函式輸入多個字串,則應在輸入時以空格分隔
char str1[5], str2[2], str3[5];
scanf("%s %s %s", str1, str2, str3);
scanf 函式中的輸入項如果是字元陣列名,不要再加地址符&
因為在C語言中陣列名代表該陣列的起始地址
使用字串處理函式
在C函式庫中提供了一些用來專門處理字串的函式
puts 函式--輸出字串的函式
一般形式:puts(字元陣列)
其作用是將一個字串(以'\0'
結束的字元序列)輸出到終端
用 puts 函式輸出的字串中可以包含跳脫字元
char str[] = "China";
puts(str);
//輸出 China
gets 函式--輸入字串的函式
一般形式:gets(字元陣列)
其作用是從終端輸入一個字串得到字元陣列,並且得到一個函式值。該函式值是字元陣列的起始地址
char str[1024];
gets(str);
//在終端獲取字串儲存在 str 中
一般利用 gets 函式的目的是向字元陣列輸入一個字串,而不大關心其函式值
puts 和 gets 函式只能輸出或輸入一個字串
strcat 函式--字串連線函式
其一般形式:strcat(字元陣列1, 字元陣列2)
其作用是把兩個字元陣列中的字串連線起來,把字串2接到字串1的後面,結果放在字元陣列1中,函式呼叫後得到一個函式值--字元陣列1的地址
char str1[100] = "People's Republic of ";
char str2[] = "China";
printf("%s", strcat(str1, str2));
//輸出 People's Republic of China
字元陣列1必須足夠大,以便容納連線後的新字串
連線前兩個字串的後面都有'\0'
連線時將字串1後面的'\0'
取消,只在新字串最後保留'\0'
strcpy 和 strncpy 函式--字串複製函式
其一般形式:strcpy(字元陣列1, 字元陣列2)
其作用是將字串2複製到字元陣列1中去
char str1[10], str2[] = "China";
strcpy(str1, str2);
//str1 = "China"
字元陣列1必須定義的足夠大,以便容納被賦值的字串2;字元陣列1的長度不應小於字串2的長度
“字元陣列1”必須寫成陣列名的形式,“字元陣列2”可以是字元陣列名,也可以是一個字串常量
不能用賦值語句將一個字串常量或字元陣列直接給一個字元陣列,只能用 strcpy 函式將一個字串複製到另一個字元陣列中去。用賦值語句只能將一個字元賦給一個字元型變數或字元陣列元素
可用用 strncpy 函式將字串2中前面n個字元賦值到字元陣列1中去
strcmp 函式--字串比較函式
其一般形式:strcmp(字串1, 字串2)
其作用是比較字串1和字串2
字串比較的規則是:將兩個字串自左向右逐個字元相比(按ASCII碼值大小比較)直到出現不同的字元或遇'\0'
為止
如果全部字元相同,則認為兩個字串相等
若出現不相同的字元,則以第一對不相同的字元的比較結果為準
比較的結果由函式值返回:
- 如果字串1=字串2,則返回0
- 如果字串1>字串2,則函式值是一個正整數
- 如果字串1<字串2,則函式值是一個負整數
strlen 函式--測字串長度的函式
其一般形式:strlen(字元陣列)
它是測試字串長度的函式,函式值為字串中的實際長度(不包括'\0'
在內)
strlwr 函式--轉換為小寫的函式
其一般形式:strlwr(字串)
其作用是將字串中大寫字母換成小寫字母
strupr 函式--轉換為大寫的函式
其一般形式:strupr(字串)
其作用是將字串中小寫字母換成大寫字母
在使用字串處理函式時,應當在程式檔案的開頭用#include <string.h>