c印记(五):数组

目录

1、 什么是数组

所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。在c语言中数组属于构造数据类型。它的特点是:数组内部的元素都是同一种数据类型,可以是int,char,指针以及其他构造数据类型。

2、定义

定义格式:类型名 数组名[数组容量];
例如:

/** 一个班有30个人,需要定义一个整型数组来存放他们的学号 */
int number[30]; /** 其中 int:数据类型, number: 数组名,30: 数组容量 */

3、 初始化,访问以及遍历

a. 定义时初始化

格式:类型名 数组名[数组容量] = {数组元素/0};

解释:其前面部分和上面的定义格式是一样的,这里就不再累述,只是需要注意一点,‘数组容量’在这里是可选的,然后在’=’右边的花括号里面就是初始化数组的具体内容。
例如:

/**和初始化格式描述的完全一样的方式,其中int:类型,a:数组名,3:数组容量,{...}:初始化元素 */
int a[3] = {0,1,2}; 
int b[3] = {0};   /**将所有数组元素初始化为 0 */
/** 省略数组容量的定义和初始化方式,注意:这里如果像数组b一样初始化,就表示数组容量为 1 */
int c[]  = {0,1,2}; 

数组的内存布局为(假想地址,非真实地址):

int a[3];

地址元素
0x800a[0]
0x804a[1]
0x808a[2]

其布局是线性的,因为元素是int类型,所以每个元素暂用4个字节。


这里说的都是一维数组的情况,而c语言中还有多维数组,以二维数组为例(更高维数组就可以以此类推),其定义和初始化的格式为:

类型名 数组名[行数][列数];

类型名 数组名[行数][列数] = {{第一行元素}, {第二行元素},…{第n行元素}} 或者 {0};

注意:这里和一维数组有定义和初始化很相似,但是在二维数组定义并初始化时,行数可以省略,但列数却不能省略。其实在c语言中的多维数组在本质上仍然是一维数组(都是线性的),比如这个二维数组,就可以看做是由 ‘行数’个元素组成的一维数组,而这个元素又是一个有‘列数’个元素的一维数组,由于数组的特点是,所有元素都要是同一种数据类型,所以这个‘列数’必须要有,这样才能保证所有元素都是一样的,如果省略,那就会由{…}内填充的数据来决定,而数组在定义的时候,需要知道每个元素大小,以此来分配存储空间,如果省略了‘列数’,编译器就不知道其大小,就无法进行存储空间的分配。

例如:

/** 
 * 固定行数的定义和初始化方式
 * int: 类型名,
 * a:   数组名,
 * 2:   行数
 * 3:   列数
 * {{...},{...}}:初始化元素
 * 花括号里面, 1: a[0][0],第一行,第一列
 *           3: a[0][2],第一行,第三列 
 *           4: a[1][0],第二行,第一列
 */
int a[2][3] = {{1,2,3}, {4,5,6}};

/** 同上,只是将所有元素都初始化为 0 */
int b[2][3] = {0};

/** 省略‘行数’的定义和初始化方式 */
int c[][3] = {{1,2,3}, {4,5,6}};
b. 访问及遍历

c语言中的数组在底层其实都是使用指针实现的,而且c语言规定:数组名是一个指向数组元素类型的指针,它是指向该数组的第一个(即下标值为零的第0号)元素的指针常量。所以c语言的数组就有两种访问方式:
- 使用下标运算符 [] + 下标 进行访问,形如:数组名[下标]
- 使用取内容运算符 *,形如: *(数组名 + 下标)

注意:c语言数组的下标是从 0 开始的

例如:

int a[3] = {1,2,3}; /** 定义一个拥有三个元素的素组 */

/** 访问第二个元素 */
//使用下标运算符 + 下标的方式
int i = a[1];  //获取第二个元素的值
a[1] = 5;      //给第二个元素赋值

//使用取内容运算符 * 的方式
int j = *(a + 1); //获取第二个元素的值

*(a + 1) = 5;     //给第二个元素赋值

数组的遍历就比较简单了:

  • 可以简单是使用一个for循环,从下标 0 到 最大下标号(数组容量 - 1)的依次访问,形如:
void main()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    int i;
    for (i = 0; i < sizeof(a)/sizeof(a[0]); i++)
    {/** 
      * sizeof(a) 获取数组总共占用的字节数,sizeof(a[0])获取一个元素占用的字节数,
      * 二者相除就得到数组的元素数量 
      */
        printf("element number:%d, value:%d\n", i, a[i]);
    }
}
  • 使用函数递归的方式进行数组遍历,形如:
void array_foreach_recursive(int a[], int index)
{
    if (index == 0)
    {
        return;
    }
    else
    {
        int i = index - 1;

      array_foreach_recursive(a, i);
      printf("element number:%d, value:%d\n", i, a[i]);
    }
}

//在遍历的时候直接调用上面的函数,
void main()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,10};

    array_foreach_recursive(a, sizeof(a)/sizeof(a[0]));

    /**
     * 注意,这里没有在遍历函数内部获取数组a的元素数量,是因为在c语言中,
     * 数组作为函数参数的时候,会自动退化为指针,也就是说,在
     * array_foreach_recursive函数中使用sizeof(a)得到的不是数组占用的字节数,而是得到
     * 指针占用的字节数,在32bit的系统上是 4 字节,在64bit的系统上是8字节。
     */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值