C Prime Plus---------------------------多维数组(第十章)

本文详细介绍了C语言中的多维数组,包括其概念、初始化、赋值和使用指针操作多维数组的方法。此外,还讨论了指针与多维数组的关系,如指针和数组的关系、指向多维数组的指针、指针的兼容性以及在函数中处理多维数组的方式。最后,提到了变长数组和复合字面量的应用,为处理不同尺寸的数组提供了灵活性。
摘要由CSDN通过智能技术生成

一、多维数组的概念

多维数组可以看作是数组 的数组。即主数组的元素依然是一个数组。

二维数组的声明: float rain[5][12];这声明了一个有5个元素的数组rain,至于每个元素的情况,查看声明其余部分,可以看到每一个元素的类型是float[12],即每一个元素本身是一个内含12个float类型的数据。

二维数组的初始化:①.类似于一维数组  float rain[5][12] = {1,2,3,4,5,6};

                                ②:float rain[5][12] = {

                                                                                   { 1,2,3}, 

                                                                                   { 1,2,3},

                                                                                   { 1,2,3},

                                                                                   { 1,2,3}, 

                                                                                   { 1,2,3}                                                  

                                                                           };

二维数组的赋值: 二维数组需要使用两个嵌套的for循环,一个循环处理数组的第一个下标,另一个循环处理数组的第二个下标。

二、指针和多维数组

2.1指针和数组的关系:

int zippo[4][2];

数组名 zippo的数组首元素的地址,所以 zippo = &zippo[0];

zippo[0]本身是一个内含两个整数的数组,所以zippo[0]= &zippo[0][0];

                                                                         zippo = &zippo[0]= &&zippo[0][0];

                                                                        *zippo = zippo[0]=&zippo[0][0];

                                                                        **zippo = * (zippo[0])= zippo[0][0].

指针或地址加1,其值会增加对应类型大小的数值。zippo 和zippo[0]不同,zippo指向对象占用两个int大小,而zippo指向对象只占用一个int大小。zippo+1和zippo[0]+1的值不同。

2.2指向多维数组的指针

如何声明一个指针变量pz指向一个二维数组(如,zippo)?

int (*pz) [2]; //  pz指向一个内含两个int类型值的数组  (每一个元素内含两个int 类型的数值)

pz = zippo;

虽然pz是一个指针,不是数组名,但是也可以使用pz[2][1]这样的写法。可以使用数组表示法或指针表示法来表示一个数组元素,既可以使用数组名,也可以使用指针名

zippo[m][n]=pz[m][n]=*(*(pz+m)+n)

2.3指针的兼容性

在一维数组中,我们知道不能把指向int类型的指针赋值给指向double类型的指针,再多维数组中依然有这样的问题。

例如:int * pt, int ** pc  int(*pa)[2]  int (*pb)[3];     int ar_1[3][2]    int ar_1[2][3]

以下赋值操作:

pt = &ar_1[0][0];  //均指向int类型

pt = ar_2[0];      //均指向int类型

pt = ar_1;    // 错,pt指向int类型,ar_1指向一个内含3个int类型元素的数组

pa = ar_1;  //均指向一个内含2个int类型的数组;

pa = ar_2; // 错 pa指向一个内含2个int类型的数组,ar_2指向一个内含3个int类型的数组

pb = ar_2; //均指向一个内含3个int类型的数组;

pc = &pt;  //均指向一个指针

*pc = ar_1[0];  //均指向一个int的指针

pc = ar_1;  //错 ,pc指向指针,ar_1指向数组,类型不同。

注意:在一维数组const使用方法里讲到,可以把非const数据赋值给一个指向const的指针,这种方法仅限于一级解(只有指针变量,没有指向指针的变量)引用,如果有大于一级解引用,这时运行的结果是未定义的(乱码、垃圾值之类)。

2.4函数和多维数组

如果要编写处理二维数组的函数,首先要正确的理解指针才能写出声明函数的形参。在函数体中,通常使用数组表示法进行相关操作。

如果要写一个处理junk[3][4]的数组的函数

函数的声明:void somefunction ( int (* pt)[4])

               void somefunction(int pt [][4] )--------------------------只有pt在描述函数形参时才能这样书写

void somefunction(int pt [][] )-------------错误,编译器会把数组表示法转化为指针表示法,如果不知道第二个下标参数,编译器就会只知道地址,不知道一个元素的大小,如果第二个方括号是空的,编译器就不知道怎样处理,所以第二个方括号数字必须存在

常用的函数声明更是这样  void somefunction(int pt [][4],int rows ),这样就可以处理任一行数的列数相同的数组。

对于多维数组而言,只有最左边的方括号里的数字可以省略,并且如果后边有第二个参数,即便第一个方括号写上数字,也会被忽略。

三、变长数组

概念:变长数组中的“变”不是指可以修改已创建数组的大小,而是指在创建数组时,可以使用变量指定数组的维度一旦创建了变长数组,数组大小保持不变

原因:在学习使用函数处理二维数组时,要求数组第二个下标必须相同,否则就要重新编写函数,所以就有了变长数组的由来。

变长数组的声明: int sum2d(int rows,iint cols,int ar[rows][cols]);  //顺序不能变

                             int sum2d(int ,int ,int ar[*][*]); //可以省略原型中的变量名,但是必须用星号代替省略的维度。 

以变长数组作为形参的函数不仅可以处理传统C数组,也可以处理变长数组。

是否可以在声明数组时使用const常量?

C99/C11标准允许在声明变长数组时使用const常量,数组的定义必须是生命在块中的自动存储类别数组。(const常量释放内存是,数组也会被释放)

四、复合字面量

由来:对于一个接受int变量的函数,我们既可以传入一个int 变量,也可以直接传入一个整型常量,如4,5等。那么对于数组,我们要怎么传入一个类似于常量的数组呢?复合字面量就解决了这个问题。

对于数组,复合字面量类似于数组初始化列表,复合字面量会创建一个匿名数组(没有名字),因此复合字面量必须在创建时就要使用。

int diva[2]= {10,20};                 (int[2]){10,20};-------复合字面量

典型用法:

total 1 = sum(pt1,2);

total 3 = sum( (int [6]) {4,5,6,7,8,9}, 6 );

其他用法:提前定义指针,在创建复合字面量时将指针指向该复合字面量,然后就可以通过指针访问这个匿名变量。

int *pt1;

pt1 =   (int[2]){10,20};    *pt1 = 10; pt1[1]=20;

注意:复合字面量是提供临时需要值得一种手段,定义在最内层的花括号里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值