C 语言笔记:数组

一、数组的概念

数组是若干个相同类型的变量在内存中有序存储的集合。

  • 数组用于存储一组数据
  • 数组里面存储的数据类型必须是相同
  • 数组在内存中会开辟一块连续空间

int [a] 定义了一个整型的数组 a ,a 是数组的名字,数组中有 10 个元素,每个元素的类型都是 int 类型,而且在内存中连续存储。
这 10 个元素分别是 a[0], a[1], a[2], ..., a[9].

一个 int 型变量占 4 个字节,int a[10]\(4 \times 10 = 40\) 个字节。

二、数组的分类

(一)按元素类型分

  1. 字符数组:char s[10]
  2. 短整型的数组:short int a[10]
  3. 整型的数组:int a[8]
  4. 长整型的数组:long int a[9]
  5. 浮点型的数组(单、双):float a[12], double a[10]
  6. 指针数组:char *a[10], int *a[10]
  7. 结构体数组:struct stu boy[10]

(二)按维数分

  1. 一维数组
    int a[30];
  2. 二维数组
    int a[2][30];有 2 行、30 列
    二维数组由多个一维数组构成
  3. 多维数组
    int a[4][2][10];
    三维数组由多个相同的二维数组构成

三、定义数组

(一)定义一维数组

格式:数据类型 数组名[元素个数];
例子:int a[10];

注意:数组元素的个数在定义的时候可以不写,但是如果不写,必须初始化(定义的时候赋值)。

#include <stdio.h>

int main()
{
    // 定义一个一维数组
    int a[10];
    // 通过 sizeof 关键字可以获取数组的大小
    printf("sizeof(a) = %d %d\n", sizeof(a), 10 * sizeof(int));

    // 定义数组的同时赋值(初始化)
    int b[] = {10, 20, 30};
    printf("sizeof(b) = %d\n", sizeof(b));

    return 0;
}

运行结果:

sizeof(a) = 40 40
sizeof(b) = 12

分别为 40 字节和 12 字节

(二)定义二维数组

格式:数据类型 数组名[行数][列数];
例子:int a[2][4];,定义一个名为 a 的二维数组,每一个元素都是 int 类型,2 行 4 列,共 \(2 \times 4 = 8\) 个元素。

注意:
(1)二维数组也是连续开辟空间。
(2)访问元素都是从 0 行和 0 列开始:a[0][0], a[0][1], a[0][2], a[0][3], a[1][0], a[1][1], a[1][2], a[1][3].
(3)二维数组的下标也可以省略,但是有条件。在初始化时,二维数组的行数可以省略,但列数不能省略

#include <stdio.h>

int main()
{
    // 定义一个二维数组
    int b[2][4];
    printf("sizeof(b) = %d %d\n", sizeof(b), 2 * 4 * sizeof(int));

    // int c[][];会报错
    // int c[][] = {1, 2, 3, 4, 5};会报错
    // int c[3][] = {1, 2, 3, 4, 5};会报错
    int c[][4] = {1, 2, 3, 4, 5};
    printf("sizeof(c) = %d\n", sizeof(c));

    int d[][4] = {{1, 2, 3, 4}, {5, 0, 0, 0}};
    printf("sizeof(d) = %zu\n", sizeof(d));

    return 0;
}

运行结果:

sizeof(b) = 32 32
sizeof(c) = 32
sizeof(d) = 32
  • 对于第一个数组 c[][4],由于没有提供足够的初始化数据,编译器会尽量填充,而缺失的部分会被补充为 0。这导致该数组实际上包含了两个一维数组,每个一维数组有4个元素。因此,sizeof(c) 的结果是 \(4 \times 4 \times 2 = 32\) 字节。

  • 对于第二个数组 d[][4],提供了完整的初始化数据,包含两个一维数组,每个一维数组有 4 个元素。因此,sizeof(d) 的结果同样是 \(4 \times 4 \times 2 = 32\) 字节。
    int c[][4] = {1, 2, 3, 4, 5};是一个 1 行 4 列的数组。

四、定义并初始化

开辟空间的同时给变量赋值。

(一)一维数组初始化

如果不初始化,将得到随机值的数组

#include <stdio.h>

int main()
{
    // 一维数组的初始化
    int a[4];//得到随机值
    printf("%d\n", a[0]);
    printf("%d\n", a[1]);
    printf("%d\n", a[2]);
    printf("%d\n", a[3]);
    return 0;
}

运行结果:

-1265888272
530
0
0
  1. 全部初始化
#include <stdio.h>

int main()
{
    // 全部初始化
    int a[4] = {523, 253, 46, 9};
    printf("%d\n", a[0]);
    printf("%d\n", a[1]);
    printf("%d\n", a[2]);
    printf("%d\n", a[3]);

    return 0;
}

运行结果:

523
253
46
9
  1. 部分初始化
#include <stdio.h>

int main()
{
    // 全部初始化
    int a[4] = {15, 6};
    printf("%d\n", a[0]);
    printf("%d\n", a[1]);
    printf("%d\n", a[2]);
    printf("%d\n", a[3]);

    return 0;
}

运行结果:

15
6
0
0

没有初始化的元素自动补 0 .

(二)二维数组初始化

如果不初始化,得到的都是随机值:

#include <stdio.h>

int main()
{
    // 二维数组初始化
    int a[2][3];// 得到随机值
    printf("%d\n", a[0][0]);
    printf("%d\n", a[0][1]);
    printf("%d\n", a[0][2]);
    printf("%d\n", a[1][0]);
    printf("%d\n", a[1][1]);
    printf("%d\n", a[1][2]);

    return 0;
}

运行结果:

0
0
93
0
-71298048
527
  1. 按行初始化
    (1) 全部初始化
#include <stdio.h>

int main()
{
    // 按行初始化
    // 全部初始化
    int a[2][3] = {{10, 20, 30}, {66, 77, 888}};
    printf("%d\n", a[0][0]);
    printf("%d\n", a[0][1]);
    printf("%d\n", a[0][2]);
    printf("%d\n", a[1][0]);
    printf("%d\n", a[1][1]);
    printf("%d\n", a[1][2]);

    return 0;
}

运行结果:

10
20
30
66
77
888

(2) 部分初始化:没有初始化的位置自动填 0

#include <stdio.h>

int main()
{
    // 按行初始化
    // 部分初始化
    int a[2][3] = {{10, 20}, {66}};
    printf("%d\n", a[0][0]);
    printf("%d\n", a[0][1]);
    printf("%d\n", a[0][2]);
    printf("%d\n", a[1][0]);
    printf("%d\n", a[1][1]);
    printf("%d\n", a[1][2]);

    return 0;
}

运行结果:

10
20
0
66
0
0
  1. 逐步初始化
    (1) 全部初始化
#include <stdio.h>

int main()
{
    // 逐个初始化
    // 全部初始化
    int a[2][3] = {1, 2, 3, 4, 5, 6};
    printf("%d\n", a[0][0]);
    printf("%d\n", a[0][1]);
    printf("%d\n", a[0][2]);
    printf("%d\n", a[1][0]);
    printf("%d\n", a[1][1]);
    printf("%d\n", a[1][2]);

    return 0;
}

运行结果

1
2
3
4
5
6

(2) 部分初始化:没有初始化的位置自动填 0

#include <stdio.h>

int main()
{
    // 逐个初始化
    // 全部初始化
    int a[2][3] = {1, 2, 3};
    printf("%d\n", a[0][0]);
    printf("%d\n", a[0][1]);
    printf("%d\n", a[0][2]);
    printf("%d\n", a[1][0]);
    printf("%d\n", a[1][1]);
    printf("%d\n", a[1][2]);

    return 0;
}

运行结果:

1
2
3
0
0
0

五、数组元素的引用方式

(一)一维数组的引用方法

数组名[下标];//下标表示元素在数组中的位置
注意:从 0 开始引用

int a[10];
a[2];

用 for 循环引用一维数组:

#include <stdio.h>

int main()
{
    // 一维数组的引用以及一维数组的遍历
    int a[6] = {111, 222, 333, 444, 555, 666};

    // 一维数组的遍历
    int i;
    for(i = 0; i < sizeof(a) / sizeof(int); i++)
    {
        printf("a[%d] = %d\n", i, a[i]);
    }
    return 0;
}
  • sizeof(a) 返回数组 a 所占空间;sizeof(int) 返回整型数组每个元素所占大小;sizeof(a) / sizeof(int) 返回数组 a 的元素个数。

运行结果:

a[0] = 111
a[1] = 222
a[2] = 333
a[3] = 444
a[4] = 555
a[5] = 666

(二)二维数组的引用方法

#include <stdio.h>

int main()
{
    // 二维数组的引用以及二维数组的遍历
    int b[3][4] = {1, 2, 3, 4,
                    5, 6, 7, 8,
                    9, 10, 11, 12};

    // 二维数组的遍历
    int m, n;
    // 外层循环控制行
    for (m = 0; m < 3; m++)
    {
        //内层循环控制列
        for (n = 0; n < 4; n++)
        {
            printf("%-4d", b[m][n]);
        }
        printf("\n");// 每行输出结束后换行
    }

    return 0;
}
  • %-4d表示输出宽度为 4 左对齐的整型。
    运行结果:
1   2   3   4   
5   6   7   8   
9   10  11  12  

六、字符数组的定义和初始化

定义下面 4 个字符数组:

char c1[] = {'c', ' ', 'p', 'r', 'o', 'g'};
char c2[] = "c prog";
char c3[][5] = {
    {'B', 'A', 'S', 'I', 'C'},
    {'d', 'B', 'A', 'S', 'E'}
                };
char c4[][6] = {"hello", "world"};

让我们分别分析这四个数组在内存中的存放情况:

  1. 对于 char c1[] = {'c', ' ', 'p', 'r', 'o', 'g'};
    c1[0] c1[1] c1[2] c1[3] c1[4] c1[5]
    'c' ' ' 'p' 'r' 'o' 'g'
  2. 对于 char c2[] = "c prog";
    c2[0] c2[1] c2[2] c2[3] c2[4] c2[5] c2[6]
    'c' ' ' 'p' 'r' 'o' 'g' '\0'

\0 是空字符

  1. 对于 char c3[][5]

    c3[0][0] c3[0][1] c3[0][2] c3[0][3] c3[0][4]
    'B' 'A' 'S' 'I' 'C'
    c3[1][0] c3[1][1] c3[1][2] c3[1][3] c3[1][4]
    'd' 'B' 'A' 'S' 'E'
  2. 对于 char c4[][6] = {"hello", "world"};

    c4[0][0] c4[0][1] c4[0][2] c4[0][3] c4[0][4] c4[0][5]
    'h' 'e' 'l' 'l' 'o' '\0'
    c4[1][0] c4[1][1] c4[1][2] c4[1][3] c4[1][4] c4[1][5]
    'w' 'o' 'r' 'l' 'd' '\0'

总结:每个字符占用一个字节,字符串以空字符 '\0' 结尾。对于字符数组,如果没有明确指定大小,编译器会根据初始化的元素个数确定数组大小。对于二维字符数组,第一维大小为数组元素个数,第二维大小为字符个数。

#include <stdio.h>

int main()
{
    // 定义一个字符数组,通过 scanf 函数输入字符串并输出结果
    // 通过赋值""这样的方式可以清除字符数组中的垃圾字符,让每个元素都是\0
    char ch[32] = "";

    // 数组名就是当前数组的首地址。所以 scanf 的第二个参数直接传数组名
    scanf("%s", ch);
    printf("ch = %s\n", ch);
    return 0;
}

在 Qt 中使用 scanf ,需要通过终端输入输出


回到『编辑』

posted @ 2024-02-03 21:01  茴香豆的茴  阅读(30)  评论(0编辑  收藏  举报