IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 数组 [3]|二维数组(C语言) -> 正文阅读

[C++知识库]数组 [3]|二维数组(C语言)

文章转载请注明出处,加上原文链接,谢谢!



什么是二维数组?

E.g. int array[2][3]={{1,2,3},{4,5,6}}

示例数组是一个初始化的 二维数组。定义一个 二维数组和一个普通的一维数组类似,同样包含三要素: 数据类型数组名数组大小。大部分人会说两者的区别在于第三要素 —— 数组大小方面多了一个方括号“[]”,使得二维数组能自由的定义 行数列数 的数量多少。但在笔者看来,矩阵(Matrix)—— 这一数学概念可以完美的阐述两者的区别:

一维数组(int array[]) —— A 1 × n A_{1 \times n} A1×n?
二维数组(int array[][]) —— A m × n A_{m \times n} Am×n?

二维数组和一维数组的表述形式虽然不同,但两个数组在计算机内存里的存储方式是一致的,即 所有数据都是按顺序存储在连续的内存空间内。这一点可自行探究。

二维数组的使用有诸多细节,这里博主再补充一点:参数传递。运用二维数组进行函数传递参数时 行数可以不用填写,但列数必须填写。

演示代码:print_array_double.c

/* print_array_double.c */
#include <stdio.h>

void printArrayDouble(int array[][3])
{
        int i, j;
        for(i = 0; i < 2; i++){
                for(j = 0; j < 3; j++){
                        printf("%d ", array[i][j]);
                }
                putchar('\n');
        }
}

int main()
{
        int array[2][3] = {{1,2,3}, {4,5,6}};
        printArrayDouble(array);
        return 0;
}

点击此处,阅读笔者关于“一维数组”的博文。


二维数组的取值技巧总结

演示代码:value_array_double.c

/* value_array_double.c */
#include <stdio.h>

int main()
{
        int a[2][3] = {{1,2,3},{4,5,6},};
        int i,j;

        printf("a[2][3]: \n");
        for(i = 0; i < 2; i++){
                for(j = 0; j < 3; j++){
                        printf("%d ", a[i][j]);
                }
                putchar('\n');
        }
        putchar('\n');

        printf("a[0][0]     : %d\n", a[0][0]);
        printf("*(*(a+0))   : %d\n", *(*(a+0)));
        printf("**a         : %d\n", **a);
        printf("p of a[0][0]: %p\n", a);
        printf("a[1][1]     : %d\n", a[1][1]);
        printf("*(a[1]+1)   : %d\n", *(a[1]+1));
        printf("*(*(a+1)+1)): %d\n", *(*(a+1)+1));
        printf("p of a[1][2]: %p\n", *(a+2));
        printf("a[1][0]     : %d\n", a[1][0]);
        printf("a[0]+1      : %d\n", *(*(a+1)));
        printf("p of a[1][0]: %p\n", a+1);
        return 0;
}

运行结果:

a[0][0]     : 1
*(*(a+0))   : 1
**a         : 1
p of a[0][0]: 0x7ffcbd065d40
a[1][1]     : 5
*(a[1]+1)   : 5
*(*(a+1)+1)): 5
p of a[1][2]: 0x7ffcbd065d58
a[1][0]     : 4
a[0]+1      : 4
p of a[1][0]: 0x7ffcbd065d4c

二维数组取值形式与含义总结:

表现形式含义
a二维数组名,指向一维数组a[0],即第零行1首地址。
a[0] , ? \ast ?(a+0), ? \ast ?a第零行第零列元素首地址。
a[0][0], ? \ast ?( ? \ast ?(a+0)), ? ? \ast\ast ??a第零行第零列元素的数值。
a+1,&a[1]第一行首地址。
a[1], ? \ast ?(a+1)第一行第零列元素a[1][0]元素的地址。
a[1]+2, ? \ast ?(a+1)+2,&a[1][2]第一行第二列元素a[1][2]的地址。
? \ast ?(a[1]+2), ? \ast ?( ? \ast ?(a+1)+2,a[1][2]第一行第二列元素a[1][2]的值。

? \ast ?注意:二维数组元素的取值方式相比一维数组虽然略有繁琐,但以数学形式理解无非都是存储数据的矩阵而已。配合以上代码理解将事半功倍。


二维数组的遍历

|运用指针遍历二维数组

指针遍历的代码:double_array_pointer.c

/* double_array.c */
#include <stdio.h>

int main()
{
        int array[2][3] = {{1,2,3},{456}};
        int i, j;
        int *p = NULL;
        p = &array[0][0];

        for(i = 0; i < 3; i++){
                for(j = 0; j < 3; j++){
                        printf("%d ", *p++);
                }
                putchar('\n');
        }
        return 0;
}

|数组指针遍历二维数组

演示代码:arrayDouble_arrayPointer.c

/* arrayDouble_arrayPointer.c */
#include <stdio.h>

int main()
{
	int i,j;
	int array[2][3] = {{1,2,3},{4,5,6}};
	int (*p)[3] = NULL;
	p = array;

	printf("for循环遍历:\n");
	for(i = 0; i < 2; i++){
		for(j = 0; j < 3; j++){
			printf("%d ", array[i][j]);
		}
		putchar('\n');
	}
	
	putchar('\n');	
	
	printf("数组指针遍历:\n");
	for(i = 0; i < 2; i++){
		for(j = 0; j < 3; j++){
			//printf("%d ", p[i][j]);
			printf("%d ", *(*(p+i)+j));
		}
		putchar('\n');
	}
	return 0;
}

? \ast ?注:对于优先级混乱的读者,只需牢牢记住三个字符的优先级为 () > [] > ? \ast ?,从大到小逐次递减。


引申 —— 函数指针数组

演示代码:fun_pointer_array.c

/* fun_poniter_array.c 2022.6.18 17:52 */
#include <stdio.h>
#include <stdlib.h>

int getMax(int data1, int data2)
{
        return data1 > data2 ? data1:data2;
}

int getMin(int data1, int data2)
{
        return data1 < data2 ? data1:data2;
}

int getSum(int data1, int data2)
{
        return data1 + data2;
}

int main()
{
        int a = 10, b = 20;
        int ret;

        int (*pfunc[3])(int /*data1*/, int /*data2*/) = {getMax, getMin, getSum};

        for(int i=0; i<3; i++){
                ret = (*pfunc[i])(a, b);
                printf("ret = %d\n", ret);
        }
        return 0;
}

? \ast ?注:该段代码来自陈立臣教师新版C语言教学视频。


参考资料

  • 陈立臣老师新版C语言教学视频。

文章更新记录

  • 文章整体框架搭好。「2022.11.2 11:27」
  • “什么是二维数组?”一节完成。「2022.11.2 16:40」
  • “二维数组的取值技巧总结”一节完成。「2022.11.3 10:30」
  • 第一节“参数传递”补充完毕。「2022.11.3 16:23」
  • “函数指针数组”一节更新完毕。「2022.11.3 16:56」
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:06:35  更:2022-11-05 00:08:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 5:05:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码