1. 二维数组定义与内存结构
(1) 语法
类型说明符 数组名[行数][列数];
int a[3][4]; // 3行4列的整型数组
(2) 内存布局
连续存储:按行优先顺序排列(先存第0行所有元素,再存第1行,依此类推)
地址关系: a[0]:第0行首地址,等价于&a[0][0]
a:整个数组的起始地址,与&a[0]相同
2. 二维数组初始化
(1) 完全初始化
int arr[2][3] = {1,2,3,4,5,6};
(2) 部分初始化
int arr[2][3] = {1,2,3,4}; // 第0行1,2,3;第1行4,0,0
(3) 行数
int a[][3] = {{1}, {2,3}}; // 行数为2 ,靠近变量名的行可以省略
3. 二维数组操作
(1) 元素访问
a[1][2] = 100; // 修改第2行第3列元素
(2) 行数与列数计算
int rows = sizeof(a) / sizeof(a[0]); // 总行数
int cols = sizeof(a[0]) / sizeof(a[0][0]); // 每行列数
4.程序
(1)二维数组求和
//求和
int main(void)
{
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int rows = sizeof(a) / sizeof (a[0]);
int cols = sizeof(a[0]) / sizeof(a[0][0]);
int i,j,sum = 0;
for(i = 0;i < rows;++i)
{
for(j = 0;j < cols;++j)
{
sum = sum + a[i][j];
}
}
printf("%d\n",sum);
return 0;
}
(2)边缘数的和
//四周之和
int main(void)
{
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int i,j,sum = 0;
int rows = sizeof(a) / sizeof(a[0]);
int cols = sizeof(a[0]) / sizeof(a[0][0]);
for(i = 0;i < rows;++i)
{
for(j = 0;j < cols;++j)
{
if(0 == i || 0 == j || rows - 1 == i || cols - 1 == j)
{
sum += a[i][j];
}
}
}
printf("%d\n",sum);
return 0;
}
(3)水平翻转
//水平翻转
int main(void)
{
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int i,j;
int rows = sizeof(a) / sizeof(a[0]);
int cols = sizeof(a[0]) / sizeof(a[0][0]);
for(i = 0;i < rows;++i)
{
for(j = 0;j < rows / 2;++j)
{
int t;
t = a[i][j];
a[i][j] = a[i][cols - j - 1];
a[i][cols - j - 1] = t;
}
}
for(i = 0;i < rows;++i)
{
for(j = 0;j < cols;++j)
{
printf("%2d",a[i][j]);
}
puts("");
}
return 0;
}
(4)魔方阵
//魔方阵
int main(void)
{
int a[3][3] = {0};
int i = 0,j = 1,n;
a[i][j] = 1;
int rows = sizeof(a) / sizeof(a[0]);
int cols = sizeof(a[0]) / sizeof(a[0][0]);
for(n = 2;n < 10;++n)
{
int x = i;
int y = j;
++j;
if(j > 2)
{
j = 0;
}
--i;
if(i < 0)
{
i = 2;
}
if(0 != a[i][j])
{
i = x;
j = y;
++i;
if(i > 2)
{
i = 0;
}
}
a[i][j] = n;
}
for(i = 0;i < rows;++i)
{
for(j = 0;j < cols;++j)
{
printf("%2d",a[i][j]);
}
puts("");
}
return 0;
}
(5)极值
//极值
#include <string.h>
int main(void)
{
char s[][100] = {"Hello","World","china"};
char max[100];
int i;
int rows = sizeof(s) / sizeof(s[0]);
strcpy(max,s[0]);
for(i = 1;i < rows;++i)
{
if(strcmp(max,s[i]) < 0)
{
strcpy(max,s[i]);
}
}
puts(max);
return 0;
}
(6)逆序
//逆序
#include <string.h>
int main(void)
{
char s[][100] = {"Hello","World","china"};
int rows = sizeof(s) / sizeof(s[0]);
int i;
for(i = 0;i < rows / 2;++i)
{
char a[100];
strcpy(a,s[i]);
strcpy(s[i],s[rows - i - 1]);
strcpy(s[rows - i - 1],a);
}
for(i = 0;i < rows;++i)
{
puts(s[i]);
}
return 0;
}
(7)排序
a.选择排序
//选择排序
#include <string.h>
int main(void)
{
char s[][100] = {"Hello","World","China","America"};
int rows = sizeof(s) / sizeof(s[0]);
int i,j;
for(i = 0;i < rows - 1;++i)
{
for(j = i + 1;j < rows;++j)
{
if(strcmp(s[i],s[j]) > 0)
{
char a[100];
strcpy(a,s[i]);
strcpy(s[i],s[j]);
strcpy(s[j],a);
}
}
}
for(i = 0;i < rows;++i)
{
puts(s[i]);
}
return 0;
}
b.冒泡排序
//冒泡排序
#include <string.h>
int main(void)
{
char s[][100] = {"Hello","World","China","America"};
int rows = sizeof(s) / sizeof(s[0]);
int i,j;
for(i = rows - 1;i > 0;--i)
{
for(j = 0;j < i;++j)
{
if(strcmp(s[j],s[j + 1]) > 0)
{
char a[100];
strcpy(a,s[j]);
strcpy(s[j],s[j + 1]);
strcpy(s[j + 1],a);
}
}
}
for(j = 0;j < rows;++j)
{
puts(s[j]);
}
return 0;
}
c.插入排序
//插入排序
#include <string.h>
int main(void)
{
char s[][100] = {"Hello","World","China","America"};
int rows = sizeof(s) / sizeof(s[0]);
int i,j;
for(i = 1;i < rows;++i)
{
char a[100];
strcpy(a,s[i]);
int j = i;
while(j > 0 && strcmp(s[j - 1],a) > 0)
{
strcpy(s[j],s[j - 1]);
--j;
}
strcpy(s[j],a);
}
for(i = 0;i < rows;++i)
{
puts(s[i]);
}
return 0;
}
(8)二分查找
//二分查找
#include <string.h>
int main(void)
{
char s[][100] = {"Hello","World","China","America"};
int rows = sizeof(s) / sizeof(s[0]);
int i,j;
for(i = rows - 1;i > 0;--i)
{
for(j = 0;j < i;++j)
{
if(strcmp(s[j],s[j + 1]) > 0)
{
char a[100];
strcpy(a,s[j]);
strcpy(s[j],s[j + 1]);
strcpy(s[j + 1],a);
}
}
}
char n[100] = "China";
int begin = 0;
int end = rows - 1;
int mid;
while(begin <= end)
{
mid = (begin + end) / 2;
if(strcmp(s[mid],n) > 0)
{
end = mid - 1;
}
else if(strcmp(s[mid],n) < 0)
{
begin = mid + 1;
}
else
{
break;
}
}
if(begin <= end)
{
printf("found\n");
}
else
{
printf("error\n");
}
return 0;
}
5.总结
1. 二维数组本质:一维数组的扩展,按行连续存储
2. 内存视角:a、a[0]、a[0][0]地址相同但类型不同
3. 行/列计算:通过`sizeof`运算符动态获取维度信息
4. 嵌入式应用:图像处理、矩阵运算