数组的认识和使用

一、数组的概念:

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

数组的定义:

1、数组中存放的是一个或多个数据,但是数组元素不能为0

2、数组中存放的多个数据类型是相同的

3、数组分为一维数组和多维数组,多维数组一般比较常见的是二维数组

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

数组的创建

一维数组的基本语法如下:

type arr_name[常量值]

type:数组中存放数据的类型,如int char float等,也可以是自定义类型

arr_name:一维数组的名字,有意义就行

存放在数组的值被称为数组元素,数组在创建的时候可以指定数组的大小值和数组元素的类型

数组的初始化:

int data1[10] = {0};
int data2[10] = {1,2,3};

一维数组的类型:

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

比如:

int arr1[10]; int [10]

char ch[5]; char [5]

就是数组的类型

三、一维数组的使用:

数组的下标:

数组的下标指的是数组元素的编号,下表是从0开始的且最后一个元素的下表是n-1

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

这个代码等价于:int arr[10] ={1,2,3,4,5,6,7,8,9,10}

数组的使用:

在c语言中数组访问提供了一个操作符[]。这个操作符叫做下标引用操作符

如果我们想要访问数组arr[7]和arr[9]里面的元素的话:

int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10}
printf("%d",arr[7]);
printf("%d",arr[9]);
return 0;
}

这样我们就会在屏幕上打印出数组arr中下标为7和9的元素了

数组元素的打印:

如果我们想要访问整个数组的内容,那我们只需要把数组的所有下标全部访问一遍

比如:

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

只需要用一个for循环来把数组的所有下标全部访问一遍,这种方法我们称为数组的遍历。

数组的输入:

其实数组的输入跟数组元素的打印差不多

int main()
{
int arr[10] = {0};//创建数组
for(int i = 0;i<10;i++)//对数组进行遍历
{
scanf("%d",&arr[i]);//对数组进行输入
}
return 0;
}

四、一维数组在程序中的储存:

数组在内存中是连续存放的

随着下标的增长,地址是由小(低)到大(高)的变化

五、sizeof计算元素的个数:

int main()
{
int arr[10] = {0};
printf("%zd\n",sizeof(arr));//计算的是数组总大小,比如说int是4字节的,
//一共有10个元素输出就是40字节
printf("%zd\n",sizeof(arr[0]));//单个数组元素的大小
printf("%zd\n",sizeof(arr)/sizeof(arr[0]));//计算的是数组中元素的个数
return 0;
}

这里提示一下sizeof和strlen的区别:

strlen 用于计算字符串的实际长度,sizeof 用于计算数据类型或者变量占用的字节数。

sizeof:这是一个操作符,并非函数。在编译阶段,它就能计算出数据类型或者变量所占用的内存字节数。

strlen:这是一个标准库函数,在运行时,它会计算以空字符 '\0' 结尾的字符串的实际长度。

六、二维数组的创建:

二维数组的概念:

前面学习的数组被称为一维数组,数组的元素都是内置类型的,如果我们把一维数组作为数组的元素,这时候就是二维数组,二维数组作为数组元素被称为三维数组,二维数组及以上的数组统称为多维数组

说白了就是由多个一维数组组合在一起。

二维数组的创建:

二维数组的语法如下:

type arr_name [常数值1][常数值2];

比如下列这两个二维数组:

int arr1[2][4];

char arr2[3][5];

就拿数组arr1[2][4]来说

type:数组的类型的定义是int类型

arr是数组名,可以根据自己的需要来指定名字

date数组意思基本一样

2表示数组有2行

4表示每一行有4个元素

七、二维数组的初始化:

在创建变量或者数组的时候,给定义些初始值,被称为初始化。

二维数组不完全初始化:

例如:int arr1[3][5] = {1,2};

int arr2[3][5] = {0};

这两个数组的初始化如下:

因为没有完全初始化的话,除了已经初始化的值意外,系统默认没有初始化的值为0

二维数组完全初始化:

当然有不完全初始化肯定也有完全初始化

例如:int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6 ,3,4,5,6,7};

按照行初始化:

例如:

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

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

例如:

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

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

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

八、二维数组的使用:

二维数组的下标:

其实二维数组的下标跟一维数组的下标一样都是从0开始,不管是行还是列下标都是从0开始。

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

为了更直观啊的感受

     0    1   2     3   4

0   1,2,3,4,5

1   2,3,4,5,6

2   3,4,5,6,7

二维数组的输入输出:

访问⼆维数组的单个元素我们知道了,那如何访问整个⼆维数组呢?其实我们只要能够按照⼀定的规律产⽣所有的⾏和列的数字就⾏;以上⼀段代码中的arr数组为例,⾏的选择范围是0~2,列的取值范围是0~4,所以我们可以借助循环实现⽣成所有的下标。

如下:

int main()
{
int arr[3][5] = {1,2,3,4,5 ,2,3,4,5,6 ,3,4,5,6,7};
for (int i = 0;i<3;i++)//产生行号
{
for (int j = 0;j < 5;j++)//产生列号
{
scanf("%d",&arr[i][j]);//输入数据
}
}//输出
for (int i = 0;i < 3;i++)
{
for (int j = 0;j < 5;j++)
{
printf("%d ",arr[i][j]);//输出数据
}
printf("\n");
}
return 0;
}

代码结果如下:

输出的值取决于用户输入的值

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

,每⼀⾏内部的每个元素都是相邻的,地址之间相差4个字节,跨⾏位置处的两个元素(如:arr[0][4]和arr[1][0])之间也是差4个字节,所以⼆维数组中的每个元素都是连续存放的。

十、C99中的变长数组:

在C99标准值前,c语言在创建数组的时候,数组大小的指定只能使用常量、常量表达式,或者如果我们初始化数据的话,可以省略数组的大小。

例如:

int arr1[10];

int arr2[3+5];

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

这样的语法限制,让我们创建数组就不够灵活,有时候数组大了浪费空间,有时候数组又小了不够用。

因此C99中给了一个变长数组的新特性,允许我们可以使用变量指定数组大小:

变长数组的大小在运行的时候确定,不能改变

一旦确定了大小后,它的大小是固定的,无法改变。

注意:vs编译器上不支持C99,可以使用gcc编译器

接下来让我们做一下数组的练习吧:

练习

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

编写代码,演示多个字符从两端移动,向中间汇聚

#include<windows.h>
#include<string.h>
#include<stdlib.h>
int main()
{
	do
	{
		char arr1[] = "meizhu I love you!!!";
		char arr2[] = "********************";
		int left = 0;
		int right = strlen(arr1) - 1;
		while (left <= right)
		{
			arr2[left] = arr1[left];
			arr2[right] = arr1[right];
			Sleep(500);//sleep是windows.h中的函数,单位是毫秒,可以让程序暂停一段时间
			system("cls");//清理屏幕上的信息,他是stdlib.h中的函数
			printf("%s\n", arr2);
			left++;
			right--;
		}
	} while (1);//死循环,也就是外面广告牌的工作原理。
	return 0;
}

结果如下:

实际上这个程序是不会停止的,是因为我按下了CTRL+C

这段程序中有两个陌生知识一个是Sleep函数,一个是system函数的清屏的用法

Sleep函数的用法是:

Sleep(常量);

调用Sleep函数需要#include这个头文件

system函数的用法是:

system("cls");

调用system函数需要#include这个头文件

练习二:二分查找

在一个升序的数组中查找指定的数字n,很容易想到的方法就是遍历数组,但是这种方法效率比较低。

什么是二分查找:就比如说猜一个数字100-200之间,很多人都会直接猜150,直接就是对半,大了就会猜100-150之间的数,这样会快捷很多。

当然,使用二分查找是有条件的:必须是有序的

int main()
{
int arr[20] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
int left = 0;//数组左边的下标
int k = 0;
scanf("%d", &k);//输入需要查找到数
int right = sizeof(arr) / sizeof(arr[0])-1;//先算数组元素的个数,再减一就是最后元素的下标了
int flag = 0;
while (left<=right)//当left>right的时候就已经超出数组的范围了,所以就需要退出循环
{
int mid = left + (right - left) / 2;//right - left:计算当前查找区间的长度
//(right - left) / 2:算出当前查找区间长度的一半。
//left + (right - left) / 2:在左边界 left 的基础上,加上区间长度的一半,从而得到中间位置的索引
if (arr[mid] < k)//如果比需要查找到数小,下标向右移一位
{
left = mid + 1;
}
else if (arr[mid] > k)//如果比需要查找到数大,下标向左移一位
{
right = mid - 1;
}
else
{
printf("找到了,下标是:%d\n", mid);
flag = 1;
break;
}
}
if (flag == 0)
{
printf("找不到\n");
}
return 0;
}

代码结果如下:

二分查找可以大大缩减查询的时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值