目录
1.数组简介
比如现在有如下场景,有100个变量需要你去定义,如果没有数组我们只能int a,int b,int c,int d.........或者inta,b,c,d,.......这样的的方式去定义,很麻烦并且这种定义方式在内存空间中是分散的,并不好去管理这些变量。那么我们引入数组的概念:
如何定义一个数组
int a[10] ;它表示定义了一个整形数组,数组名为a,此数组有10个整形元素。定义一个一维数组的一般表达形式:类型符 数组名[常量表达式];这里要注意必须是相同的数据类型。
如何访问数组
我们知道数组里面定义的变量是没有变量名的,我们可以通过下标法访问某个元素,从0开始计数。a[0],代表数组内第一个变量,a[1]代表第二个以此类推。类似于通过学号就能找到某个学生是一样的。并且通过数组定义的这些变量地址空间都是连续的。
我们可以定义一个数组并且把各个变量的地址打印出来看一看,代码如下。从下面的现象不能看出每个变量的地址都是连续的。
#include <stdio.h>
int main()
{
int a[10];
int data;
for(data=0;data<10;data++){
a[data] = data+10;
}
for(data=0;data<10;data++){
printf("变量=%d,地址=%p\n",a[data],&a[data]);
}
return 0;
}
2.初始化数组的几种方式
1.全部幅值
2.部分赋值
只给数组的一部分赋值,后面没有赋上值的系统自动幅值为0。
3.初始化成0
4.见怪不怪的写法
不定义数组内变量的个数,系统会自动给数组里面的内容进行分配。
这种写法通常也可以配合sizeof来使用。把整个数组的大小除以数组中一个元素的大小就可以计算出整个数组中的变量有多少个。
sizeof:是用来计算出对应数据的内存空间大小,并且它是一个C语言关键字,并不是一个函数
int array[] = {1,2,3,45,66,7,77,8};
int size;
size = sizeof(arrary)/sizeof(arrary[0]);
3.数组初级小项目------冒泡排序法
刚学完数组的可以靠这个小项目练练手,这个项目也是嵌入式软件工程师常见的面试笔试题。
//由大到小排序
#include <stdio.h>
int main()
{
int i;
int j;
int tmp;
int arrary[]={8,4,13,2};
int len;
len = sizeof(arrary)/sizeof(arrary[0]);
for(i=0;i<len-1;i++){
for(j=0;j<len-1-i;j++){
if(arrary[j]<arrary[j+1]){ //如果想从小到大排序只需改为 arrary[j]>arrary[j+1]
tmp = arrary[j+1];
arrary[j+1] = arrary[j];
arrary[j]= tmp;
}
}
}
for(i=0;i<len;i++){
printf("%d ",arrary[i]);
}
}
运行结果:
4.二维数组
如何定义二维数组
类型说明符 数组名【常量表达式】【常量表达式】
二维数组可以看成为特殊的一维数组,比如之前的一维数组是定义一个班的学生,那么二维数组就可以看作一次定义很多个班的学生。
如何遍历二维数组
#include <stdio.h>
int main()
{
int arrary1[2][3] = {111,222,333,444,555,666};
int arrary2[2][3] = {{111,222,333},{444,555,666}}; //二维数组两种不同的定义方法
int i,j;
for(i=0;i<2;i++){
for(j=0;j<3;j++){
printf("%d,%d,%d\n",i,j,arrary1[i][j]);
}
}
putchar('\n');
for(i=0;i<2;i++){
for(j=0;j<3;j++){
printf("%d \n",arrary2[i][j]);
}
}
return 0;
}
二维数组的初始化
方式1:
#include <stdio.h>
int main()
{
int arrary[3][4] = {1,2,3}; //这种初始化方法是从第一行第一个开始依次赋值
int i,j;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
printf("%d ",arrary[i][j]);
}
putchar('\n');
}
return 0;
}
结果如下:
方式2:
#include <stdio.h>
int main()
{
int arrary[3][4] = {{1},{2},{3}}; //这种方式是给每一行的第一个数赋值
int i,j;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
printf("%d ",arrary[i][j]);
}
putchar('\n');
}
return 0;
}
结果如下:
方式3:可以不写行,但列必须写
int arrary[][4] = {1,2,3};
5.二维数组应用之找最大值及对应下标
#include <stdio.h>
int main()
{
int arrary[3][4] = {11,22,34,55,67,456,56,654,33,222,34,67};
int i,j;
int lang;
int lie;
int max = arrary[0][0];
for(i=0;i<3;i++){
for(j=0;j<4;j++){
printf("%d ",arrary[i][j]);
}
putchar('\n');
}
for(i=0;i<3;i++){
for(j=0;j<4;j++){
if(max < arrary[i][j]){
max = arrary[i][j];
lang = i;
lie = j;
}
}
}
printf("最大的数是%d,在第%d行第%d列\n",max,lang+1,lie+1);
return 0;
}
结果如下:
6.数组与函数开发(数组传参作为形式参数)
学习数组肯定离不开跟函数相结合使用,用下面这段demo来讲解数组与函数结合应该注意到问题。
#include <stdio.h>
void printArr(int arry[],int len) //形参中不存在数组的概念,即使括号约定了数组的大小也无效
{ //传递的是数组的首地址
int i;
for(i=0;i<len;i++)
{
printf("%d ",arry[i]);
}
putchar('\n');
}
int main()
{
int arry[5] = {29,23,45,64,21};
int len;
len = sizeof(arry)/sizeof(arry[0]);
printArr(arry,len); //数组名代表整个数组的首地址
printArr(&arry[0],len); //第一个元素代表的地址是数组的首地址
//以上两种传参方式运行结果都一致
return 0;
}
运行结果:
7.数组与函数开发(数组传参作为实际参数)
先看这样一个小例子,在自己定义的函数中和在main函数中都定义一个变量data,然后分别打印出来里面的值。结果发现看似main函数和定义的函数打印出来的值应该是一样的,运行后会发现主函数中的data的变量并没有发生改变。
为什么会出现这样的现象,是因为两次对变量data的调用其实是在不同的内存空间进行操作的,打印出地址也可以清楚的看出来地址并不相同。并没有main函数中的data所在的地址的变量进行操作,所以main函数打印出来的data值是不变的。
#include <stdio.h>
void changedta(int data)
{
data = data+100;
printf("data in func = %d,address = %p\n",data);
}
int main()
{
int data;
data = 10;
changedta(data);
printf("data in main = %d,address = %p\n",data);
return 0;
}
运行结果:
再看下面这个例子,跟上面的例子大同小异,只不过是把形参换成了数组。结果还会像上个demo一样吗,显然不是。这次两次打印出的值当然就是一样的,为什么?因为把形参变为数组之后函数传递的不再是变量值本身了,而传递的是地址。都是对同一地址里面的变量进行操作,结果当然是一样的了。
#include <stdio.h>
void changedta(int data[])
{
data[0] = data[0]+100;
printf("data in func = %d\n",data[0]);
}
int main()
{
int data[] = {10,20};
changedta(data);
printf("data in main = %d\n",data[0]);
return 0;
}
结果如下:
以上两个demo诠释了非数组变量和数组变量作为形参的区别,也是编程中的大坑。
数组的内容就总结到这里了,欢迎交流。