目录
6.数组作为函数参数
1.二维数组的创建
int arr[3][4];
//创建了一个整形的二维数组
//3行4列
char arr[2][5];
//创建了一个字符型数组
double arr[4][2];
//创建了一个浮点型数组
如何理解一个二维数组:
- 对一个一维数组int arr[5]:
//可以看出一维数组是由单行元素构成
//将一维数组看做一条数轴
//通过某一个确定的数字可以在数轴上找到一个确定的点
//同理:通过一个确定的下标数字,在一维数组中可以找到与之对应的元素,如:arr[2]
- 对于一个二维数组int arr[3][4]:
//二维数组由多行多列的元素构成
//这个数组可以看成是由三行的一维数组组成
//在平面直角坐标系中,通过一个坐标(2,3)可以找到唯一与之对应的一个点
//二维数组中,通过arr[2][3]可以找到唯一一个元素
2.二维数组的初始化
- int arr[3][4] = { 0 };
//把二维数组中所有元素初始化为0
- int arr[3][4] = {1,2,3,4,5,6,7,8,9};//不完全初始化
由以上程序看出二维数组初始化的规律:先初始化第一行,再初始化第二行;不够补0
- 我们再看另一种初始化方式:int arr[3][4] = { {1,2},{4,5,6},{7,8} };
//当使用{ }时,{1,2}就为第一行元素,不够补0
我们知道一维数组初始化可以不指定大小,那么二维数组可以不指定大小吗?
运行结果如下:
//程序报错:数组arr缺少下标
//我们知道二维数组初始化时先把列填满,再填充下一行,可以得出列必须是已知的
//所以二维数组如果有初始化,行可以省略,列不能
数组行大小的计算:sizeof(arr)/ sizeof(arr[0])
//数组的大小除以第一行的大小
数组列大小的计算:sizeof(arr[0])/ sizeof(arr[0][0])
//第一行的大小除以第一个元素的大小
3.二维数组的使用
3.1 矩阵转置
例题:将一个2*3的矩阵转置变成3*2矩阵
由示意图分析:
//得有一个2*3的矩阵和一个3*2的矩阵——>创建俩个二维数组arr1[2][3],arr2[3][2];
//输入要转置的矩阵
//矩阵转置
//由示意图可以发现转置就是将元素行和列的数字交换
//由此可得以下代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr1[2][3] = { 0 };
int arr2[3][2] = { 0 };
int i = 0;
int n = 0;
//原矩阵赋值
while (1)
{
for (i = 0; i < 2; i++)
{
int j = 0;
for (j = 0; j < 3; j++)
{
scanf("%d", &n);
arr1[i][j] = n;
}
}
break;
}
//输出原矩阵
printf("转置前的矩阵为:\n");
for (i = 0; i < 2; i++)
{
int j = 0;
for (j = 0; j < 3; j++)
{
printf("%d ", arr1[i][j]);
}
printf("\n");
}
//输出转置后的矩阵
printf("转置后的矩阵为:\n");
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 2; j++)
{
printf("%d ", arr1[j][i]);
}
printf("\n");
}
return 0;
}
程序运行:
注:这是规定了矩阵行列的情况,同样的道理,我们可以实现3*4,5*6,.......矩阵的转置
4.二维数组在内存中的存储
我们把二维数组每个元素的地址打印出来:
012FF868
012FF86C
012FF870
.......
//地址以十六进制存储,每个地址相差四个字节
//我们定义的是int类型的数组,所以一个元素所占的内存是4个字节
//所以二维数组在内存中是连续存放的
5.数组越界
我们先来看一段打印一维数组的代码:
程序运行后,打印的是:1 2 3 4 5 -858993460
//我们的目的是打印数组中所有元素:1 2 3 4 5
//但是打印的结果不止有数组的五个元素
//所以我们打印代码有问题
//for(i = 0; i <= 5; i++)
//循环时i的取值是0~5,总共六个数字
//但是数组的下标范围是0~4,循环多进行了一次,产生了arr[5]
//arr[5]是非法的,导致数组越界访问,超出了数组合法空间的访问
但是程序可以正常运行,不会报错,只会产生一个警告
//因为C语言本身不做数组下标的越界检查,编译器也不一定不报错
//所以编译器不报错,并不意味着程序正确
6.数组作为函数参数
详见冒泡排序的实现 冒泡排序