1.1一维数组的定义以及初始化
数组:用来定义多个同类型的变量
格式:
类型 数组名称[长度]
int arr[10];//定义一个长度为10的int数组arr
具体用例:
int main()
{
int a = 10;//是初始化
int b;//随机值(-858993460),不是0
b = 10;//不是初始化
int arr[10];//定义一个长度为10的int数组,没有初始化,默认全为随机值
int brr[10] = { 1,2,3,4,5,6,7,8,9,10 };//初始化列表,全部成员都初始化
int crr[10] = { 1,2,3,4,5,6 };//1,2,3,4,5,6,0,0,0,0 只初始化一部分,剩余部分全为0(重要)
int drr[] = { 1,2,3,4,5 };//自动推导数据长度
return 0;
}
注:当我们遇到输出是屯屯屯或者烫烫烫的时候都是因为没有正确初始化内存:
举个例子:(-858993460)负8亿多之类的数字(未初始化内存)转为16进制为0xcccc中文字符码为烫,而动态内存未初始化的值为屯,16进制为0xcd
1.2一维数组的使用
数组通过下标访问每个元素,下标从0开始,注意不要越界
int brr[10];//定义长度为10的int数组
长度为10,下标从0开始,那么就是(0~9);如果需要将红色格子的数据改为100,则可写成brr[3]=100;下标可以是整型变量
int arr[10];//数组定义时,[]中必须是常量,表示长度
arr[0] = 100;//数组使用时候,[]中可以使用常/变量,表示下标
提示:变量和函数定义时前面有数据类型,使用时没有数据类型,通过这个就能区分定义和使用
例:通过下标循环遍历数组中的每个元素
int main()
{
int brr[] = { 0,1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < sizeof(brr) / sizeof(brr[0]); i++)//sizeof()表示求里面的字节数,总字节数/每个格子的字节数,就是数组长度
{
printf("%d ", brr[i]);
}
printf("\n");
}
1.2.1通过下标访问数组的数据
例:把arr数组的奇数下标值+10,偶数下标+20
void show(int* arr, int len)
{
for (int i = 0; i < len ; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//把arr数组的奇数下标+10,偶数下标+20
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
if (i % 2 == 0)//偶数下标
arr[i] += 20;
else//奇数下标
arr[i] += 10;
}
show(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
1.2.2数组的整体处理
例:1.把arr的值复制到brr中(不能brr=arr,数组不能整体赋值)
2.把arr和brr对应下标的值相加存放到crr中(不能crr=arr+brr)
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int brr[10];
int crr[10];
//把arr的值复制到brr中(不能brr=arr,数组不能整体赋值)
for (int i = 0; i < sizeof(brr) / sizeof(brr[0]); i++)
{
brr[i] = arr[i];
}
show(brr, sizeof(brr) / sizeof(brr[0]));
//把arr和brr对应下标的值相加存放到crr中(不能crr=arr+brr)
for (int i = 0; i < sizeof(crr) / sizeof(crr[0]); i++)
{
crr[i] = arr[i]+brr[i];
}
show(crr, sizeof(crr) / sizeof(crr[0]));
}
例3:把数组的数据进行反转,即第一个数据和最后一个数据进行交换,第二个数据与倒数第二个进行交换,直到所有数据反序
思路:定义两个变量i,j分别从数据的前面往后走和后面往前面走,交换其中两个变量的数据。
int main()
{
//数组反转
int arr[] = { 1,2,3,4,5,6,7,8,9,10};
int size = sizeof(arr) / sizeof(arr[0]); // 动态计算数组大小
int tmp;
for (int i = 0, j = size-1; i <j; i++, j--)
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
show(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
2.数组长度公式
- sizeof(表达式):求表达式占用的字节数
- 一维数组arr,求其长度公式:sizeof(arr)/sizeof(arr[0]) (数组所有元素的字节数/数组中一个格子的字节数=数组格子数=数组长度)
注意:这个数组arr不能是函数的形参
注:指针在不同平台的大小不一样,这里只是说明sizeof求其长度,不适用于arr是函数的形参
3.二维数组
3.1二维数组的定义和初始化
定义:
数据类型 数组名[行数][列数]
int arr[3][4];//行为3,列为4的int数组
int main()
{
int arr[] = { 1,2,3 };//定义一维数组
int brr[3][4];//定义3行4列的二维数组未初始化
int crr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
int drr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int err[][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };//可省略高维信息
return 0;
}
注:二维数组和一维数组定义类似
二维数组也是通过下标访问其中的元素,且下标也是从0开始,将红色格子的值改为100,则brr[2][1]=100
例:输出brr的内容
int main()
{
int brr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%-3d ", brr[i][j]);//-3d表示每个数字输出占3格,左对齐。美观
}
printf("\n");
}
}
3.2二维数组的使用
例1:矩阵逆置,将一个二维数组行和列的元素互换,存到另一个二维数组中
思路:既然逆置了,那就要定义一个crr[4][3],然后把brr的数据遍历复制到crr中
void show2(int (*arr)[3], int low)
{
for (int i = 0; i < low; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%-3d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int brr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
int crr[4][3];
for (int i = 0; i < 3; i++)//遍历每一行
{
for (int j = 0; j < 4; j++)//遍历每一列
crr[j][i] = brr[i][j];//注意不要写错了,行列互换
}
show2(crr, 4);
return 0;
}
注:这个输出函数(show2)的参数传递在后面讲,现在就只是单纯输出一下
例2:有一个3*4的矩阵,求其最大值以及对应的行 列号
思路:遍历整个数组,用一个变量保存最大值,另外两个变量保存最大值所对应的下标
int main()
{
int arr[3][4] = { 1,2,5,7,3,9,7,0,5,8,11,8};
int max = arr[0][0];//保存最大值
int low = 0;//保存行号
int high = 0;//保存列号
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
if (arr[i][j] >= max)//如果比当前max大,则替换最新的max
{
max = arr[i][j];
low = i;
high = j;
}
}
}
printf("最大值为:%d,行号:%d,列号:%d\n", max, low + 1, high + 1);
return 0;
}
4.数组在进行参数传递时,该如何定义形参
4.1一维数组的参数传递
向函数传递一维数组时,形参可以定义成数组/指针的形式
因为用到数组就需要用到数组长度,刚才又说了,当arr为形参时候sizeof就不适用于求数组长度,所以我们只能从外界传入长度
(但是字符串数组可以不传长度,因为有strlen()函数可以求其长度)
4.2二维数组的参数传递
有几种方法,我把自己觉得最适用的两种方法记录下来
4.2.1使用指针
void arry(int (*arr)[3],int rows)
//调用时就 arry(arr,4)//传递3行4列的二维数组
注:为什么要这么写函数参数传递呢?这我在后面讲指针数组|数组指针|指针函数|函数指针的时候具体说明
4.2.2将二维数组转为一维数组传递
这种方式需要手动计算元素位置,但可避免指定第二维的大小
void arry(int* arr, int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
printf("%-3d ", *(arr + i * cols + j));
}
printf("\n");
}
}
注:arr为二维数组的首元素地址,i*cols为前面i行元素总数,j是当前行第j元素的偏移量
arr+i*cols+j为arr[i][j]的地址,再通过解引用获取当前值.