目录

  • 数组
  • 一维数组
    • 一维数组的创建和初始化
      • 一维数组的定义
      • 一维数组的初始化
        • 完全初始化
        • 不完全初始化
    • 一维数组的使用
      • 一维数组的使用代码示例
    • 一维数组在内存中的存储
      • 代码示例
  • 二维数组
    • 二维数组的创建和初始化
      • 二维数组的定义
      • 二维数组的初始化
    • 二维数组的使用
      • 代码示例
    • 二维数组在内存中的存储
      • 代码示例

数组

数组(Array)是在内存中连续存储的具有相同类型的一组数据的集合。
数组是一组相同类型元素的集合。这些元素在内存中依次连续挨着存放。

数组中,若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标

注意:
1,数组的下标从0开始(包括0)连续计算。
2,数组中的各元素的存储是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起。
3,数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a[0]表示名字为a的数组中的第一个元素,a[1]代表数组a的第二个元素,以此类推。
4,数组中的所有元素都具有相同类型。数组中的元素存储在一个连续性的内存块中,并通过索引来访问。最低的地址对应第一个元素,最高的地址对应最后一个元素。
5,数组元素并非只能是基本数据类型,还可以是结构、枚举或类。

一维数组

一维数组的创建和初始化

一维数组是最简单的数组,其逻辑结构是线性表。要使用一维数组,需经过定义、初始化和应用等过程。

一维数组的定义

在 C 中要声明一个数组,需要指定元素的类型和元素的数量,一维数组定义的语法规则为:
类型说明符 数组名[常量表达式];
例如:

 char arr1[3];//数组类型为char,数组名为arr1,数组中一共有3个元素。int arr2[5];double arr3[8];int arr4[3+7];

在上面的例子中,定义了一个数组名为arr1的char类型数组,该数组中可以容纳3个char类型的元素。
注意:数组的创建定义中,[ ]内要给一个常量(或者常量表达式)才可以,不能使用变量。

一维数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理的初始值(初始化)。

完全初始化

定义数组时给所有元素赋初值,这叫“完全初始化”。

 char arr1[3] = {'a','d','f'};int arr2[5] = {1, 2, 3, 4, 5};double arr3[2+3] = {1.0, 2.0, 3.0, 4.0, 5.0};char arr4[5] = "abcde";

注意:数组{ }中元素的个数不能大于数组声明时[ ]中常量的个数。如果定义的数组的长度比花括号中所提供的初值的个数少,也是语法错误,如int arr[2] = {1,2,3,4};,这样写是错误的。

如果定义数组时就给数组中所有元素赋初值,那么就可以不指定数组的长度,因为此时元素的个数已经确定了。编程时我们经常都会使用这种写法,因为方便,既不会出问题,也不用自己计算有几个元素,系统会自动分配空间。例如:

 int arr1[] = {1, 2, 3, 4, 5}; //相当于int arr1[5] = {1,2,3,4,5}; char arr2[] = "asdf";

这种写法和上面的写法一样,只不过数组[ ]中的元素个数等于后面{ }的元素个数,编程时自动给数组分配内存。
注意:省略[ ]中数字的写法只适用于在定义数组时就初始化时。如果定义数组时不初始化,那么省略数组长度就是语法错误。例如:int arr[];这种写法是错误的。编译器会提示你没有指定数组的长度。

不完全初始化

可以只给一部分元素赋值,这叫“不完全初始化”。
如果在定义和初始化数组时,[ ]中的数字大于数组{ }中的元素个数,则后面还没初始化的元素值默认全为0。比如:

int arr1[5] = {1, 2, 3};//只初始化了3个元素
int arr2[5] ={0};

上面的代码中arr1中的全部元素为:1,2,3,0,0;arr2中全部元素为:0,0,0,0,0。
定义的数组 a 有 5 个元素,但花括号内只提供两个初值,这表示只给前面两个元素 a[0]、a[1] 、a[2]初始化,而后面三个元素都没有被初始化。不完全初始化时,没有被初始化的元素自动为 0。
注意:“不完全初始化”和“完全不初始化”不一样。如果“完全不初始化”,即只定义“int a[5];”而不初始化,那么各个元素的值就不是0了,所有元素都是随机值,也称为:垃圾值。
不可以写成int a[5]={};。这是完全不初始化,如果大括号中什么都不写,那就是极其严重的语法错误。
大括号中最少要写一个数。比如int a[5]={0};,这是不完全初始化,这时就是给数组“清零”,此时数组中每个元素都是零。

一维数组的使用

我之前详细写了操作符的有关内容,感兴趣的朋友可以看这:C语言 操作符详解(一)C语言 操作符详解(二)。

对于数组的使用需要借助一个操作符:[ ],下标引用操作符。它其实就是数组访问的操作符。

数组必须先定义,然后使用。C 语言规定,只能逐个引用数组元素,而不能一次引用整个数组。数组的元素只能一个一个的输出。数组元素的表示形式为:
数组名[下标]

注意:定义数组时用到的 “数组名[常量表达式]” 和引用数组元素时用到的 “数组名[下标]” 是有区别的,定义数组时的常量表达式表示的是数组的长度,而引用数组元素时的下标表示的是元素的编号。
例如:

int num = 0;
int arr[5] = {1, 2};//定义长度为5的数组arr
num = arr[0];//引用数组arr中下标为0的元素a[0]赋值给num

一维数组的使用中,很多时候都需要借助for循环。

一维数组的使用代码示例

#include<stdio.h>
int main()
{int arr[10] = {0};//数组的不完全初始化//用sizeof操作符计算数组元素的个数int sz = sizeof(arr) / sizeof(arr[0]);//对数组的内容复赋值,数组是使用下标来访问的,下标从0开始。int i = 0;//index做下标for(i = 0; i < 10; i++){//将数组的10个元素全部赋值为0~9arr[i] = i;}//输出打印数组的全部内容for(i = 0; i < 10; i++){printf("%3d",arr[i]);}printf("\n");printf("数组中元素的个数为:%d\n",sz);return 0;
}

输出结果为:

  0  1  2  3  4  5  6  7  8  9
数组中元素的个数为:10
请按任意键继续. . .

注意:
1,数组是使用下标来访问的,数组的下标是从0开始的。
2,数组的使用要小心月结访问,比如:int arr[5];那么我们只能访问 arr[0]~arr[4] 之间的5个元素,其它元素都是非法的,如,arr[5]是非法的。
3,数组的大小可以通过单目操作符 sizeof 计算得到。

一维数组在内存中的存储

代码示例

#include<stdio.h>
int main()
{int arr[8] = {0};int i = 0;for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){printf("&arr[%d] = %p\n",i, &arr[i]);}return 0;
}

输出结果:

&arr[0] = 005EFC2C
&arr[1] = 005EFC30
&arr[2] = 005EFC34
&arr[3] = 005EFC38
&arr[4] = 005EFC3C
&arr[5] = 005EFC40
&arr[6] = 005EFC44
&arr[7] = 005EFC48
请按任意键继续. . .

观察输出结果,从中可以看出,随着数组下标的增长,元素的地址也在有规律的递增。
结论,数组在内存中是连续存放的。

二维数组

二维数组与一维数组相似,但是用法上要比一维数组复杂一点。后面的编程中,二维数组用得很少,因为二维数组的本质就是一维数组,只不过形式上是二维的。能用二维数组解决的问题用一维数组也能解决。

二维数组的创建和初始化

二维数组通常可以用来表示数学上的行列矩阵。即用二维数组的第一维表示行,第二维表示列;生活中凡是能抽象为对象及对象的若干同类型属性的问题,一般用二维数组来描述。

二维数组的定义

二维数组的语法规则为:
类型说明符 数组名[第一维大小][第二维大小];

其中,第一、二维的大小一般均为常量表达式。
二维数组中的元素个数 等于 第一维大小 乘 第二维大小
示例:

 char arr1[3][4];//表示3行4列的char类型数组arr1int arr2[5][6];double arr3[8][4];int arr4[3+7][2+4];

第一维大小 表示第一维下标的长度,第一维大小 表示第二维下标的长度。
从矩阵方面来理解的话,第一维大小 表示 行 下标的长度,第一维大小 表示 列 下标的长度。

注意:下面这些定义形式都是错误的:

 int arr5[][3];//错误。编译器无法确定所需空间int arr6[2][];//错误。缺少列下标,编译器无法确定所需空间

二维数组的初始化

 int arr1[2][3] = {1, 2, 3, 4, 5, 6};int arr2[3][4] = {{1, 2},{3, 4}};int arr3[][5] = {{1, 2, 3},{4, 5}};//表示这是一个2行5列的int型数组arr3char arr4[][5] = {"abct","dgf"};

1, 分行给二维数组赋初值

int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};//3行4列

2,将所有数据写在一个花括号内,按数组排列的顺序对各元素赋初值

int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};//表示3行4列的12个元素

3,只对部分元素赋初值

int arr[3][4] = {{1, 2, 3}, {5}, {9}};//不完全初始化,表示3行4列

它的作用是对第一行的前两个元素赋值、第二行和第三行的第一个元素赋值。其余元素自动为 0。这个二维数组初始化后数组各元素为:

          1  2  3  05  0  0  09  0  0  0

4, 如果在定义数组时就对全部元素赋初值,即完全初始化,则第一维的长度可以不指定,但第二维的长度不能省。

int arr[][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

等价于:

int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

系统会根据数据总数和第二维的长度算出第一维的长度。但这种省略的写法几乎不用,因为可读性差。
但是如果 只指定第一维的长度,不指定第二维的长度, 这样会发生错误,二维数组不允许这样的初始化方式。

5,二维数组“清零”,里面每一个元素都是零

 int a[3][4]={0};

二维数组的使用

二维数组的使用也是通过下标的方式。一维数组的使用中,“数组的元素只能一个一个输出”,二维数组也不例外。在一维数组中是用一个 for 循环进行输出,而二维数组元素的输出要使用两个 for 循环嵌套。

代码示例

#include<stdio.h>
int main()
{int arr[3][4] = {{1,2,3},4,5,6,7,8,9,10,11};int i = 0;//i为行循环变量,用来控制行int j = 0;//j为列循环变量,用来控制列for (i = 0; i < 3; i ++){for(j = 0; j < 4; j ++){printf("  %2d",arr[i][j]);}printf("\n");//每一行结束时,用来换行}return 0;
}

输出结果:

   1   2   3   04   5   6   78   9  10  11
请按任意键继续. . .

二维数组的打印输出中,有两个for循环,第一个for循环用来控制行,第二个for循环用来控制列。

二维数组在内存中的存储

二维数组在内存中是连续存储的,二维数组的底层是按一维数组存的。

代码示例

#include<stdio.h>
int main()
{int arr[3][4];int i,j;for (i = 0; i < 3; i ++){for (j = 0; j < 4; j ++){printf("arr[%d][%d] = %p  ",i, j, &arr[i][j]);}printf("\n");}return 0;
}

输出结果:

arr[0][0] = 007DF7EC  arr[0][1] = 007DF7F0  arr[0][2] = 007DF7F4  arr[0][3] = 007DF7F8
arr[1][0] = 007DF7FC  arr[1][1] = 007DF800  arr[1][2] = 007DF804  arr[1][3] = 007DF808
arr[2][0] = 007DF80C  arr[2][1] = 007DF810  arr[2][2] = 007DF814  arr[2][3] = 007DF818
请按任意键继续. . .

从代码的输出结果和下图中我们可以看出,二维数组的底层存储是按一维数组连续存储的。

C语言 一维数组、二维数组的创初始化、使用和存储相关推荐

  1. c 语言 二维数组地址,C/C++ 关于一维或二维数组首地址表示含义

    C/C++ 关于一维或二维数组首地址表示含义 发布时间:2020-06-26 10:35:21 来源:51CTO 阅读:210 作者:sonissa 这是一个经常会忘却的知识点,最近也一直在吃这方面的 ...

  2. C语言指针和二维数组

    二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有"缝隙".以下面的二维数组 a 为例: int a[3][4] = { {0, 1, 2, ...

  3. c语言字符串二维数组的动态分配应,C语言中动态分配二维数组复习过程.doc

    C语言中动态分配二维数组复习过程.doc C语言中动态分配二维数组在C中动态分配内存的,对于单个变量,字符串,一维数组等,都是很容易的.C中动态分配二维数组的方法,很少有C语言书中描述,我查找了有的C ...

  4. 二维数组在c语言中的作用,C语言中的二维数组

    1.二维数组的定义和引用 一. 数据类型 数组名[常量表达式1][常量表达式2]; (1)假如有个二维数组array[n][m],则行下标的取值范围0~n-1 (2)列下标的取值范围0~m-1 (3) ...

  5. c语言字符二维数组传参,C语言函数传递二维数组

    C语言如果给函数传递二维数组作为参数 问题的产生 先看一个传递二维数组的例子: #include void foo(int a[][], int m, int n) { int i = 1; int ...

  6. c语言动态生成二维数组,C语言 动态创建二维数组

    /*C语言 如何动态创建二维数组 转化为一维数组申请数组,创建和释放都比较简单 */ #include #include #include #define RANK 10 #define COLUMN ...

  7. C语言数组——二维数组

    C语言目录 C/C++学习资源(百度云盘链接) 计算机二级资料(过级专用) C语言学习路线(从入门到实战) 编写C语言程序的7个步骤和编程机制 C语言基础-第一个C程序 C语言基础-简单程序分析 VS ...

  8. C# 指定格式的字符串截成一维数组(二维数组)的操作类

    指定格式的字符串截成一维数组(二维数组)的操作类 做项目时经常会遇到将"1,3,a,b,d"截成一维数组或将"1,a;2,b;3,c;4,d"截成二维数组.虽然 ...

  9. 【C 语言】二级指针内存模型 ( 指针数组 | 二维数组 | 自定义二级指针 | 将 一、二 模型数据拷贝到 三 模型中 并 排序 )

    文章目录 一.指针数组 和 二维数组 数据 拷贝到 自定义二级指针 中 1.函数形参 设计规则 2.三种内存模型 对应 函数形参 指针退化规则 二.完整代码示例 一.指针数组 和 二维数组 数据 拷贝 ...

  10. (c语言)编程输出二维数组中元素的最大值,要求用指针实现。

    (c语言)编程输出二维数组中元素的最大值,要求用指针实现. #include<stdio.h> #include<stdlib.h> #define N 6 //行数 #def ...

最新文章

  1. java openfile busy_android java.io.IOException: open failed: EBUSY (Device or resource busy)
  2. 新手探索NLP(九)——文本摘要
  3. ACM入门之【前缀和】
  4. 2014年3月26日,今天的收获_______每天都能觉得进步,这是多么好的一件事
  5. flock lock ex php,php – flock有可能用LOCK_EX返回false吗?
  6. 聊天室程序python_Python聊天室程序(基础版)
  7. 老李分享知识:性能测试之TPS和吞吐率
  8. 2011最赚钱的行业和公司排行榜(verified 版本)
  9. 如何将PDF转换成可以直接编辑的CAD图纸
  10. 英特尔 英特尔 显示器音频_每日新闻摘要:ZombieLoad是对英特尔PC的最新威胁
  11. 如何按照滑环的原理来自制简易导电滑环
  12. 怎么样振作起来-How to Cheer Up
  13. python 爬取拉钩网数据
  14. 抖音seo源码,抖音seo矩阵系统源码搭建技术+二开开源代码
  15. TBR架构的一些理解
  16. 在Linux系统(CentOS 8.2)腾讯云服务器下部署原神云崽机器人(Yunzai-Bot)【保姆入门级】
  17. 馈线自动化的主要采用计算机技术,配电及馈线自动化技术探讨
  18. 计算机教学得意之处,继续教育网反思周记
  19. 基于javaweb+jsp的生病慢病报销管理信息系统(java+MySQL+Jdbc+Servlet+Jsp)
  20. 实现epub中链接脚注加1的操作

热门文章

  1. 死锁、活锁、饥饿定位死锁解决死锁
  2. 智慧校园有什么亮点?
  3. android保存连接地址到桌面快捷方式,Android创建桌面快捷方式两种方法
  4. 视频编辑软件会声会影2018中文版
  5. UCI-ICS32Python第一周笔记
  6. Python 大漠免注册
  7. c++ set 的一些使用
  8. stemadb反扒机制分析
  9. Java单例模式的5种实现方法
  10. 数据结构基本框架思维导图