数组详细讲解
数组
数组概念:数组一组相同元素的集合(数组中的元素类型相同)
数组元素的个数不能为0
数组分为一维数组,二维数组, 三维数组........
数组的创建
type arr_name[常量值]
//type表示数组里元素的类型(int char double...)
//arr_name表示数组名字(后期指针中拿数组名来表示数组第一个元素的地址)
数组也有特定的类型 type [常量值]即为数组类型,比如int a[10]的类型是int [10], char a[10]的类型为 char [10]........
完全初始化:int arr[5]={1,2,3,4,5};
数组初始化
不完全初始化:int arr[5]={1}; 注意:这里不是指数组里的所以元素都初始化成 1,而是第一个元素初始化为1剩余的默认为0
错误数组初始化 int arr[5]={1,2,3,4,5,6}; 数据溢出初始化元素个数超过数组大小
一维数组
1.数组的下标
数组 | 1 | 2 | 3 | 4 | 5 |
下标 | 0 | 1 | 2 | 3 | 4 |
c语言规定数组里第i个元素的下标为i-1
输入:1 2 3 2 1
输出:1 2 3 2 1
2.数组访问:C语言提供了一个访问数组的操作符[ ](下表引用操作符)
举例:对于数组a
int a[5]={1,2,3,4,5};
printf("%d\n",a[2]);//访问数组a的下标为2也就是第三个元素结果为3
printf("%d\n",a[4]);// 结果为5
3.数组的输入和输出
#include <stdio.h>
int main()
{int a[5];//不写默认元素为0int i=0;for(i=0;i<5;i++)//数组a起始下标为0所以i从0开始取scanf("%d",&a[i]);for(i=0;i<5;i++)printf("%d",a[i]);return 0;
}
//输入:1 2 3 2 1
//输出:1 2 3 2 1
4.一维数组在内存中的存储
#include <stdio.h>
int main()
{int a[5]={1,2,3,4,5};for(int i=0;i<5;i++){printf("&a[%d]=%p\n",i,&a[i]);//%p打印地址 &取地址操作符}
return 0;
}
&a[0]= 013F8D0
&a[1]= 013F8D4
&a[2]= 013F8D8//这里是以16进制来表示地址
&a[3]= 013F8DC
&a[4]= 013F8E0
由每个地址的最后两个数D0, D4, D8. DC......不难看出两个相邻的元素之间相差4(一个整型(int)占4个字节),且数组的内存是连续存放的.
danshi
5. 计算数组元素个数
计算数组元素的个数利用sizeof(计算类型或变量的大小单位为字节)
int a[5]={1,2,3,4,5};//元素类型是in类型占4字节
sizeof(a);//计算数组a所占字节,则结果为5*4=20
所以数组元素个数等于数组所占字节/单个元素所占字节
int s=sizeof(a)/sizeof(a[0]);
二维数组
1.二维数组的创建
type arr_name[常量值1][常量值2]//常量值1表示行,常量值2表示列//int a[3][5]
//double a[5][5]
int a[2][5]:
下标 | 0 | 1 | 2 | 3 | 4 |
0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 |
完全初始化 int a[2][3]={1,2,3,4,5,6}
下标 | 0 | 1 | 2 |
0 | 1 | 2 | 3 |
1 | 4 | 5 | 6 |
二维数组初始化 按照行初始化 int a[2][3]={{1,2},{3,4}}(用{}表示{}内的元素为一行)
下标 | 0 | 1 | 2 |
0 | 1 | 2 | 0 |
1 | 3 | 4 | 0 |
错误初始化:1. int a[3][]={1,2,3,4,5}//不确定一行有几个就不能确定哪些元素在哪一行
所以二维数组创建时可以省略行不能省略列(int a[][3]={1,2,3,4,5}表示1,2,3在第一行,4,5,0在第二行,该数组一共两行)
2.二维数组的访问
对于数组a[2][3]={1,2,3,4,5}
int a[2][3]={1,2,3,4,5};
//a[0][2]=3
//a[1][1]=4
//a[1][2]=0
3.二维数组的输入和输出
int main()
{int a[2][3];int i =0,j=0;//i表示行坐标,j表示列坐标for(i=0;i<2;i++)for(j=0;j<3;j++)scanf("%d",&a[i][j]);for(i=0;i<2;i++){for(j=0;j<3;j++)printf("%d",a[i][j]);putchar('\n');//输出一个字符}return 0;
}
//输入:1 2 3 4 5 6
//输出:1 2 34 5 6
3.二维数组在内存中的存储
int main()
{int a[2][3]={0};int i =0,j=0;for(i=0;i<2;i++){for(j=0;j<3;j++)printf("&a[%d][%d]="i,j,&a[i][j]);}return 0;
}
二维数组跟一维数组一样每两个相邻的元素之间相差4,且每个元素都是连续存放的.
数组拓展(C99中的变长数组)
1.变长数组
变长数组允许变量来指定数组大小,能避免有时候数组过大占空间以及过小不够使用的情况
int n;
scanf(“%d”,&n);
int a[n]int n,m;
scanf("%d %d",&n,&m);
int a[n][m];
注意:变长数组在vs——Msvc编译器中不可使用,在小熊猫c++/dev c++——gcc编译器可以实现。程序运行后n确定了,变长数组大小也就固定了,不可更改。
2.多个字符从两端移动,中间汇聚
char a[]={dian zan jia guan zhu zhi chi};
char b[]={#############################};
int left=0;
int right=(sizeof(a)/sizeof(a[0]))-1;
while(left<=right)
{b[left]=a[left];b[right]=a[right];printf("%s\n",b);left++;//向左移动right--;//向右移动
}
d############################
di##########################i
dia########################hi
dian######################chi
dian #################### chi
dian z##################i chi
dian za################hi chi
dian zan##############zhi chi
dian zan ############ zhi chi
dian zan j##########u zhi chi
dian zan ji########hu zhi chi
dian zan jia######zhu zhi chi
dian zan jia #### zhu zhi chi
dian zan jia g##n zhu zhi chi
dian zan jia guan zhu zhi chi
不过这是一次性输出来的想要一行一行输出
#include <stdlib.h>
int main()
{sleep(1000)//睡眠1000毫秒
}
3.数组与算法的结合(二分查找)
#include <stdio.h>
int main()
{int a[] = { 1,2,3,4,5,6,7,8,9,10 };int left = 0;int right = sizeof(a) / sizeof(a[0]) - 1;int mid = 0;int flag = 0;//定义一个变量来判断有没有找到int key;//要查找的数scanf("%d", &key);while (left <= right){mid = (left + right) / 2;if (a[mid] > key)//说明查找元素在left~mid-1之间right = mid - 1;//更新查找区域的右下标else if (a[mid] < key)//说明查找元素在mid+1~right之间left = mid + 1;if (a[mid] == key){flag = 1;break;}}if (flag)printf("找到了下标是%d\n", mid);elseprintf("找不到\n");
}
7
找到了下标是6
依次遍历的时间O(n),二分查找时间复杂度为O(log2n)[每次查找去掉一半区域]
比如在2^16个数中找一个数,依次遍历最多需要2^16次,而二分查找制药16次,可见二分查找效率高。
注意:二分查找只能使用在有序序列(递增或递减)
制作不易,希望小伙伴们多多点赞支持关注。哪里有问题也可以随时私信我。