利用陣列處理批次資料

EricsT發表於2024-10-23

陣列是一組有序資料的集合。陣列中各資料的排列有一定規律,下標代表資料在陣列中的序號

用一個陣列名和下標來唯一的確定陣列中的元素

陣列中的每一個元素都屬於同一個資料型別。不能把不同型別的資料放在同一個陣列中

將陣列和迴圈結合起來,可以有效的處理大批次的資料

怎樣定義和引用一維陣列

一維陣列是陣列中最簡單的,它的元素只需要用陣列名加一個下標,就能唯一的確定

怎樣定義一維陣列

要使用陣列,必須在程式中先定義陣列,即通知計算機:由哪些資料組成陣列,陣列中有多少元素,屬於哪個資料型別。否則計算機不會自動的把這一批資料作為陣列處理。

定義一維陣列的一般形式:型別符 陣列名[常量表示式]

陣列名的命名規則和變數名相同,遵循識別符號命名規則

在定義陣列時,需要指定陣列中元素的個數,方括號中的常量表示式用來表示元素的個數,即陣列長度

常量表示式中可以包括常量和符號常量,不能包含變數。也就是說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開始的

一維陣列的初始化

為了使程式簡潔,常在定義陣列的同時,給各陣列元素賦值,這稱為陣列的初始化。可以用“初始化列表”方法實現陣列的初始化

  1. 在定義陣列時,對全部陣列元素賦予初值int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }將陣列中元素的初值順序放在一堆花括號內,資料間用逗號分隔 。花括號內的資料就稱為“初始化列表”
  2. 可以只給陣列中的一部分元素賦值int a[10] = { 0, 1, 2, 3, 4 }定義陣列有10個元素,但括號內只提供5個初值,這表示只給前面5個元素賦初值,系統自動給後面5個元素賦初值為0
  3. 如果想使一個陣列中全部元素值為0,可以寫成int a[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }或者int a[10] = { 0 } //未賦值的部分元素自動設為0
  4. 在對全部陣列元素賦初值時,由於資料的個數已經確定,因此可以不指定陣列長度int a[5] = { 1, 2, 3, 4, 5 }可以寫成int a[] = { 1, 2, 3, 4, 5 }

如果陣列長度與提供初值的個數不一致時,則方括號中的陣列長度不能省略

如果在定義數值型陣列時,指定了陣列的長度並對之初始化,凡未被“初始化列表”指定初始化的陣列元素,系統會自動把它們初始化為0(如果是字元型陣列,則初始化為‘\0’,如果是指標型陣列,則初始化為NULL,即空指標)

怎樣定義和引用二維陣列

二維陣列通常稱為矩陣。把二維陣列寫成行和列的排列形式,可以有助於形象化的理解二維陣列的邏輯結構

怎樣定義二維陣列

二維陣列定義的一般形式為:型別說明符 陣列名[常量表示式][常量表示式];

C語言對二維陣列採用這樣的定義方式,使得二維陣列可以被看作是一種特殊的一維陣列:它的元素又是一個一維陣列。

C語言中,二維陣列中元素排列的順序是按行存放的,即在記憶體中先順序存放第一行的元素,接著再存放第二行的元素...

用矩陣形式表示二維陣列,是邏輯上的概念,能形象的表示出行列關係。而在記憶體中,各元素是連續存放的,不是二維的,是線性的。

C語言還允許使用多維陣列,多維陣列元素在記憶體中排列的順序為:第一維的下標變化最慢,最右邊的下標變化最快

怎樣引用二維陣列的元素

二維陣列元素的表示形式:陣列名[下標][下標]下標應是整型表示式

陣列元素可以出現在表示式中,也可以被賦值

在引用陣列元素中,下標值應在已定義的陣列大小的範圍內。

二維陣列的初始化

可以用“初始化列表”對二維陣列初始化

  1. 分行給二維陣列賦初值:int a[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }};這種賦初值方法比較直觀,把第一個花括號內的資料給第一行的元素,第二個花括號內的資料給第二行的元素...即按行賦值
  2. 可以將所有資料寫在一個花括號內,按陣列元素在記憶體中的排列順序對各元素賦初值:int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };效果和第一種方法相同,但是這種不直觀,容易遺漏,不易檢查
  3. 可以對部分元素賦初值:int a[3][4] = { { 1 }, { 5 }, { 9 } };未賦值元素自動賦0,對非0元素少時方便
  4. 如果對全部元素都賦初值(即提供全部初始資料),則定義陣列時對第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 };
  5. 在定義時也可以只對部分元素賦初值而省略第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'

字元陣列的輸入和輸出

字元陣列的輸入輸出可以有兩種方法:

  1. 逐個字元輸入輸出,用格式符"%c"輸入或輸出一個字元
  2. 將整個字串一次輸入輸出,用"%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>

相關文章