二维数组&指针数组&双重指针

前言

        二维数组,指针数组的理解和应用

引入

        以前对此问题有过分析,现在的理解又深刻了一些,所以再做个整体的归纳

二维数组

        二维数组和表的形式类似(表需要简单数据类型,二维数组数据类型随意),例如

 列1列2
行112
行234
行356
行478
行5910
int型二维数组

        用代码表示如下:

int data[5][2]={{1,2},{3,4},{5,6},{7,8},{9,10}};

        二维数组数据的访问:

#include<stdio.h>

int main(void) {
	int data[5][2] = { {1,2},{3,4},{5,6},{7,8},{9,10} };
	/*指向二维数组的指针*/
	int(*datap)[2] = data;				//正确用法
   //int **datap=data					//不可用,不能用双重指针指向二维数组,提示访问错误
	for (int i = 0; i < 5; i++)
		for (int j = 0; j < 2; j++) {
			printf("%d,", datap[i][j]);
		};	
	printf("\n");
	/*第二种访问写法*/
	for (int i = 0; i < 5; i++)
		for (int j = 0; j < 2; j++) {
			printf("%d,", *(*(datap+i)+j));
		};
}

        说明:双重指针不能指向二维数组,编译器不知道访问数据的边界.

                忽略硬编码部分,循环个数i和j直接用数字,C语言特点每个数组必须自己指定边界.

二维数组的特点

        1.二维数组是一维数组的数组.

        2.指向二维数组的指针必须表明一维数组中的数据个数(列数).

        3.二维数组不灵活,有3个地方是固定的:数组中数据的类型,列数,行数.

指针数组

        将上述的二维数组用指针数组表示,如下:

	/*指针数组表达二维数组*/
	int ar1[2] = { 1,2 };
	int ar2[2] = { 3,4 };
	int ar3[2] = { 5,6 };
	int ar4[2] = { 7,8 };
	int ar5[2] = { 9,10 };
	int* arp[5] = { ar1,ar2,ar3,ar4,ar5 };
	for (int k = 0; k < 5; k++)
		for (int n = 0; n < 2; n++) {
			printf("%d,", arp[k][n]);
		};

        指针的特点:可以指向空,指向单(个数据),指向数据集合(数组,链表及其他数据结构).指针数组是由指针组成的数组,遍历指针数组得到一个指针,指针可以指向的数据只保证数据类型是同一个数据类型,但个数是可以不同的.

        再举个例子:

	/*指针指向不同个数的数据*/
	int arr1 = { 1 };
	int arr2[3] = { 2,3,4 };
	int* arrp[3] = { arr1,arr2,0 };		//0表示空指针

        指针数组arrp中有3个元素:arr1有1个,arr2中有3个.空指针也可以作为指针元素

        由上面可以看出:二维数组是指针数组的特例.

        因为指针自动指向数组,双重指针可以指向指针数组,

	int** arrpp = arrp;

        arrpp[0]和arrp[0]都表示数组arr1.

双重指针

        简单说一下双重指针:

        以前才看见双重指针的时候觉得有点复杂,以为是很厉害的技能,又奇怪为何书中没有用多的篇幅来写,现在才知道一是繁琐二是不够灵活,尽量不用双重指针.像上面的例子,指针数组用数组名来表示就可以了,无需专门用双重指针来表达.

        双重指针的应用场景也曾提过:在函数中需要改变指针指向的时候.有兴趣可以翻笔者以前的贴

表(二维数组)的替代方案

        用一维数组的数组来替换二维数组

//用一个数据类型表示一行
struct Complex_data{
    int data_1;
    int data_2;
};
//一个数据表示一个元组
Complex_data cd1={1,2};
Complex_data cd2={3,4};
//一个表用一个数组来表达
Complex_data cd[5]={cd1,cd2};

        每个复杂类型Complex_data还可以表达不止一种类型(int)

=============================内容分割线↓===================================

        在上一篇帖子中,用表提供了数据文件中的数据单元的抽象.然而数据文件如何与操作系统交互,又如何放到程序中呢?这个问题没解决是很难办的.所以表仍然以数据对象的形式放在.h或者.c文件中为好.

        因此表换成datatype+参数,这种形式可以满足笔者目前水平要求

=============================内容分割线↑===================================

指针数组的应用

       笔者分析过Object类型,有兴趣可以看谢谢支持.

        在C++或者Java中有个类叫做Object,象征"无限".类型中有Object*对象代表拥有所有的数据,不管这些数据是什么时候添加的.继承Object表示自身也属于无限的一部分,非常方便.而C++和Java底层都是C来写的,在C语言中Object是如何实现的呢?

        假设这样写

//C语言写Object
struct Object{
    char *any[type_number];
    int type_number;
    int anytype_number[type_number];    
    struct Object * object_array;
}

        每有一个类型,就把它"压扁"成一个char型数组(计算机最小单位"字节"),用type_number表示数据类型的个数,用anytype_number表示每个数据类型的对象个数---指针可以指向空,单,多.

        单从数据类型包含数据内容的角度,Object类型表达就是这样.当然具体类型要表达出包含数据的相对关系,这要写算法来表达,这里不展开了.

小结

        二维数组是指针数组的特例,指针数组很灵活源于指针的特点.

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重庆彭枫

你的鼓励是我创作的动力,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值