C 语言--数组

jefxff 153,637 2020-08-10

数组

标量和聚合变量: 标量(scalar)具有保存单一数据项的能力; 聚合(aggregate)变量可以存储一组一组的数值;
C语言中聚合变量包括: 数组(array) 和 结构(structure)


1. 一维数组

数组是包含多个数据值且具有相同数据类型的数据结构, 每一个数据值称为元素(element);

含义: 一维数组中的元素一个接一个地编排在单独的一行

1.1 数组声明

  • type arrayName[intSize]; 如: int arr[10]: 就表示声明了一个数组arr, 数组的元素是10个int类型的元素;
  • 最好是使用宏来定义数组的长度, 即: # define N 10; int arr[N]

数组下标(index):

  • 数组元素始终从0开始, 到数组长度 n-1 结束, 通过 arrayName[index] 就可以访问数组的元素

  • C语言不检查数组的下标范围, 不像Java会有数组越界异常; C语言数组下标越界会产生不可预知的行为

1.2 数组初始化

  • C语言数组初始化和Java中的静态初始化一样, 即直接采用大括号对每一元素赋值; 如 int arr[2] = {1, 2}
  • 如果赋值了一部分元素, 另外一部分元素未赋值, 此时剩余的元素的值为0
  • 所以可以采用技巧: 即 int arr[10] = {0} 这种形式来将数组的元素的值全部设为0; (其实这只初始化了第一个元素, 但是编译器会自动将其他元素初始化为0)
  • 如果直接给定了初始化式; 也可以省略数组的长度

1.3 指定初始化式

  • 指定初始化式意思就是声明一个数组后, 并不想对数组的元素全部初始化赋值, 而是仅仅想对其中的某些元素进行显式的初始化, 此时就需要指示符: 通过 [index] = value 的形式对数组的指定位置的元素进行显式初始化; [index] 中index就是指示符, 他的范围就是数组元素的范围 即: 0 ~ n-1

  • 如: int arr[15] = {[1]=12, [5]=14, [9]=7,[14]=29};

  • 如果通过显式的指定初始化式, 二没有指定数组的长度, 那么数组的长度就是指定初始化式中index中的最大值加1;

    # include <stdio.h>
    
    int main() {
    	// 定义数组, 不指定长度, 数组通过老式的(对应index赋值), 以及指示符来混合赋值; 而数组的长度
    	// 是由指示符中 index 的最大值确定的, 即下面的数组的长度是8; 即 7 + 1 决定的
        // 对于没有指定的值的元素, 其值就是 0
        int arr[] = {1, 2, 3, [3] = 4, [7] = 5};
    
        for (int i = 0; i < 8; i++ ) {
            printf("%d ", arr[i]);  // 输出: 1 2 3 4 0 0 0 5
        }
    }
    

1.4 对数组sizeof运算

  • sizeof() 方法可以确定类型的字节数, 也可以确定数组的字节数, Java中可以直接通过 len(array) 或在 array.size() 来确定数组的大小, 但是C语言目前所学的只能通过sizeof() 来确定

  • sizeof(array) 获取的是数组的字节数, 而sizeof(array[0]) 获取的是数组的元素的字节数, 所以通过 (sizeof(arr) / sizeof(arr[0]) )即可获取此数组的大小;

  • sizeof(array) 返回值类型是 size_t (一种无符号类型); 而通常需要强转为有符号整数类型来使用

  • 通常这种方法获取数组的长度时, 通过 宏定义来做: # difine (SIZE (int) (sizeof(arr) / sizeof(arr[0])))

    # include <stdio.h>
    
    // 通过宏定义来获取数组的长度
    # define SIZE ((int) (sizeof(arr) / sizeof(arr[0])))
    
    int main() {
        // 指示符最大值小于数组初始化的元素, 所以数组的长度是由指示符最大值加上指示符后面初始化元素的个数确定
        int arr[] ={ 1, 2, 3, [3] = 4, [7] = 5, [6] = 9, 89, 25, 27, 55, 44, 99 };
    
        printf("arrays's length is: %d\n", SIZE); // 输出: arrays's length is: 13
    
        // 程序中直接使用定义好的宏即可
        for (int i = 0; i < SIZE; i++) {
            printf("%d ", arr[i]);  // 输出: 1 2 3 4 0 0 9 89 25 27 55 44 99
        }
        return 0;
    }
    

2. 多维数组

2.1 多维数组声明及初始化

声明二维数组

  • 二维数组可以理解成是一个二维矩阵, 如: 定义一个 int arr[5][6] 的二维数组, 可以想象成是一个5 行6列的二维矩阵
  • 访问二维数组可以通过 arr[i][j], 这种形式来访问, 即获取的是arr二维数组低i行, 第j列确定的唯一元素
  • 实际上C语言定义的二维数组在内存中是按照 行主序 存储数组的, 也就是第0行(所有元素排列), 紧接着第一行(所有元素排列)......

初始化二维数组

  • 通过嵌套一维初始化的方法来初始化二维数组

  • 也可以通过指定初始化式对多维数组进行初始化

    // 嵌套一维初始化的方法来初始化二维数组
    int arrs[5][9] ={ { 1, 1, 1, 1, 2, 0, 0, 0, 1 },
                     { 1, 1, 1, 1, 2, 0, 0, 0, 1 },
                     { 1, 1, 1, 1, 2, 0, 0, 0, 1 },
                     { 1, 1, 1, 1, 2, 0, 0, 0, 1 },
                     { 1, 1, 1, 1, 2, 0, 0, 0, 1 }};
    
    // 通过指定初始化式对多维数组进行初始化
    int arrs[5][9] = {  [0][0] = 1, [1][2] = 4, [3][8] = 8, [4][8] = 99 };
    
     // 程序输出:
     // 1  0  0  0  0  0  0  0  0
     // 0  0  4  0  0  0  0  0  0
     // 0  0  0  0  0  0  0  0  0
     // 0  0  0  0  0  0  0  0  8
     // 0  0  0  0  0  0  0  0 99
    

2.2 常量数组

常量数组含义

  • 常量数组即数组中的元素不可改变

  • 常量数组通过 const类型限定符来修饰; 声明常量数组是只需在数组前加关键字 const 即可;

  • const 不仅仅用于数组, 也可以和任何变量一起使用,

    // 定义一个常量数组
    const char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', 
                             '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    

3. C99中的变长数组

变长数组含义

  • 变长数组(variable-length array, VLA)的长度是在程序执行时计算的, 而不是在程序编译时计算的, 其优点是不必在构造数组时指定一个长度, 程序在执行时可以准确地计算出所需的元素个数(程序员直接在构造数组时指定的话可能会使数组过长或过短)

  • 边长数组的长度可以是变量, 也可以是任意表达式

  • 变长数组主要限制是他们没有静态存储期限

    // 定义变长数组
    int arr1[3 * i + 5]
    int arr2[j + k]
    
    int arr3[i+5][j+3]
    

# C # 数组