数组可以说是目前为止讲到的第一个真正意义上存储数据的结构。虽然前面学习的变量也能存储数据,但变量所能存储的数据很有限。不仅如此,数组和指针(后续会讲)是相辅相成的,学习数组可以为学习指针打下基础。

那么到底什么是数组呢?顾名思义数组就是很多数的组合!那么这些数有没有什么要求呢,是不是不管什么数组合在一起都是数组呢?同一数组中存储的数必须满足以下两个条件:

这些数的类型必须相同。

这些数在内存中必须是连续存储的。

换句话说,数组是在内存中连续存储的具有相同类型的一组数据的集合。

一维数组

一维数组的定义方式如下:

类型说明符 数组名[常量表达式];

例如:

int a[5];

它表示定义了一个整型数组,数组名为 a,定义的数组称为数组 a。数组名 a 除了表示该数组之外,还表示该数组的首地址(关于地址现在先不讨论,稍后讲指针的时候再说)。

此时数组 a 中有 5 个元素,每个元素都是 int 型变量,而且它们在内存中的地址是连续分配的。也就是说,int 型变量占 4 字节的内存空间,那么 5 个int型变量就占 20 字节的内存空间,而且它们的地址是连续分配的。

这里的元素就是变量的意思,数组中习惯上称为元素。

在定义数组时,需要指定数组中元素的个数。方括号中的常量表达式就是用来指定元素的个数。数组中元素的个数又称数组的长度。

数组中既然有多个元素,那么如何区分这些元素呢?方法是通过给每个元素进行编号。数组元素的编号又叫下标。

数组中的下标是从 0 开始的(而不是 1)。那么,如何通过下标表示每个数组元素的呢?通过“数组名[下标]”的方式。例如“int a[5];”表示定义了有 5 个元素的数组 a,这 5 个元素分别为 a[0]、a[1]、a[2]、a[3]、a[4]。其中 a[0]、a[1]、a[2]、a[3]、a[4] 分别表示这 5 个元素的变量名。

为什么下标是从 0 开始而不是从 1 开始呢?试想,如果从 1 开始,那么数组的第 5 个元素就是 a[5],而定义数组时是 int a[5],两个都是 a[5] 就容易产生混淆。而下标从 0 开始就不存在这个问题了!所以定义一个数组 a[n],那么这个数组中元素最大的下标是 n–1;而元素 a[i] 表示数组 a 中第 i+1 个元素。

另外,方括号中的常量表达式可以是“数字常量表达式”,也可以是“符号常量表达式”。但不管是什么表达式,必须是常量,绝对不能是变量。通常情况下 C 语言不允许对数组的长度进行动态定义,换句话说,数组的大小不依赖程序运行过程中变量的值。非通常的情况为动态内存分配,此种情况下数组的长度就可以动态定义,这个稍后会讲。

一维数组初始化

一维数组的初始化可以使用以下方法实现:

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

int a[5] = {1, 2, 3, 4, 5};

通过将数组元素的初值依次放在一对花括号中,如此初始化之后,a[0]=1;a[1]=2;a[2]=3;a[3]=4;a[4]=5,即从左到右依次赋给每个元素。需要注意的是,初始化时各元素间是用逗号隔开的,不是用分号。

2) 可以只给一部分元素赋值,这叫“不完全初始化”。例如:

int a[5] = {1, 2};

定义的数组 a 有 5 个元素,但花括号内只提供两个初值,这表示只给前面两个元素 a[0]、a[1] 初始化,而后面三个元素都没有被初始化。不完全初始化时,没有被初始化的元素自动为 0。

需要注意的是,“不完全初始化”和“完全不初始化”不一样。如果“完全不初始化”,即只定义“int a[5];”而不初始化,那么各个元素的值就不是0了,所有元素都是垃圾值。

你也不能写成“int a[5]={};”。如果大括号中什么都不写,那就是极其严重的语法错误。大括号中最少要写一个数。比如“int a[5]={0};”,这时就是给数组“清零”,此时数组中每个元素都是零。此外,如果定义的数组的长度比花括号中所提供的初值的个数少,也是语法错误,如“a[2]={1,2,3,4,5};”。

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

int a[5] = {1, 2, 3, 4, 5};

可以写成:

int a[] = {1, 2, 3, 4, 5};

第二种写法的花括号中有 5 个数,所以系统会自动定义数组 a 的长度为 5。但是要注意,只有在定义数组时就初始化才可以这样写。如果定义数组时不初始化,那么省略数组长度就是语法错误。比如:

int a[];

那么编译时就会提示错误,编译器会提示你没有指定数组的长度。

下面给大家写一个简单的程序:

# include

int main(void)

{

int a[5] = {1, 2, 3, 4, 5};

int i;

for (i=0; i<5; ++i)

{

printf("%d\n", a[i]);

}

return 0;

}

输出结果是:

1

2

3

4

5

a 表示数组的名字,[5] 表示这个数组有 5 个元素,并分别用 a[0]、a[1]、a[2]、a[3]、a[4] 表示。并分别把花括号内的 1、2、3、4、5 赋给变量 a[0]、a[1]、a[2]、a[3]、a[4]。再次强调,下标从 0 开始,即从 a[0] 开始,而不是 a[1]。

也可以用 scanf 手动从键盘对数组进行初始化:

# include

int main(void)

{

int a[5] = {0}; //数组清零初始化

int i;

printf("请输入5个数:");

for (i=0; i<5; ++i)

{

scanf("%d", &a[i] );

}

for (i=0; i<5; ++i)

{

printf("%d\x20", a[i]);

}

printf("\n");

return 0;

}

输出结果是:

请输入5个数:1 2 3 4 5

1 2 3 4 5

同使用 scanf 给字符数组输入字符串时有所不同,输入数字时必须用 for 循环进行输入。而输入字符串时无须用循环,直接用 scanf 就可以了。

一维数组元素的引用

数组必须先定义,然后使用。C 语言规定,只能逐个引用数组元素,而不能一次引用整个数组。前面讲过,数组元素的表示形式为:

数组名[下标]

下标可以是整型常量或整型表达式,比如:

a[0] = a[5] + a[7] - a[2 * 3]

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

# include

int main(void)

{

int a[5] = {1, 2, 3, 4, 5}; //定义长度为5的数组a

int t;

t = a[3]; /*引用数组a中下标为3的元素a[3], 此时的3不代表数组的长度*/

printf("t = %d\n", t);

return 0;

}

输出结果是:

t = 4

“int a[5];”是定义了有 5 个元素的数组,这 5 个元素分别为 a[0]、a[1]、a[2]、a[3]、a[4]。而 t=a[3] 中的 a[3] 不是数组,只是其中的元素 a[3]。

因此,下面这个程序是错的:

# include

int main(void)

{

int a[5];

a[5] = {1, 2, 3, 4, 5};

return 0;

}

错误的原因是下面的 a[5] 不是数组。只有在定义的时候“a[常量]”表示的才是数组,此时方括号中的数字才表示数组长度。除此之外程序中任何地方看到“a[常量]”都不是数组,都只是数组的一个元素、一个变量,此时的“常量”表示的是元素的下标。

此外,当给元素单独赋值时不能加大括号,因为元素就是变量,即 a[5] 只是一个变量名。前面是怎么给变量赋值的现在就怎么给数组元素赋值,比如“a[5]=1;”。但是对于上面这个程序,这么写还是错误的。因为数组元素的下标是从 0 开始的,数组 a 的元素只有 a[0]~a[4],并没有 a[5] 这个元素。

c语言定义不定长数组初始化_数组的定义,初始化和使用,C语言数组详解相关推荐

  1. pythonbool类型数组生成_对numpy中布尔型数组的处理方法详解

    布尔数组的操作方式主要有两种,any用于查看数组中是否有True的值,而all则用于查看数组是否全都是True. 如果用于计算的时候,布尔量会被转换成1和0,True转换成1,False转换成0.通过 ...

  2. c语言将字符串按空格分割_如何在c++中实现字符串分割函数split详解

    前言 在学习c++中string相关基本用法的时候,发现了sstream的istringstream[1]可以将字符串类似于控制台的方式进行输入,而实质上这个行为等同于利用空格将一个字符串进行了分割, ...

  3. C语言 函数不定长参数 - C语言零基础入门教程

    目录 一.前言 二.函数不定长参数简介 1.va_start 2.va_arg 3.va_end 三.自定义不定长参数的函数 1.va_start/va_arg/va_end 案例一 2.va_sta ...

  4. C语言 函数不定长参数 ##__VA_ARGS__经典案例 - C语言零基础入门教程

    目录 一.##__VA_ARGS__简介 二.##__VA_ARGS__经典案例 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 一.## ...

  5. c语言定义不定长数组初始化_大学C语言期末考试练习题(带详解答案)(1)

    链接:https://pan.baidu.com/s/1d2Bb1vNTyBNpFGneIAicVw 提取码:y7uw 单项选择题 C语言的基本单位是 函数 1.(A  )是构成C语言程序的基本单位. ...

  6. c语言定义不定长数组初始化_C语言如何定义一组长度不定的数组?

    1 引言 定长数组包 在平时的开发中,缓冲区数据收发时,如果采用缓冲区定长包,假定大小是 1k,MAX_LENGTH 为 1024.结构体如下: // 定长缓冲区 //公众号:c语言与cpp编程 st ...

  7. c语言定义不定长数组初始化_C语言数组初始化的三种方式

    1.{0} 初始化 int arr1[3] = {0}; 使用 {0} 的方式最简洁,一般在定义的时候使用. 2.for 循环初始化 int arr2[3]; for (int i = 0; i &l ...

  8. 结构体 — C 语言中不定长结构体的使用

    1.结构体的定长表示 C语言中结构体的使用基本上都是定长的,就如以下这种: typedef struct {int a;int b;char c[100];double d; }STRU; 2.结构体 ...

  9. python数组类型_一文搞懂Python中的所有数组数据类型

    关于我 编程界的一名小小程序猿,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. 联系:hylinux1024@gmail ...

最新文章

  1. android 网络编程实现,Android开发使用HttpURLConnection进行网络编程详解【附源码下载】...
  2. Yesterday、Today、Tomorrow - 昨天、今天、明天
  3. [转]C++二进制完成加减乘除
  4. leetcode 1143. 最长公共子序列(dp)
  5. 有重复数字的组合问题_带数字重复的组合和问题
  6. wordpress插件-really-simple-ssl插件解决网站开启ssl证书后,图片不能正常显示
  7. 如何快速清除 Ubuntu 的系统缓存
  8. 安卓获取签名证书SHA1值
  9. 基于物联网平台开发手机混合 App
  10. if else 条件语句
  11. java调用打印机打印
  12. 修改IE浏览器点击右键“查看源文件”时的打开程序
  13. OSChina 周日乱弹 —— 十大人艰不拆的网络真相!
  14. 国内外优秀程序员的博客全在这了,请查收
  15. 第二次项目《吃货联盟Plus》
  16. ARP 地址解析协议 IP地址到MAC地址的转换过程
  17. 机器学习数据挖掘笔记_18(PGM练习二:贝叶斯网络在遗传图谱在的应用)
  18. Android实现直播的博文和流程(全过程,超详细/附源码)
  19. ASP.NET2.0数据操作之母板页和站点导航
  20. 使用Teleport Ultra批量克隆网站,使用Easy CHM合并生成chm文件

热门文章

  1. 【2021最新版】MongoDB面试题总结(95道题含答案解析)
  2. Aimersoft DVD Creator mac如何将iMovie项目导出和刻录到DVD
  3. Doxygen wizard
  4. RedditVideoMakerBot 视频制作机器人自动生成视频搭建教程
  5. 「大话设计模式 - 解读」5 大作业
  6. Unity-笔记-ILRuntime接入
  7. 从零到壹构建基于 Fabric-SDK-Go 的Web应用之三:完成Web应用
  8. java http proxy pptp_pptp搭建及问题点
  9. nginx代理mysql数据库 stream
  10. 关于最小割的求解方法