11-C語言數(shù)組-指趣學院

數(shù)組的基本概念

  • 數(shù)組,從字面上看,就是一組數(shù)據(jù)的意思,沒錯,數(shù)組就是用來存儲一組數(shù)據(jù)的

    • 在C語言中,數(shù)組屬于構造數(shù)據(jù)類型
  • 數(shù)組的幾個名詞

    • 數(shù)組:一組相同數(shù)據(jù)類型數(shù)據(jù)的有序的集合
    • 數(shù)組元素: 構成數(shù)組的每一個數(shù)據(jù)。
    • 數(shù)組的下標: 數(shù)組元素位置的索引(從0開始)
  • 數(shù)組的應用場景

    • 一個int類型的變量能保存一個人的年齡,如果想保存整個班的年齡呢?
      • 第一種方法是定義很多個int類型的變量來存儲
      • 第二種方法是只需要定義一個int類型的數(shù)組來存儲
#include <stdio.h>

int main(int argc, const char * argv[]) {
    /*
    // 需求: 保存2個人的分數(shù)
    int score1 = 99;
    int score2 = 60;
    
    // 需求: 保存全班同學的分數(shù)(130人)
    int score3 = 78;
    int score4 = 68;
    ...
    int score130 = 88;
    */
    // 數(shù)組: 如果需要保存`一組``相同類型`的數(shù)據(jù), 就可以定義一個數(shù)組來保存
    // 只要定義好一個數(shù)組, 數(shù)組內(nèi)部會給每一塊小的存儲空間一個編號, 這個編號我們稱之為 索引, 索引從0開始
    // 1.定義一個可以保存3個int類型的數(shù)組
    int scores[3];
    
    // 2.通過數(shù)組的下標往數(shù)組中存放數(shù)據(jù)
    scores[0] = 998;
    scores[1] = 123;
    scores[2] = 567;
   
    // 3.通過數(shù)組的下標從數(shù)組中取出存放的數(shù)據(jù)
    printf("%i\n", scores[0]);
    printf("%i\n", scores[1]);
    printf("%i\n", scores[2]);
    return 0;
}

定義數(shù)組

  • 元素類型 數(shù)組名[元素個數(shù)];
// int 元素類型
// ages 數(shù)組名稱
// [10] 元素個數(shù)
int ages[10];

初始化數(shù)組

  • 定義的同時初始化
  • 指定元素個數(shù),完全初始化
    • 其中在{ }中的各數(shù)據(jù)值即為各元素的初值,各值之間用逗號間隔
int ages[3] = {4, 6, 9};
  • 不指定元素個數(shù),完全初始化
    • 根據(jù)大括號中的元素的個數(shù)來確定數(shù)組的元素個數(shù)
int nums[] = {1,2,3,5,6};
  • 指定元素個數(shù),部分初始化
    • 沒有顯式初始化的元素,那么系統(tǒng)會自動將其初始化為0
int nums[10] = {1,2};
  • 指定元素個數(shù),部分初始化
int nums[5] = {[4] = 3,[1] = 2};
  • 不指定元素個數(shù),部分初始化
int nums[] = {[4] = 3};
  • 先定義后初始化
int nums[3];
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
  • 沒有初始化會怎樣?
    • 如果定義數(shù)組后,沒有初始化,數(shù)組中是有值的,是隨機的垃圾數(shù),所以如果想要正確使用數(shù)組應該要進行初始化。
int nums[5];
printf("%d\n", nums[0]);
printf("%d\n", nums[1]);
printf("%d\n", nums[2]);
printf("%d\n", nums[3]);
printf("%d\n", nums[4]);
輸出結果:
0
0
1606416312
0
1606416414
  • 注意點:
  • 使用數(shù)組時不能超出數(shù)組的索引范圍使用, 索引從0開始, 到元素個數(shù)-1結束
  • 使用數(shù)組時不要隨意使用未初始化的元素, 有可能是一個隨機值
  • 對于數(shù)組來說, 只能在定義的同時初始化多個值, 不能先定義再初始化多個值
int ages[3];
ages = {4, 6, 9}; // 報錯

數(shù)組的使用

  • 通過下標(索引)訪問:
// 找到下標為0的元素, 賦值為10
ages[0]=10;
// 取出下標為2的元素保存的值
int a = ages[2];
printf("a = %d", a);

數(shù)組的遍歷

  • 數(shù)組的遍歷:遍歷的意思就是有序地查看數(shù)組的每一個元素
    int ages[4] = {19, 22, 33, 13};
    for (int i = 0; i < 4; i++) {
        printf("ages[%d] = %d\n", i, ages[i]);
    }

數(shù)組長度計算方法

  • 因為數(shù)組在內(nèi)存中占用的字節(jié)數(shù)取決于其存儲的數(shù)據(jù)類型和數(shù)據(jù)的個數(shù)
    • 數(shù)組所占用存儲空間 = 一個元素所占用存儲空間 * 元素個數(shù)(數(shù)組長度)
  • 所以計算數(shù)組長度可以使用如下方法
    數(shù)組的長度 = 數(shù)組占用的總字節(jié)數(shù) / 數(shù)組元素占用的字節(jié)數(shù)
    int ages[4] = {19, 22, 33, 13};
    int length =  sizeof(ages)/sizeof(int);
    printf("length = %d", length);
輸出結果: 4

練習

  • 正序輸出(遍歷)數(shù)組
    int ages[4] = {19, 22, 33, 13};
    for (int i = 0; i < 4; i++) {
        printf("ages[%d] = %d\n", i, ages[i]);
    }
  • 逆序輸出(遍歷)數(shù)組
    int ages[4] = {19, 22, 33, 13};
    for (int i = 3; i >=0; i--) {
        printf("ages[%d] = %d\n", i, ages[i]);
    }
  • 從鍵盤輸入數(shù)組長度,構建一個數(shù)組,然后再通過for循環(huán)從鍵 盤接收數(shù)字給數(shù)組初始化。并使用for循環(huán)輸出查看

數(shù)組內(nèi)部存儲細節(jié)

  • 存儲方式:

    • 1)內(nèi)存尋址從大到小, 從高地址開辟一塊連續(xù)沒有被使用的內(nèi)存給數(shù)組
    • 2)從分配的連續(xù)存儲空間中, 地址小的位置開始給每個元素分配空間
    • 3)從每個元素分配的存儲空間中, 地址最大的位置開始存儲數(shù)據(jù)
    • 4)用數(shù)組名指向整個存儲空間最小的地址
  • 示例

#include <stdio.h>
int main()
{
    int num = 9;
    char cs[] = {'l','n','j'};
    printf("cs = %p\n", &cs);       // cs = 0060FEA9
    printf("cs[0] = %p\n", &cs[0]); // cs[0] = 0060FEA9
    printf("cs[1] = %p\n", &cs[1]); // cs[1] = 0060FEAA
    printf("cs[2] = %p\n", &cs[2]); // cs[2] = 0060FEAB

    int nums[] = {2, 6};
    printf("nums = %p\n", &nums);      // nums = 0060FEA0
    printf("nums[0] = %p\n", &nums[0]);// nums[0] = 0060FEA0
    printf("nums[1] = %p\n", &nums[1]);// nums[1] = 0060FEA4
    
    return 0;
}
  • 注意:字符在內(nèi)存中是以對應ASCII碼值的二進制形式存儲的,而非上述的形式。

數(shù)組的越界問題

  • 數(shù)組越界導致的問題
    • 約錯對象
    • 程序崩潰
    char cs1[2] = {1, 2};
    char cs2[3] = {3, 4, 5};
    cs2[3] = 88; // 注意:這句訪問到了不屬于cs1的內(nèi)存
    printf("cs1[0] = %d\n", cs1[0] );
輸出結果: 88

為什么上述會輸出88, 自己按照"數(shù)組內(nèi)部存儲細節(jié)"畫圖腦補


數(shù)組注意事項

  • 在定義數(shù)組的時候[]里面只能寫整型常量或者是返回整型常量的表達式
 int ages4['A'] = {19, 22, 33};
 printf("ages4[0] = %d\n", ages4[0]);

  int ages5[5 + 5] = {19, 22, 33};
  printf("ages5[0] = %d\n", ages5[0]);

  int ages5['A' + 5] = {19, 22, 33};
  printf("ages5[0] = %d\n", ages5[0]);
  • 錯誤寫法
// 沒有指定元素個數(shù),錯誤
int a[];

// []中不能放變量
int number = 10;
int ages[number]; // 老版本的C語言規(guī)范不支持
printf("%d\n", ages[4]);

int number = 10;
int ages2[number] = {19, 22, 33} // 直接報錯

// 只能在定義數(shù)組的時候進行一次性(全部賦值)的初始化
int ages3[5];
ages10 = {19, 22, 33};

// 一個長度為n的數(shù)組,最大下標為n-1, 下標范圍:0~n-1
int ages4[4] = {19, 22, 33}
ages4[8]; // 數(shù)組角標越界
  • 練習
    • 從鍵盤錄入當天出售BTC的價格并計算出售的BTC的總價和平均價(比如說一天出售了10個比特幣)

數(shù)組和函數(shù)

  • 數(shù)組可以作為函數(shù)的參數(shù)使用,數(shù)組用作函數(shù)參數(shù)有兩種形式:
    • 一種是把數(shù)組元素作為實參使用
    • 一種是把數(shù)組名作為函數(shù)的形參和實參使用

數(shù)組元素作為函數(shù)參數(shù)

  • 數(shù)組的元素作為函數(shù)實參,與同類型的簡單變量作為實參一樣,如果是基本數(shù)據(jù)類型, 那么形參的改變不影響實參
void change(int val)// int val = number
{
    val = 55;
}
int main(int argc, const char * argv[])
{
    int ages[3] = {1, 5, 8};
    printf("ages[0] = %d", ages[0]);// 1
    change(ages[0]);
    printf("ages[0] = %d", ages[0]);// 1
}
  • 用數(shù)組元素作函數(shù)參數(shù)不要求形參也必須是數(shù)組元素

數(shù)組名作為函數(shù)參數(shù)

  • 在C語言中,數(shù)組名除作為變量的標識符之外,數(shù)組名還代表了該數(shù)組在內(nèi)存中的起始地址,因此,當數(shù)組名作函數(shù)參數(shù)時,實參與形參之間不是"值傳遞",而是"地址傳遞"
  • 實參數(shù)組名將該數(shù)組的起始地址傳遞給形參數(shù)組,兩個數(shù)組共享一段內(nèi)存單元, 系統(tǒng)不再為形參數(shù)組分配存儲單元
  • 既然兩個數(shù)組共享一段內(nèi)存單元, 所以形參數(shù)組修改時,實參數(shù)組也同時被修改了
void change2(int array[3])// int array = 0ffd1
{
    array[0] = 88;
}
int main(int argc, const char * argv[])
{
    int ages[3] = {1, 5, 8};
    printf("ages[0] = %d", ages[0]);// 1
    change(ages);
    printf("ages[0] = %d", ages[0]);// 88
}

數(shù)組名作函數(shù)參數(shù)的注意點

  • 在函數(shù)形參表中,允許不給出形參數(shù)組的長度
void change(int array[])
{
    array[0] = 88;
}
  • 形參數(shù)組和實參數(shù)組的類型必須一致,否則將引起錯誤。
void prtArray(double array[3]) // 錯誤寫法
{
    for (int i = 0; i < 3; i++) {
        printf("array[%d], %f", i, array[i]);
    }
}
int main(int argc, const char * argv[])
{
    int ages[3] = {1, 5, 8};
    prtArray(ages[0]);
}
  • 當數(shù)組名作為函數(shù)參數(shù)時, 因為自動轉換為了指針類型,所以在函數(shù)中無法動態(tài)計算除數(shù)組的元素個數(shù)
void printArray(int array[])
{
    printf("printArray size = %lu\n", sizeof(array)); // 8
    int length = sizeof(array)/ sizeof(int); // 2
    printf("length = %d", length);
}
  • 練習:
    • 設計一個函數(shù)int arrayMax(int a[], int count)找出數(shù)組元素的最大值
    • 從鍵盤輸入3個0-9的數(shù)字,然后輸出0~9中哪些數(shù)字沒有出現(xiàn)過
    • 要求從鍵盤輸入6個0~9的數(shù)字,排序后輸出
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容