C语言系列之数组

一、数组的概念

定义:数组是一组相同类型元素的集合。
①数组中存放的是1个或多个数据,但数组元素的个数不能为0。
②数组中存放的多个数据,类型是相同的。
数组分为一维数组和多维数组,多维数组一般比较多见的是二维数组。

二、一维数组的创建和初始化

2.1数组创建

语法:

type arr_name[常量值];
//type指定的是数组中存放数据的类型

type:指定的是数组中存放数据的类型,可以是:char、short、int、float 等,也可以⾃定义的类型
arr_name:指的是数组名的名字,这个名字根据实际情况,起的有意义就⾏。
[ ]:中的常量值是⽤来指定数组的⼤⼩的,这个数组的⼤⼩是根据实际的需求指定就⾏。

例:

int n[20];

2.2数组的初始化

通常我们会在创建数组的同时给数组赋一些初始值,这种就称之为数组的初始化。
例:

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

初始化有以下一些类型:
完全初始化,不完全初始化

# include <stdio.h>
int main()
{
int arr[5] = {1,2,3,4,5};//完全初始化
int arr2[100] = {1,2,3,4,5};//不完全初始化——剩下没有初始化的默认给的是0
int arr3[3] = {1,2,3,4];//错误的初始化
return 0;
}

2.3数组的类型

数组也是有类型的,数组算一种自定义类型,去掉数组名留下的就是数组的类型。
例:

int main()
{
 int arr[10];//类型是:int [10]
 int arr1[24];//类型是:int [24]
 char ch[8];//类型是:char [8]
return 0;
}

三、一维数组的使用

3.1数组下标

C语⾔规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下
标就相当于数组元素的编号,如下:

int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
数组12345678910
对应下标0123456789

C语言中数组的访问提供了一个操作符[ ],这个操作符叫:下标引用操作符。
操作如此:访问下标为5的元素:arr [5]。

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

3.2数组元素的打印

我们如何来打印数组呢?
我们可以使⽤for循环产⽣0~9的下标,接下来使⽤下标访问来打印数组。
代码如下:

#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++)//使⽤for循环产⽣0~9的下标
{
printf("%d ", arr[i]);//使⽤下标访问来打印数组
}
return 0;
}

3.3数组的输入

了解了数组的基本内容接下来让我们来给数组自己想要的数据并输出。
代码如下:

#include <stdio.h>
int main()
{
int arr[10] = {0};
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;
}

四、一维数组在内存中的存储

如果我们想要更深入的了解数组,那么我们就要了解一下一维数组在内存中的存储。
先依次打印数组的地址:

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

在这里插入图片描述
分析:数组随着下标的增⻓,地址是由⼩到⼤变化的,并且我们发现每两个相邻的元素之间相差4(因为⼀个整型是4个字节)。
由上述的代码及其运行结果可以得出结论:一维数组在内存中应该是连续存放的。
就如下面连续存放:

数组12345678910
对应下标0123456789

五、sizeof计算数组元素个数

在遍历数组是,我们需要知道数组元素的个数,那么这时候C语言就提供了可以计算类型或者变量⼤⼩的:sizeof。
注:sizeof 是C语言中的一个关键字,是可以计算类型或者变量大小的,其实sizeof 也可以计算数组的大小。
strlen —— 求字符串长度,只能针对字符串。
使用实例:
计算数组所占内存空间的总大小:

#include <stdio.h>
 int main()
 {
 int arr[10] = {0};
 printf("%d\n", sizeof(arr));//40,计算的是数组所占内存空间的总⼤⼩,单位是字节。
 //sizeof(数组名)——计算的是整个数组,单位是字节。
 return 0;
 }

计算数组中一个元素的大小:

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

计算出数组的元素个数:

#include <stdio.h>
 int main()
 {
 int arr[10] = {0};
 int sz = sizeof(arr)/sizeof(arr[0]);//计算整个数组元素的个数。
 printf("%d\n", sz);//10
 return 0;
 }

六、二维数组的创建,初始化和输入输出

6.1二维数组的概念

如果我们把⼀维数组做为数组的元素,这时候就是⼆维数组,⼆维数组作为数组元素的数组被称为三维数组,⼆维数组以上的数组统称为多维数组。
如下图所示:
在这里插入图片描述

6.2二维数组的创建

明白了二维数组的概念那么我们怎么创建二维数组呢?
语法如下:

type arr_name[常量值1][常量值2];
//int arr[3][5];
//double poe[5][7];

这里的[3] [5],前者表示数组有3行,后者表示数组每一行有5列。
int表⽰数组的每个元素是整型类型。
arr是数组名,可以根据⾃⼰的需要指定名字。
poe数组意思基本⼀致。

6.3二维数组的初始化

在创建变量或者数组的时候,给定⼀些初始值,被称为初始化。
二维数组和一维数组初始化基本相同,都是用大括号进行初始化的。

6.3.1不完全初始化

不完全初始化如下:

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

如下图所示:
在这里插入图片描述

6.3.2完全初始化

完全初始化如下:

int arr2[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

如下图所示:
在这里插入图片描述

6.3.3按照行初始化

按照行初始化如下:

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

如下图所示:
在这里插入图片描述

6.3.4初始化时,省略行但不能省略列

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

如下图所示:
在这里插入图片描述

6.4二维数组的下标

⼆维数组访问也是使⽤下标的形式的,⼆维数组是有⾏和列的,只要锁定了⾏和列就能唯⼀锁定
数组中的⼀个元素。C语⾔规定,⼆维数组的⾏是从0开始的,列也是从0开始的。
以下面代码举例:

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

下标如下图标所示:
在这里插入图片描述

6.5二维数组的输入输出

了解了二维数组的创建,我们来实现一个代码来输入一个3行5列的数据并且打印出来。

#include <stdio.h>
int main()
{
int arr[3][5] = {1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};
int i = 0;
//输入
for(i = 0;i < 3;i++)
{
int j = 0;
for(j = 0;j < 5;j++)
{
scanf("%d",&arr[i][j]);
}
}
//输出
for(i = 0;i < 3;i++)
{
int j = 0;
for(j = 0;j < 5;j++)
{
printf("%d",arr[i][j]);
}
printf("\n");
}
return 0;
}

结果如下:
在这里插入图片描述

七、二维数组在内存中的存储

打印数组所有元素的地址,代码如下:

#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;
 }

运行结果如图所示:
在这里插入图片描述
总结:每一行内部的每个元素都是相邻的,地址之间相差4个字节,跨⾏位置处的两个元素之间也是差4个字节,所以⼆维数组中的每个元素都是连续存放的。
如下图:
在这里插入图片描述
结论:二维数组在内存中也是连续存放的,一行存完,再存下一行。

八、C99中的变长数组

为了使数组的创建更加灵活,C99中给⼀个变⻓数组(variable-lengtharray,简称VLA)的新特性,允许我们可以使⽤变量指定数组⼤⼩。

int n = a+b;
int arr[n];

上述代码中数组arr 就是变⻓数组,因为它的⻓度取决于变量n的值,编译器没法事先确定,只有运⾏时才能知道n是多少。
变长数组的根本特征就是数组长度只能在运行时才能确定,所以变长数组不能初始化。

它的好处是程序员不必在开发时,随意为数组指定⼀个估计的⻓度,程序可以在运⾏时为数组分配精确的⻓度。
有⼀个⽐较迷惑的点,变⻓数组的意思是数组的⼤⼩是可以使用变量来指定的,在程序运⾏的时候,根据变量的大小来指定数组的元素个数而不是说数组的大小是可变的。数组的大小⼀旦确定就不能再变化了。

变长数组在VS版本迭代虽然支持C99大部分语法但变长数组的语法不支持无法演示,下面我们用底层的是gcc的小熊猫C++来演示:

#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩
int arr[n];
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}

结果图如下:
在这里插入图片描述
在这里插入图片描述
变长数组注意:
1、可以使用变量来指定数组大小。
2、并不是说数组的大小是变化的。

九、数组练习

9.1练习1:多个字符从两端移动,向中间汇聚

代码如下:

# include<stdio.h>
# include<windows.h>
# include<string.h>
# include<stdlib.h>
int main()
{
	char arr1[] = "welcome to bit!!!!!";
	char arr2[] = "*******************";
	int left = 0;
	int right = strlen(arr1) - 1;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s/n", arr2);
		Sleep(1000);//单位是毫秒
		system("cls");
		left++;
		right--;
	}
	printf("%s\n", arr2);
	return 0;
}

这个代码运行的结果是动态显示,需要看结果的可以自行复制观看结果。这里还用了windows系统的操作代码,可以查找C语言官方网站查看函数。

9.2练习2:二分查找(有序数组中查找具体指的数,是否存在)

代码如下:

# include<stdio.h>
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int k = 0;
scanf("%d",&k);//在arr数组中找K
int sz = sizeof(arr) / sizeof(arr[0]);//10
int left = 0;
int right = sz - 1;
while(left <= right)
{
int mid = (left + right)/2;
if(arr[mid] <k)
left = mid + 1;
else if(arr[mid]>k)
right = mid - 1;
else
{
printf("找到了,下标是:%d\n",mid);
break;
}
}
if(left > right)
printf("找不到\n");
return 0;
}

在VS上测试时,需要我们在前面第一行加上#define_CRT_SECURE_NO_WARNINGS 1即可。
测试结果如下:
在这里插入图片描述
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值