揭秘C语言:高效数据管理之数组

一、数组的概念

数组是一组相同类型元素的集合

那数组有什么要求呢?

  • 数组中至少要有一个数据。
  • 数组中的数类型必须相同。
  • 数组在内存中是连续存储的。

 那用数学的语言来描述就是:数组是在内存中连续存储的具有相同类型的一组数据的集合。

二、一维数组

2.1 一维数组的创建与初始化

2.1.1 数组的创建

一维数组定义方式如下:

type_t   arr_name   [const_n];
//type_t 是指数组的元素类型
//arr_name 是数组的名字
//const_n 是一个常量表达式,用来指定数组的大小

例如:

//代码1
int arr1[10];
char arr2[10];
float arr3[1];
//代码2
//用宏定义的方式
#define X 3
int arr5[X];
//代码3
//错误使用
int count = 10;
int arr6[count];//数组是否可以正常创建?

:数组创建, [] 中要给一个常量才可以,不能使用变量。可以直接用常量,或者使用宏定义

2.1.2 数组的初始化

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

1. 数组大小和数值个数相等,这种方式也被称为完全初始化。

例如:

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

2. 数组大小大于初始数,这种方式被称为不完全初始化。

例如:

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

 3. 不指定数组大小

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

:果进行初始化,可以不在[]声明有几个元素,数组会默认初始化几个元素,数组大小就是几个元素,但是不初始化就一定要声明有几个元素哦~,否则就会报错 

4. 字符数组的存储

需要注意的是,给字符数组初始化时如果指定大小,那么指定大小要比字符数多一个,因为在字符串中结束标志是'\0',它也需要占据一个存储位置。如果没有这个结束标志,虽然程序不会报错,但在使用的时候无法得知结束位置,会导致使用错误。

2.2 一维数组的使用

2.2.1 数组下标

c语言数组规定是有下标的,下标是从0开始的(而不是1),假设数组有n个元素,最后⼀个元素的下标是n-1,例如:int arr[10]={1,2,3,4,5,6,7,8,9,10}。

arr12345678910
下标0123456789

2.2.2 数组的打印

我们知道了数组下标的概念,那我们怎么进行访问数组,打印出来呢?

让我们参考如下代码:

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//循环输出
	}
	
	return 0;
}

打印结果为:1 2 3 4 5 6 7 8 9 10

2.2.3 数组的输入

输入和我们正常的差不多,只是吧变量换成了数组。

#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
    int i = 0;
    for(i=0; i<10; i++)
    {
        scanf("%d", &arr[i]);
    }

    for(i=0; i<10; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

2.3 一维数组在内存中的存储

既然有元素的存在,那数组中每个元素是如何存储的呢?

让我们参考以下代码:

#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
    int i = 0;
    for(i=0; i<10; i++)
    {
        printf("&arr[%d] = %p\n ", i, &arr[i]);
    }
    return 0;
}

输出结果如下:

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

2.4 sizeof的用法

在遍历数组的时候,我们经常想知道数组的元素个数,那c语言中要怎么得到呢?可以使⽤sizeof。

sizeof是c语言里面的一个关键字是可以计算类型或者变量⼤⼩的,其实 sizeof 也可以计算数组的大小。

例如:

#include <stido.h>
int main()
{
    int arr[10] = {0};
    printf("%d\n", sizeof(arr));
    return 0;
}

这⾥输出的结果是40,计算的是数组所占内存空间的总⼤⼩,单位是字节。

我们又知道数组中所有元素类型都是相同的,那我们只要知道一个元素的大小就能知道数组中有多少个元素。

#include <stido.h>
int main()
{
    int arr[10] = {0};
    printf("%d\n", sizeof(arr[0]));//计算⼀个元素的⼤⼩,单位是字节
    return 0;
}

 接下来就能计算出数组中元素的个数。

#include <stido.h>
int main()
{
    int arr[10] = {0};
    int sz = sizeof(arr)/sizeof(arr[0]);
    printf("%d\n", sz);
    return 0;
}

输出结果是10,代表着数组中有十个元素。

三、二维数组

3.1 二维数组的创建与初始化

3.1.1 数组的创建

  1. 类型说明符 数组名[ 常量表达式][ 常量表达式];
  2. 类比一维数组的定义,二维数组第一个常量表达式表示行,第二个常量表达式表示列。
  3. 二维数组创建时,行数可以忽略不写。并且所有维度的数组其第一个方括号的内容可忽略。
//数组创建
int arr[3][4];//[行数][列数]
char arr[][5];
double arr[2][4];

3.1.2 数组的初始化

//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};

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

例如:

int arr3[3][3] = { {1,2},{2,3} };//按照行初始化

存放形式如下: 

120
230
000

:在二维数组的初始化中只能省略行,不能省略列,因为二维数组在空间中是连续存放的,需要知道每一行的起始位置在哪。

3.2 二维数组的使用

二维数组的使用也是通过下标的方式,二维数组是有行和列的,只要锁定了行和列的坐标,用双重循环嵌套进行索引使用。

与一维数组同理,二维数组的下标也是从0开始的。

如下所示:

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

编译结果如下:

3.3 二维数组在内存中的存储

我们知道一维数组在内存中是连续存放的,那二维数组在内存中是怎么存放的呢?

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

结果如下:

 通过结果我们可以分析到,其实二维数组在内存中也是连续存储的。

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

四、变长数组

在C99标准之前,C语⾔在创建数组的时候,数组⼤⼩的指定只能使⽤常量、常量表达式,或者如果我们初始化数据的话,可以省略数组⼤⼩。 

例如:

int arr1[10];
char arr2[4];
int arr3[] = {1,2,3};

但是这样的语法限制,让我们创建数组就不够灵活,有时候数组⼤了浪费空间,有时候数组⼜⼩了不够⽤,所以在C99中给⼀个变⻓数组(variable-length array,简称VLA)的新特性,允许我们可以使⽤变量指定数组⼤⼩。 

例如:

int n = a+b;
int arr[n];
可惜的是在vs2022编译器上不支持这种写法,会发生报错,也就没法给大家演示结果了。
  • 29
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值