C语言二维数组与指针

16 篇文章 0 订阅
16 篇文章 0 订阅

<c程序设计语言>中的关于这个的解释:

Newcomers to C are sometimes confused about the difference between a two-dimensional array and an array of pointers, such as name in the example above. Given the definitions 

   int a[10][20];

   int *b[10];

then a[3][4] and b[3][4] are both syntactically legal references to a single int. But a is a true two-dimensional array: 200 int-sized locations have been set aside, and the conventional rectangular subscript calculation 20 * row +col is used to find the element a[row,col]. For b, however, the definition only allocates 10 pointers and does not initialize them; initialization must be done explicitly, either statically or with code. Assuming that each element of b does point to a twenty-element array, then there will be 200 ints set aside, plus ten cells for the pointers. The important advantage of the pointer array is that the rows of the array may be of different lengths. That is, each element of b need not point to a twenty-element vector; some may point to two elements, some to fifty, and some to none at all. 

Although we have phrased this discussion in terms of integers, by far the most frequent use of arrays of pointers is to store character strings of diverse lengths, as in the function month_name. Compare the declaration and picture for an array of pointers: 

   char *name[] = { "Illegal month", "Jan", "Feb", "Mar" };

with those for a two-dimensional array: 

   char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };

 


所以如果传递参数为二维数组的话,形参类型应该为int *b[]

--------------------------------

概括的说,指针其实就是可变数组的首地址,说是可变数组,是 指其包含内容的数量的可变的,并且是可动态申请和释放的,从而充 
分节约宝贵的内存资源。我一向喜欢一维数组,除非万不得已,我一 般是不用二维数组的,多维的则更是很少涉足了。因为一维简单,容 
易理解,而用指针指向的多维数组就具有相当的复杂性了,也因此更 具有讨论的必要。 
    闲话少说,这里我就以三个二维数组的比较来展开讨论: 
    (1)、int **Ptr; 
    (2)、int *Ptr[ 5 ]; 
    (3)、int ( *Ptr )[ 5 ]; 
    以上三例都是整数的二维数组,都可以用形如 Ptr[ 1 ][ 1 ] 的 方式访问其内容;但它们的差别却是很大的。下面我从四个方面对它们 
进行讨论: 
    一、内容: 
       它们本身都是指针,它们的最终内容都是整数。注意我这里说 的是最终内容,而不是中间内容,比如你写 Ptr[ 0 ],对于三者来说, 
其内容都是一个整数指针,即 int *;Ptr[ 1 ][ 1  ] 这样的形式才 是其最终内容。 
    二、意义: 
       (1)、int **Ptr 表示指向"一群"指向整数的指针的指针。 
       (2)、int *Ptr[ 5 ] 表示指向 5 个指向整数的指针的指针。 
       (3)、int ( *Ptr )[ 5 ] 表示指向"一群"指向 5 个整数数 组的指针的指针。 
    三、所占空间: 
       (1)、int **Ptr 和 (3)、int ( *Ptr )[ 5 ] 一样,在32位平 台里,都是4字节,即一个指针。 
       但 (2)、int *Ptr[ 5 ] 不同,它是 5 个指针,它占5 * 4 = 20 
个字节的内存空间。 
    四、用法: 
       (1)、int **Ptr       因为是指针的指针,需要两次内存分配才能使用其最终内容。首 先,Ptr = ( int ** )new int *[ 5 ];这样分配好了以后,

它和(2)的 意义相同了;然后要分别对 5 个指针进行内存分配,例如: 
  Ptr[ 0 ] = new int[ 20 ];   它表示为第 0 个指针分配 20 个整数,分配好以后, Ptr[ 0 ] 为指 
向 20 个整数的数组。这时可以使用下标用法 Ptr[ 0 ][ 0 ] 到 Ptr[ 0 ][ 19 ] 了。       如果没有第一次内存分配,该 Ptr 是个"野"指针,

是不能使用 的,如果没有第二次内存分配,则 Ptr[ 0 ] 等也是个"野"指针,也 是不能用的。当然,用它指向某个已经定义的地址则是允许的,那是另外 
的用法(类似于"借鸡生蛋"的做法),这里不作讨论(下同)。
      (2)、int *Ptr[ 5 ] 
      这样定义的话,编译器已经为它分配了 5 个指针的空间,这相当 于(1)中的第一次内存分配。根据对(1)的讨论可知,显然要对其进行一次 
内存分配的。否则就是"野"指针。 
      (3)、int ( *Ptr )[ 5 ] 
      这种定义我觉得很费解,不是不懂,而是觉得理解起来特别吃力, 也许是我不太习惯这样的定义吧。怎么描述它呢?它的意义是"一群" 
指针,每个指针都是指向一个 5 个整数的数组。如果想分配 k 个指针,这样写: Ptr = ( int ( * )[ 5 ] ) new int[ sizeof( int ) * 5 * k ]。 
这是一次性的内存分配。分配好以后,Ptr 指向一片连续的地址空间, 其中 Ptr[ 0 ] 指向第 0 个 5 个整数数组的首地址,Ptr[ 1 ] 指向第 
1 个 5 个整数数组的首地址。    综上所述,我觉得可以这样理解它们: 
   int ** Ptr <==> int Ptr[ x ][ y ]; 
   int *Ptr[ 5 ] <==> int Ptr[ 5 ][ x ]; 
   int ( *Ptr )[ 5 ] <==> int Ptr[ x ][ 5 ]; 
   这里 x 和 y 是表示若干的意思。

from:http://www.cnblogs.com/carekee/articles/1948326.html


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值