1.二维数组的概念
二维数组具有多行多列
2.二维数组的定义及使用
(1)二维数组的定义
数据类型 二维数组名[行数][列数] = {{第0行的初始值},{第1行的初始值}......};
例:int array[3][3] = {{10, 20, 30}, {40, 50, 60},{70, 80, 90}};
(2)数组元素的访问
二维数组名[i][j]; //第i行第j列的元素的值
(3)给数组元素赋值
二维数组名[i][j] = 值; //给第i行第j列元素赋值
(4)二维数组的特点
1> 二维数组中的每个元素的类型一致,由定义数组时的数据类型决定
2> 二维数组的每个元素在内存中依然是连续的
3> 二维数组的行下标和列下标依然从0开始义数组时的数据类型决定
2> 二维数组的每个元素在内存中依然是连续的
3> 二维数组的行下标和列下标依然从0开始
3.二维数组抽象图
《1》
《2》
《3》
4.二维数组定义及初始化方式
#include <stdio.h>
/*
* 二维数组作为函数的实参时,形参写成:数据类型 数组名[][列数]
* 给其传递实参时需要传递一个每行有4列的二维数组
*
* row : 二维数组的行数
* */
void print_array(int array[][4], int row)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", array[i][j]);
}
putchar('\n');
}
}
int main(int argc, const char *argv[])
{
// 1. 定义二维数组的同时对每个元素进行初始化
int arr1[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("%d ", arr1[i][j]);
}
putchar ('\n');
}
// 2. 定义二维数组时,对二维数组的每行的元素部分进行初始化,
// 每行的其他元素默认初始化为0
int arr2[3][4] = {{1,2},{5,6,7},{8}};
// 遍历二维数组,访问二维数组的每个元素
for (int i = 0; i < 3; i++) // 遍历二维数组的行数
{
for (int j = 0; j <4; j++) // 遍历二维数组的每行的列数
{
printf("%d ", arr2[i][j]);
}
putchar ('\n');
}
// 3. 定义二维数组时,依次对每行的元素进行初始化,
// 没有指定初始值的则赋值为0
int arr3[3][4] = {1,2,3,4,5,6,7,8,9};
print_array(arr3, 3);
// 4. 定义二维数组时,将二维数组的所有元素初始化为0
int arr4[3][4] = {0};
print_array(arr4, 3);
// 5. 先定义二维数组,后对数组的每个元素进行初始化,
// 如果二维数组一旦被定义了,在访问数组的每个元素时,
// 只能一个一个元素的进行访问
int arr5[3][4] = {0};
arr5[0][0] = 10;
arr5[0][3] = 40;
arr5[1][1] = 55;
arr5[1][2] = 66;
arr5[2][0] = 88;
arr5[2][3] = 99;
print_array(arr5, 3);
// 6. 通过终端输入的方式对二维数组的每个元素赋值
int arr6[3][4] = {0};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
// &数组名[i][j] : 数组的第i行第j列元素的地址
scanf("%d", &arr6[i][j]);
}
}
print_array(arr6, 3);
#if 0
// 7. 不可以使用以下方式对二维数组进行初始化
// 一旦二维数组定义完成之后,不可以整体赋值
int arr7[2][3];
//arr7 = {{1,2,3},{4,5,6}}; // 错误
// 不可以使用一个二维数组给另一个二维数组赋值
// 原因:二维数组名也是一个常量,不可以被修改
//arr7 = arr5; // 错误
#endif
// 8. 定义二维数组时,不指定二维数组的行数,
// 由定义二维数组进行初始化的值决定二维数组的行数
// 不可以省略二维数组的列数
// 如果省略二维数组的行数,不可以先定义后初始化,
// 必须定义的同时进行初始化
int arr8[][4] = {1,2,3,4,5,6,7,8,9}; // 数组有三行
// int arr9[3][] = {1,2,3,4,5,6,7,8,9}; // 错误,不可以省略列数
return 0;
}
5.二位数组的使用特性
(1)二维数组在访问时,编译器也不会进行二维数组的越界检查, 需要程序员关注访问二维数组时不要进行越界访问
(2) 二维数组名[i][j] : 第i行第j列元素的值
二维数组名[i][j] + 1 : 第i行第j列元素的值 加 1
(3)&二维数组名[i][j] : 第i行第j列元素的地址
&二维数组名[i][j] + 1 : 第i行第j列元素的地址 加 1 , 加1 加二维数组元素类型的大小
(4)二维数组名 : 二维数组名是一个常量,表示二维数组的首地址,
二维数组名是一个行地址 , 二维数组名 + 1 : 二维数组名是一个行地址,加1 加的是二位数组一行的大小
(5)二维数组名[i] : 二维数组的第i行的首地址
二维数组名[i] + 1 : 加1 加二维数组元素类型的大小
(6) &二维数组名[i] : 二维数组的第i行的首地址在进行取地址,变成行地址
&二维数组名[i] + 1 : 加1 加二维数组一行元素的大小
// row : 表示行下标 col:表示列下标 下标从0开始
// 行地址
// 二维数组名 + row <==> &二维数组名[0] + row <==> &二维数组名[row]
// 元素的地址
// &二维数组名[row][col] <==> 二维数组名[row] + col <==> &二维数组名[0][0] + (row * 列数 + col
#include <stdio.h>
int main(int argc, const char *argv[])
{
// 1. 定义一个二维数组
long arr1[3][3] = {10000,20000,30000,
40000,50000,60000,
70000,80000,90000};
// 2. 验证二维数组的每个元素在内存中是连续的
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("&arr1[%d][%d] = %p ", i, j, &arr1[i][j]);
}
putchar('\n');
}
// 3. 二维数组在访问时,编译器也不会进行二维数组的越界检查
// 需要程序员关注访问二维数组时不要进行越界访问
arr1[4][4] = 100000;
printf("arr1[4][4] = %ld\n", arr1[4][4]);
// 4. 二维数组名的使用
// 4.1 二维数组名[i][j] : 第i行第j列元素的值
// 二维数组名[i][j] + 1 : 第i行第j列元素的值 加 1
printf("arr1[1][1] = %ld\n", arr1[1][1]);
printf("arr1[1][1] + = %ld\n", arr1[1][1] + 1);
// 4.2 &二维数组名[i][j] : 第i行第j列元素的地址
// &二维数组名[i][j] + 1 : 第i行第j列元素的地址 加 1
// 加1 加二维数组元素类型的大小
printf("&arr1[0][0] = %p\n", &arr1[0][0]);
printf("&arr1[0][0] + 1 = %p\n", &arr1[0][0] + 1);
// 4.3 二维数组名 : 二维数组名是一个常量,表示二维数组的首地址,
// 二维数组名是一个行地址
// 二维数组名 + 1 : 二维数组名是一个行地址,加1
// 是加二维数组一行的大小
printf("arr1 = %p\n", arr1);
printf("arr1 + 1 = %p\n", arr1 + 1);
// 4.4 二维数组名[i] : 二维数组的第i行的首地址
// 二维数组名[i] + 1 : 加1 加二维数组元素类型的大小
printf("arr[2] = %p\n", arr1[2]);
printf("arr[2] + 1 = %p\n", arr1[2] + 1);
// 4.5 &二维数组名[i] : 二维数组的第i行的首地址在进行取地址,变成行地址
// &二维数组名[i] + 1 : 加1 加二维数组一行元素的大小
printf("&arr[2] = %p\n", &arr1[2]);
printf("&arr[2] + 1 = %p\n", &arr1[2] + 1);
// arr1 <==> &arr1[0]
// &arr1[0][0] <==> arr1[0]
// arr1 + 1 <==> &arr1[0] + 1 <==> &arr1[1]
// &arr1[0][0] + 1 <==> arr1[0] + 1 <==> &arr1[0][1]
// row : 表示行下标 col:表示列下标 下标从0开始
// 行地址
// 二维数组名 + row <==> &二维数组名[0] + row <==> &二维数组名[row]
// 元素的地址
// &二维数组名[row][col] <==> 二维数组名[row] + col <==> &二维数组名[0][0] + (row * 列数 + col)
// 5. 计算二维数组占用内存空间的大小
printf("二维数组占用内存空间大小 = %ld\n", sizeof(arr1));
printf("计算二维数组中元素的个数 = %ld\n", sizeof(arr1) / sizeof(long));
printf("计算二维数组的行数 = %ld\n", sizeof(arr1) / sizeof(arr1[0]));
printf("计算二维数组的列数 = %ld\n", sizeof(arr1[1]) / sizeof(arr1[1][0]));
return 0;
}