深入浅出数组
目录
- 1.数组的概念
- 2.一维数组的创建和初始化
- 2.1 数组创建
- 2.2 数组的初始化
- 2.3 数组的类型
- 3.一维数组的使用
- 3.1 数组下标
- 3.2 数组元素的打印
- 3.3 数组的输入
- 4.一维数组在内存中的存储
- 5.sizeof 计算数组元素的大小
- 6.二维数组的创建
- 6.1 二维数组的概念
- 6.2 二维数组的创建
- 7. 二维数组的初始化
- 7.1 不完全初始化
- 7.2 完全初始化
- 7.3 按照行初始化
- 7.4 初始化时可以省略行,不能省略列
- 8.二维数组的使用
- 8.1 二维数组的下标
- 8.2 二维数组的输入和输出
- 9.二维数组在内存中的存储
- 10.C99中的变长数组
- 11. 数组练习
- 11.1 **练习1:多个字符从两端移动,向中间汇聚**
- 11.1.1 讲解算法原理
- 11.1.2 代码实现
- 11.2 二分查找
- 11.2.1 讲解算法原理
- 11.2.2 代码演示
1.数组的概念
数组是一组相同元素的集合
- 数组中存放的是一个或者多个数据 , 但是数组的元素不能是0。
- 数组中存放的多个数据类型是相同的
2.一维数组的创建和初始化
2.1 数组创建
一维数组的创建的基本语法如下:
type arr_name[常量值];存放在数组中的值叫做数组的元素,数组在创建的时候可以指定数组的大小和数组元素的类型。
type指定的是数组中存放数据的类型,可以是:char , short , long long , int等,也可以是自定义类型。arr_name指定的是数组的名字,起名字尽量做到见名知其意。[]中的常量值是用来指定数组的大小的。
charch[10];intarr[10];doublescore[10];2.2 数组的初始化
数组的初始化一般使用大括号,数组如果进行了初始化,数组的大小一般可以忽略的。
//完全初始化intarr[5]={1,2,3,4,5};//不完全初始化intarr1[5]={1};//第一个元素初始化为1,剩余4个元素默认初始化为0//错误的初始化 - 初始化太多intarr2[5]={1,2,3,4,5,6};2.3 数组的类型
数组算是一种自定义类型,去掉数组名留下的就是数组的类型
intarr[10];charch[5];doublea[6];- 数组
arr的类型就是int [10]; - 数组
ch的类型就是char [5]; - 数组
a的类型就是double [6];
3.一维数组的使用
3.1 数组下标
数组的下标如下:
intarr[10]={1,2,3,4,5,67,8,9};//下标 0 1 2 3 4 5 6 7 8数组元素对应的下标就为数组元素对应位置 - 1 ,下标就相当于数组元素的编号。
在C语言中对数组的访问提供了一个操作符[],这个操作符叫做:下标引用操作符。
#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};//如果我们想要访问下标为3的元素,就可以这样:printf("%d ",arr[3]);//4return0;}3.2 数组元素的打印
数组元素的打印只需要产生数组元素对应的下标,这样就可以使用for循环来访问数组元素的下标。
#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};for(inti=0;i<10;i++)printf("%d ",arr[i]);return0;}3.3 数组的输入
数组元素的输入如下:
4.一维数组在内存中的存储
从图中可以得到结论:
- 数组随着下标的增长,地址是由小到大变化的,每个相邻的元素之间相差4(因为一个整型4个字节)
- 数组在内存中是连续存放的
5.sizeof 计算数组元素的大小
如果以后想计算数组的大小,代码如下:
intsz=sizeof(arr)/sizeof(arr[0]);6.二维数组的创建
6.1 二维数组的概念
一维数组的元素都是内置类型的,如果我们把一维数组看作数组的元素,这时候就是二维数组。
6.2 二维数组的创建
如何定义二维数组,语法如下:
type arr_name[常量值1][常量值2];eg:intarr[3][5];解释上述代码的信息
- 3 表示数组有三行
- 5 表示数组又五列
- int 表示数组的每个元素是整型类型
- arr 是数组名
7. 二维数组的初始化
7.1 不完全初始化
intarr[3][5]={1,2};7.2 完全初始化
intarr3[3][5]={1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};7.3 按照行初始化
intarr4[3][5]={{1,2},{3,4},{5,6}};7.4 初始化时可以省略行,不能省略列
intarr1[][5]={1,2,3}intarr2[][5]={1,2,3,4,5,6}intarr3[][5]={{1,2},{4,5},{5,6}};8.二维数组的使用
8.1 二维数组的下标
C语言规定,二维数组的行是从0开始的,列也是从0开始的
intarr[3][5]={1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};8.2 二维数组的输入和输出
访问二维数组跟访问一维数组一样,都要使用for循环来进行遍历
9.二维数组在内存中的存储
通过上述图片,每一行数组元素内部是相邻的,地址相差4个字节,跨行元素之间也相差4个字节,说明二维数组中的每个元素都是连续存放的。
10.C99中的变长数组
C99中给⼀个变⻓数组(variable-length array,简称 VLA)的新特性,允许我们可以使用变量指定数组⼤⼩。
intmain(){intn;scanf("%d",&n);intarr[n];}上⾯⽰例中,数组arr就是变⻓数组,它的⻓度取决于变量 n 的值,编译器没法事先确定,只有运⾏时才能知道 n 是多少。变长数组的根本特征,就是数组长度只有运行时才能确定,所以变长数组不能初始化。
11. 数组练习
11.1练习1:多个字符从两端移动,向中间汇聚
11.1.1 讲解算法原理
//"welcome to bit!!!!!!"//"w##################!"//"we################!!"//"wel##############!!!"//"welo############!!!!"- 我们需要两个字符数组
char arr1[] = "welcome to bit!!!!!!" , char arr2[] = "###########" - 创建变量
left与right,指向数组的首位与末尾 - 运用while循环,循环结束的条件是left > right
11.1.2 代码实现
#include<stdio.h>#include<string.h>#include<windows.h>intmain(){chararr1[]="welcome to bit!!!!!!";chararr2[]="####################";size_tleft=0;size_tright=strlen(arr1)-1;//是用strlen函数要包含头文件<string.h>while(left<=right){arr2[left]=arr1[left];arr2[right]=arr1[right];printf("%s\n",arr2);//休眠1秒//单位是毫秒Sleep(1000);//使用Sleep库函数包含头文件<windows.h>left++;right--;}return0;}11.2 二分查找
二分查找,也叫折半查找
题⽬:给定⼀个升序的整型数组,在这个数组中查找到指定的值n,找到了就打印n的下标,找不到就
打印:“找不到”。
11.2.1 讲解算法原理
- 创建两个变量,一个left,一个right,left指向数组首项,right指向数组末项。mid用来计算arr[left]与arr[right]的平均值。
- 判断arr[mid]与key的大小,如果arr[mid]比key大,则right = mid - 1,反之left = mid + 1。
- 第二步需要使用while循环, 循环结束的条件是left > right
11.2.2 代码演示
#include<stdio.h>intmain(){intarr[12]={2,5,8,12,16,23,38,45,56,67,78,89};intleft=0;intright=sizeof(arr)/sizeof(arr[0])-1;intkey=0;scanf("%d",&key);while(left<=right){intmid=(left+right)/2;if(arr[mid]>key)right=mid-1;elseif(arr[mid]<key)left=mid+1;else{printf("%d\n",mid);break;//找到的话及时跳出循环}}if(left>right)//没找到的情况printf("没找到\n");return0;}求中间元素的下标,尽量使用left + (right - left ) / 2,这样的话防止left或者right太大超出范围。
