• 数组——C语言初阶


    一.一维数组:

    (1).一维数组的创建
    1. 概念:
      1. type_t arr_name [const_n];
      2. //type_t 是指数组的元素类型
      3. //arr_name 是数组的名字
      4. //const_n 是一个常量表达式,用来指定数组的大小

    2. 数组创建实例:
      1. #include
      2. int main()
      3. {
      4. //代码1
      5. int arr1[10];
      6. char arr2[10];
      7. float arr3[1];
      8. double arr4[20];
      9. //代码2
      10. //用宏定义的方式
      11. #define X 3
      12. int arr5[X];
      13. //代码3
      14. //错误使用
      15. //下面的代码只能支持在C99标准的编译器上编译
      16. int count = 10;
      17. int arr6[count];//这种数组是不能初始化的
      18. //在C99标准之前,数组的大小必须是常量或者常量表达式
      19. //在C99之后,数组的大小可以是变量,为了支持变长数组
      20. return 0;
      21. }

               注:在C99标准之前,数组的大小必须是常量或者常量表达式
                      在C99之后,数组的大小可以是变量,为了支持变长数组

    (2).数组的初始化:
    1. 概念:数组的初始化是指,在创建数组的同时给数组的一些内容一些合理的初始值(初始化)。
    2. 数组是具有相同类型的集合,数组的大小(即所占字节数)由元素个数乘以单个元素的大小。
    3. 数组只能够整体初始化,不能被整体赋值。只能使用循环从第一个逐个遍历赋值。
    4. 初始化时,数组的维度或元素个数可忽略 ,编译器会根据花括号中元素个数初始化数组元素的个数。
    5. 当花括号中用于初始化值的个数不足数组元素大小时,数组剩下的元素依次用0初始化。
      字符型数组在计算机内部用的时对应的ascii码值进行存储的。
    6. 一般用”“引起的字符串,不用数组保存时,一般都被直接编译到字符常量区,并且不可被修改。
    (3).一维数组的使用:
    1. 实例;
      1. #include
      2. int main()
      3. {
      4. int arr[10] = { 0 };//数组的不完全初始化
      5. //计算数组的元素个数
      6. int sz = sizeof(arr) / sizeof(arr[0]);
      7. //对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
      8. int i = 0;//做下标,此时可以是变量
      9. for (i = 0; i < 10; i++)
      10. {
      11. arr[i] = i;
      12. }
      13. //输出数组的内容
      14. for (i = 0; i < 10; ++i)
      15. {
      16. printf("%d ", arr[i]);
      17. }
      18. return 0;
      19. }
    2. 注意:                                                                                                                                                sizeof()操作符用于取长度,以字节为单位。sizeof(数组名)即求的时整个数组的大小。sizeof(首元素)即求数组单个元素大小。                                                                                             用0下标,是因为数组至少存在一个有效元素,所以0下标永远存在。数组是使用下标来访问的,下标是从0开始。                                                                                                                  数组的大小可以通过计算得到。建议采用sizeof(arr)/sizeof(arr[0])这种方式。

    (4).一维数组在内存中的储存:
    1. 数组在内存中开辟是线性连续且递增的。
    2. 在c语言中,任何变量(基本变量,指针变量,结构体变量,数组变量)的空间都是整体开辟,但任何元素的起始地址一定是开辟字节当中最小的。


    二.二维数组:

    (1).二维数组的创建

    二维数组创建时,行数可以忽略不写。并且所有维度的数组其第一个方括号的内容可忽略。

    1. #include
    2. int main()
    3. {
    4. //数组创建
    5. int arr1[3][4];//[行数][列数]
    6. char arr2[4][5];
    7. double arr3[2][4];
    8. return 0;
    9. }
     (2).二维数组的初始化
    1. //数组初始化
    2. int arr[3][4] = {1,2,3,4};
    3. int arr[3][4] = {{1,2},{4,5}};
    4. int arr[][4] = {{2,3},{4,5}};


    注意:
    花括号中的一个花括号代表一个一维数组的初始化。当里面无花括号分组时,按照顺序从第一个开始逐个进行初始化。余下的未赋值的元素用0初始化。
     

    (3).二维数组的使用 
    1. 二维数组的使用也是通过下标的方式,用双重循环嵌套进行索引使用。
    2. 二维数组中数的查找:
      1. #include
      2. int main()
      3. {
      4. int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
      5. printf("%d", arr[1][2]);
      6. //二维数组中数下标是这样规定的
      7. //00 01 02
      8. //10 11 12
      9. //20 21 22
      10. //如此输出便是6
      11. return 0;
      12. }
    3. 二维数组中打印整个数组:
      1. #include
      2. int main()
      3. {
      4. int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
      5. int i = 0;
      6. for (i = 0; i < 3; i++)
      7. {
      8. int j = 0;
      9. for (j = 0; j < 4; j++)
      10. {
      11. printf("%d ", arr[i][j]);
      12. }
      13. printf("\n");
      14. }
      15. return 0;
    4. 二维数组中重新为数组赋值:
      1. #define _CRT_SECURE_NO_WARNINGS
      2. #include
      3. int main()
      4. {
      5. int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
      6. int i = 0;
      7. for (i = 0; i < 3; i++)
      8. {
      9. int j = 0;
      10. for (j = 0; j < 4; j++)
      11. {
      12. scanf("%d ", &arr[i][j]);
      13. }
      14. }
      15. for (i = 0; i < 3; i++)
      16. {
      17. int j = 0;
      18. for (j = 0; j < 4; j++)
      19. {
      20. printf("%d ", arr[i][j]);
      21. }
      22. printf("\n");
      23. }
      24. return 0;
      25. }

    (4).二维数组在内存中的储存
    1. 二维数组在内存的空间布局上,也是线性连续且递增的!!!
    2. 二维数组本质上也是一维数组,只不过内部元素放的是一维数组

    .

    三.数组越界:

    1. 数组的下标是有范围限制的。
    2. 数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
    3. C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,所以程序员写代码时,最好自己做越界的检查
    4. 二维数组的行和列也可能存在越界:


    四.数组作为函数参数:

    1. 调用函数传参数组时,减少函数传数组时的成本问题(时间和空间)。因为传参时,需要临时拷贝,如果数组过大,可能会浪费资源,严重的话可能栈溢出。
    2. 数组元素降维成指向数组内部元素类型指针
    3. 对指针加一,加上所指向的类型的大小。

    例题:往往我们在写代码的时候,会将数组作为参数传整个函数,比如我要实现一个冒泡排序函数,将一个整型数组排序。

    代码如下:

    1. #include
    2. //形参是数组的形式;
    3. void popo(int arr[], int n)
    4. //数组名本质上是数组首元素的地址,地址是应该使用指针来接收
    5. //所以arr[]看似是数组,本质上是指针变量
    6. {
    7. //趟数
    8. int i = 0;
    9. for (i = 0; i < n - 1; i++)
    10. {
    11. //一趟冒泡排序
    12. int j = 0;
    13. for (j = 0; j < n - 1 - i; j++)
    14. {
    15. if (arr[j] > arr[j + 1])
    16. {
    17. //交换
    18. int x = arr[j];
    19. arr[j] = arr[j + 1];
    20. arr[j + 1] = x;
    21. }
    22. }
    23. }
    24. }
    25. int main()
    26. {
    27. int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
    28. int n = sizeof(arr) / sizeof(arr[0]);
    29. popo(arr,n);
    30. int i = 0;
    31. for (i = 0; i < n ; i++)
    32. {
    33. printf("%d ", arr[i]);
    34. }
    35. return 0;
    36. }

    总结:

    1. 形参格式,例如int arr[ ]或者int *arr,两者等价
    2. 形参元素个数可被忽略,并且建议忽略(有可能改变了实参的大小,这样比较方便)。或者也可以填写比实参元素个数大的值。
    3. sizeof()求数组元素个数时,尽量在数组定义时求。因为传参后数组会降维成指针。

    五.数组名:

    (1).一维数组数组名:

    数组名确实能表示首元素的地址,但是有两个例外:

    1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
    2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址

    (2).二维数组数组名:

    二维数组的数组名也表示数组首元素的地址(这里的首元素是指第一行元素地址)

  • 相关阅读:
    【毕业设计】酒店评价情感倾向分析系统 - python 深度学习
    python笔记 -- 面向对象
    没学好Netty,明年拿什么和别人竞争?这份Netty实战送给你
    QT布局管理器【QVBoxLayout,QHBoxLayout,QGridLayout】
    黑马点评--优惠卷秒杀
    Java编程技巧:Excel导入、导出(支持EasyExcel和EasyPoi)
    2023-09-10 LeetCode每日一题(课程表 II)
    地下管线探测仪 光电缆路由探测仪 管线仪 定位仪 探测0-6米 操作简捷 高精度
    P2P 技术:点对点网络的兴起
    vue2和vue3的区别
  • 原文地址:https://blog.csdn.net/qsl_81/article/details/134384966