C說話中數組的一些根本常識小結。本站提示廣大學習愛好者:(C說話中數組的一些根本常識小結)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話中數組的一些根本常識小結正文
初始化數組
int ages[3] = {4, 6, 9}; int nums[10] = {1,2}; // 其他的主動初始化為0 int nums[] = {1,2,3,5,6}; // 依據年夜括號中的元素個數肯定數組元素的個數 int nums[5] = {[4] = 3,[1] = 2}; // 指定元素個數,同時給指定元素停止初始化 int nums[3]; nums[0] = 1; nums[1] = 2; nums[2] = 3; // 先界說,後初始化
界說然則未初始化,數組中有值,然則是渣滓值。
關於數組來講,一旦有元素被初始 化,其他元素都被賦值0。
盤算數組中元素的個數
int count = sizeof(數組) / sizeof(數組[0]) // 數組的長度 = 數組占用的總字節數 / 數組元素占用的字節數
數組留意事項
在界說數組的時刻[]外面只能寫整型常量或許是前往整型常量的表達式。
int ages['A'] = {19, 22, 33}; printf("ages[0] = %d\n", ages[0]); int ages[5 + 5] = {19, 22, 33}; printf("ages[0] = %d\n", ages[0]); int ages['A' + 5] = {19, 22, 33}; printf("ages[0] = %d\n", ages[0])
毛病寫法。
沒有指定元素個數(int nums[] = {1,2,3,5,6}; 如許是可以的,然則假如先聲明,並沒有初始化,則是毛病的)
int a[]; // 毛病
[]中不克不及放變量
int number = 10; int ages[number]; // 不報錯, 然則沒有初始化, 外面是隨機值 > int number = 10; > > int ages[number] = {19, 22, 33} // 直接報錯 - > int ages10[5]; > > ages10 = {19, 22, 33}; // 毛病。只能在界說數組的時刻停止一次性(全體賦值)的初始化
- 拜訪數組越界。
數組的內存分派:
變量在內存中是從年夜到小尋址的(內存中以字節為單元),好比00000000 00000000 00000000 00001010在內存中,00001010的地址是最小的;而數組則有些分歧,數組的元素天然的從上往下分列 存儲,全部數組的地址為首元素的地址。 (然則構成元素的字節照樣按從年夜到小)
留意:字符在內存中是以對應ASCII值的二進制情勢存儲的,而非上表的情勢。 在這個例子中,數組x的地址為它的首元素的地址0x08,數組ca的地址為0x03。
留意數組越界成績,越界會拜訪到其他內容(好比有兩個數組在內存中挨著,第一個數組越界能夠會拜訪到第二個數組的元素),乃至會讓法式瓦解。
當數組名作為函數參數時, 由於主動轉換為了指針類型,所以在函數中沒法靜態盤算除數組的元素個數。
在64位編譯器下,指針類型默許為8個字節。
有的時刻我們能夠想要在一個函數外面靜態盤算數組的個數,所以能夠會這麼做:
void printMyArray(int myArray[]) { int length = sizeof(myArray) / sizeof(myArray[0]); for(int i = 0; i < length; i++) { printf("%i", myArray[i]); } } int main() { int myArray[5] = {1,2,3,4,5}; printMyArray(myArray); return 0; }
可以看到在printMyArray函數中我們靜態盤算傳出去的數組的個數,然則成果是毛病的,由於它只能輸入前兩個數。
這是由於,在把數組當做函數的參數的時刻,數組會被以為成指針,所所以8個字節,所以盤算出的length是2,所以只能輸入前兩個數字。
處理:我們須要給出一個新的參數來取得length,在main()外面盤算好length然後傳入printMyArray。
void printMyArray(int myArray[], int length) { for(int i = 0; i < length; i++) { printf("%i ", myArray[i]); } } int main(int argc, const char * argv[]) { int myArray[5] = {1,2,3,4,5}; int length = sizeof(myArray) / sizeof(myArray[0]); printMyArray(myArray, length); return 0; }
“填坑法”的思惟:
好比給出如許一題。請求從鍵盤輸出6個0~9的數字,排序後輸入。
做法有許多,”填坑法”的意思就是起首界說一個10個數的數組(0~9),初始化都為0。
接著接收用戶的輸出(可以用for輪回),症結的一步是,將用戶輸出的值作為數組的下標,將這個下標所對應的值改成1(填坑),再接著for輪回輸入數組中值是1的索引。
// 空間換時光, 合適數據比擬少 // 1.界說數組,保留用戶輸出的整數 // 必定要給數組初始化, 不然有能夠是一些隨機值 int numbers[10] = {0}; // 2.吸收用戶輸出的整數 // 2.1界說變量吸收用戶輸出的整數 int index = -1; for (int i = 0; i < 6; i++) { printf("請輸出第%d個整數\n", i + 1); scanf("%d", &index); // 將用戶輸出的值作為索引取修正數組中對應的元素的值為1 // 指針的時刻回來演示適才的成績 numbers[index] = 1 ; } int length = sizeof(numbers) / sizeof(numbers[0]); for (int i = 0; i < length; i++) { if (1 == numbers[i]) { // 輸入索引 printf("%d", i); } }
這個做法的要點是數組中的初始值都為0,而數組的索引和用戶輸出的數字是逐個對應的,所以只須要將用戶輸出的數字絕對應的索引的元素改成1,然後再for輪回輸入的話相當於有序輸入,最初獲得成果。
然則這類做法是有成績的,好比用戶輸出了反復的數字,然則下面的做法只能將雷同的數字輸入一次。我們的做法是將雷同索引的元素的數字累加,以後再增長一層輪回來停止輸入。
// 1.界說數組,保留用戶輸出的整數 int numbers[10] = {0}; // 2.吸收用戶輸出的整數 // 2.1界說變量吸收用戶輸出的整數 int index = -1; for (int i = 0; i < 6; i++) { printf("請輸出第%d個整數\n", i + 1); scanf("%d", &index); // 將用戶輸出的值作為索引取修正數組中對應的元素的值為1 // 假定 用戶輸出的是 1,1,1,2,2,2 numbers[index] = numbers[index] + 1 ; } int length = sizeof(numbers) / sizeof(numbers[0]); for (int i = 0; i < length; i++) { // j = 1 由於假如數組元素中存儲的值是0不消輸入 // 將i對應存儲空間中的元素掏出,斷定須要輸入幾回 for (int j = 1; j <= numbers[i]; j++) { printf("%d", i);// 1 1 1 2 2 2 } }
選擇排序
重要思惟就是,根本上默許數組中第一個元素為最年夜(最小)值,以後將這個元素和前面的每一個元素都停止比擬,以由年夜到小排序為例,當第一個值碰到比其年夜的,就停止交流。如許第一輪事後,第一名就是最年夜的。接著停止第二輪,由第二個數開端逐一比擬,碰到比第二個數年夜的停止交流,如許第二輪以後第二個數就是第二年夜的了,以此類推,赓續停止選擇,最初完成排序。
void selectSort(int numbers[], int length) { for (int i = 0; i < length; i++) { for (int j = i + 1; j < length; j++) { if (numbers[i] < numbers[j]) { int temp = numbers[i]; numbers[i] = numbers[j]; numbers[j] = temp; } } } } int main(int argc, const char * argv[]) { int myArray[] = {42, 7, 1, -3, 88}; int length = sizeof(myArray) / sizeof(myArray[0]); selectSort(myArray, length); for (int i = 0; i < length; i++) { printf("%i ", myArray[i]); } return 0; }
在寫的時刻可以如許想:當第一個數來比擬的時刻,i = 0,那末j應當等於i + 1,由於第一個數要和第二個數開端比,而且比擬length - 1次;當i = 1時,j = 2,而且比擬length - 2次,以此類推;下面寫的是由年夜到小排序。
冒泡排序
重要思惟是兩個相鄰的元素停止比擬,以由小到年夜排序為例,那末由第一個元素開端和第二個比擬,假如第一個比第二個年夜,那末就停止交流;然落後行第二個和第三個元素的比擬,以此類推,第一輪以後,那末數組的最初一個元素就是最年夜的,以此類推。
void bubbleSort(int numbers[], int length) { for (int i = 0; i < length - 1; i++) { for (int j = 0; j < length - i - 1; j++) { if (numbers[j] > numbers[j + 1]) { int temp = numbers[j]; numbers[j] = numbers[j + 1]; numbers[j + 1] = temp; } } } } int main(int argc, const char * argv[]) { int myArray[] = {42, 7, 1, -3, 88}; int length = sizeof(myArray) / sizeof(myArray[0]); bubbleSort(myArray, length); for (int i = 0; i < length; i++) { printf("%i ", myArray[i]); } return 0; }
留意這裡和選擇排序分歧的是,比擬的並不是numbers[i]和numbers[j],而是比擬的numbers[j]和numbers[j+1],而外層輪回的i代表比擬的輪數,內層輪回才是真實的每輪停止的比擬。這裡是由小到年夜排序。
折半查找
折半查找望文生義,我們找到數組的最年夜值max,最小值min求出中央值mid,然後用mid作為數組下標獲得對應的元素,用這個元素和目的值key停止比擬:
假如numbers[mid] > key,那末解釋key在min和mid之間,那末就設置max為mid - 1,min不變,然後從新盤算mid,反復上述步調,最初找出key。
假如numbers[mid] < key,那末解釋key在mid和max之間,那末就設置min為mid + 1,max不變,然後從新盤算mid,反復上述步調,最初找出key。
留意這裡的停止前提,有能夠數組中有這個key,也有能夠沒有,那末當min > max時,解釋數組中並沒有這個key,要當心這類情形。
折半查找請求數組必需是有序的。(有序表)
int binSearch(int myArray[], int length, int key) { int index = -1; int max = length - 1; int min = 0; int mid = (max + min) / 2; while (min <= max) { if (myArray[mid] > key) { max = mid - 1; } else if (myArray[mid] < key){ min = mid + 1; } else if (myArray[mid] == key) { index = mid; break; } mid = (max + min) / 2; } return index; } int main(int argc, const char * argv[]) { int myArray[] = {-3, 1, 7, 42, 88}; int length = sizeof(myArray) / sizeof(myArray[0]); int index = binSearch(myArray, length, 88); printf("index: %i ", index); return 0; }
起首我假定index = -1,表現沒有響應的值。接著獲得max,min,mid的值,留意while輪回的前提,在這裡我用的是當min <= max的時刻輪回,當min > max時刻跳出輪回,解釋並未找到key的值。在輪回體外面,像適才剖析的那樣斷定,當myArray[mid] == key的時刻解釋我們找到了這個值,那末將index設置成找到值的下標,然後跳出輪回。假如未找到值則index = -1。