数组

数组可以存储一个固定大小的相同类型元素的顺序集合

数组的目的是存储一系列数据,但它往往被认为是一系列相同的变量

数组一旦被创建了就不能再改变它的大小了,元素在内存中是连续依次排列的

格式

声明数组
  • 数据类型 变量名称 [元素数量]

  • 元素的数量必须是整数

    • 例如:double number[5]

      意味着这是一维数组,声明了一个类型为int包含了5个元素的数组number,它可以容纳5个int类型的数据

初始化数组
  1. 可以逐个初始化数组,也可以使用一条初始化语句数据类型 变量名称 [元素数量] = { 1000.0 , 2.0 , 3.4 , 7.0 , 50.0 }

    如果元素数量很多个,初始化的值只有一个的情况下,除了第一个元素会是初始化的值以外,其余全是0

    指定元素初始化数据类型 变量名称 [元素数量] = { [0] = 1000.0 , [2] = 3.4 , 7.0 , [4] = 50.0 },当指定了索引的时候,初始化会根据索引来定位,没有指定索引的数据接在前面一个数据的后面,其他没有初始化的值仍然是0

    如果没有声明元素数量的话,则按照初始时元素的个数来定义

  2. 创建一个数组,它与声明数组时的变量名称是相同的变量名称 [索引] =

    索引从0开始计数

    从元素0开始,数组后面的每个索引都是数组的个数减1

    索引有效的范围是从[0 ~ 数组大小-1],一旦越界可能会出现程序崩溃等问题

    number[4] = 50.0 意味着number数组里的第五个元素的值是50.0

    除了可以直接写索引数值外还可以写上变量,但是如果你需要依次向后填入数值的话,这个变量需要变化

    05-31_11:20

赋值数组元素
  • 数组元素可以通过数组名称 [索引]进行访问,所以也能将索引对应的元素赋值给其他变量
  • 可以出现在复制的左边或者右边,把数组放在右边就是读取它的值,放在左边就是将右边的数值写入数组
  • number[3] = number[5] + 6 即把数组中的第六个元素的值加上六后写入到数组第四个元素中
  • double num4 = number [3]即把数组中的第四个元素的值赋给了num4变量

遍历数组

通常采取for循环的方式,让循环的变量i从0到i<元素数量,这样循环体内最大的i正好是数组最大的有效索引

而不可以将循环结束的条件<=元素数量,也不可以在离开循环之后继续将i的值来作为数组元素的索引

数组的大小

sizeof函数能给出整个数组所占据内容的大小,单位是字节

使用sizeof(数组名称)可以得到整个数组的字节sizeof(number)/sizeiof(number[0])

sizeof(number[0])给出了数组中单个元素的大小,于是相除就得到了数组的元素个数

这样的计算方式能够让代码复用,当修改数组中初始的数据时,不需要修改遍历的代码

数组传值

  1. 如果想把a数组中的所有元素直接赋值给b数组,只能通过for循环的方式实现
  • 数组变量本身不能被赋值
  • 需要赋值的时候只能采取遍历将一个数组中的所有元素交给另一个数组
1
2
3
for ( i = 0 ; i < length (number的元素数量) ; i++ ){
new[i] = number[i];
}
  1. 当数组作为函数参数时,往往还必须再用另一个函数来传入数组的大小
  • 不能在[]中给出数组的大小
  • 不能再利用sizeof去计算数组的元素个数
1
2
3
4
5
int secondary(int size);
int main
int size = sizeof(number)/ sizeof(number[0]);
secondary(size);
int secondary(int size)

练习

  1. 写出一个程序计算用户输入一个数字的数量,用户可以输入这么多数量的数字,当输入-1的时候结束用户输入,计算这些数字的平均数,并输出所有大于平均数的数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <stdio.h>

    int main() {
    int x;
    double sum = 0;
    int time;
    printf("请输入数字的数量:");
    scanf("%d", &time);
    if ( time > 0){
    int num[time]; // C99的特性,可以根据动态的变量去定义数组数量
    scanf("%d", &x);
    for ( time = 0; x != -1 ; time++) { // time从0开始,每轮time++,直到x = -1结束循环
    num[time] = x;
    sum += x;
    scanf("%d", &x); // 输入-1结束循环
    }
    if ( time > 0) {
    double avg = sum / time; // 计算平均数
    for (int i = 0; i < time; i++) {
    if (num[i] > avg) { // num[i] = num[time] = x > avg
    printf("%d\n", num[i]);
    }
    }
    }
    }
    return 0;
    }
  2. 写出一个程序,输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数,当输入-1的时候表示结束

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <stdio.h>

    int main() {
    const int NUM = 10; // 定义常量NUM的值为 10
    int i;
    int x;
    scanf("%d", &x);
    int time[NUM] = {0}; // 有10个int类型的数据,并将它们全都初始化为0
    while ( x != -1 ){
    if ( x > 0 && x <= NUM - 1 ){
    time[x]++; // 当x满足0 < x < 9,让time[ x:0 ~ 9 ]++
    }
    scanf("%d", &x); // 输出-1结束
    }
    for ( i = 0; i < NUM ; i++) { // i : 0 ~ 9
    printf("%d:%d\n", i, time[i]); // time[i:0 ~ 9 ]出现过几次就会输出多少次
    }
    return 0;
    }

    05-31_16:40

  3. 当用户输入某个数值时,从一组固定的数据中寻找是否存在,如果存在就输出它和它在数组中的位置,不存在就输出-1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <stdio.h>
    int search( int y, b[], size ); // 声明函数
    int main() {
    int a[] = { 1 , 3 , 5 , 7 , 9 , 2 , 4 , 6 , 8 , 10 };
    int x;
    int size = sizeof(a)/ sizeof(a[0]); // 得到元素个数
    int loc;
    printf("请输入一个数字:");
    scanf("%d", &x);
    loc = search( x , a , size ); // 传值给search函数,返回loc = ret;
    if ( loc != -1 ){
    printf("%d在第%d个位置上\n", x, loc);
    } else{
    printf("%d不存在\n", x);
    }
    return 0;
    }
    int search( int y, b[], size ){
    int ret = -1;
    int i;
    for ( i = 0; i < size; i++) { // 遍历数组
    if ( b[i] == y ){ // 当数组中的数等于用户输入数时返回ret = i 的值
    ret = i; // 否则返回ret = -1
    break;
    }
    }
    return ret;
    }
  4. 老朋友:素数

    // 数组都没整明白又来让我脑壳痛的素数🙃,先囫囵吞枣消化再说

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    /*
    * 构建n以内的素数表
    * 0. 定义,并初始化数组prime[n]所有元素为1
    * 当prime[x]为1则表示x是素数
    * 1. 让x的值为2
    * 2. 让2x、3x、4x 直至到n倍数的数标记为非素数
    * 3. 如果x是素数,则对于( i = 2; x * i < n; i++ )令prime[i * x] = 0
    * 4. 令x为下一个没有被标记的非素数的数重复步骤2
    * 直到所有的数都已经尝试完成
    * */
    #include <stdio.h>

    int main() {
    int i;
    int n;
    scanf("%d", &n);
    int isPrime[n];
    int x;
    for ( i = 0; i < n; i++) {
    isPrime[i] = 1;
    }
    for ( x = 2; x < n ; x++) {
    if ( isPrime[x] ){
    for ( i = 2; i * x < n; i++) {
    isPrime[i * x] = 0;
    }
    }
    }
    for ( i = 2; i < n ; i++) {
    if ( isPrime[i]){
    printf("%d\t", i);
    }
    }
    return 0;
    }

二维数组

格式

  • 数据类型 变量名 [行] [列]

  • 例如int a[3][5]可以理解成a是一个3行5列的矩阵

    a[0][0] a[0][1] a[0][2] a[0][3] a[0][4]
    a[1][0] a[1][1] a[1][2] a[1][3] a[1][4]
    a[2][0] a[2][1] a[2][2] a[2][3] a[2][4]

遍历

与一维数组不同的是,二维数组的遍历需要将行和列都带上,外层是行,内层是列

1
2
3
4
5
for ( i = 0; i < 3; i++ ){
for ( j = 0; j < 5; j++){
a[i][j] = i * j;
}
}
  • a[x][y]是一个int
  • 代表第x行第y列上的元素

初始化

1
2
3
4
int a[][5] = {
{0,1,2,3,4},
{10,9,8,7,6}
};
  • 列数是必须指定的,但是行数可以让编译器自己去生成
  • 每行一个{},使用逗号分隔
  • 和一维数组一样,如果省略则按零补上
  • 标上行与列可以定位数组中的元素位置

三维数组

评论