精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>C、C++语言基础>>指针技术>>关于指针——指针的用法

主题:关于指针——指针的用法
发信人: riffle()
整理人: girlrong(2000-05-27 14:55:32), 站内信件
    我已经说过,指针其实可以看作是一个数组的,于是访问指针所
指向的内容就可以用下标的方式,也可以用指针的方式;但是到底哪
种方法好呢?下面我举两个例子对此进行讨论:

    假设我定义了一个数组,它是用作 FIFO 队列的:

      /* PRODUCT 表示产品数据结构 */
      PRODUCT taProduct[ MAX ];
      PRODUCT *tpProductTail = &taProduct;
      PRODUCT *tpProductHead = &taProduct;
      unsigned int uiProcductTail = 0;
      unsinged int  uiProductHead = 0;

    为了登记产品,我可以用下面的方式(方式A)

    /* 方式 A */
    Produce( PRODUCT tNewProduct )
    {
       *tpProductTail = tNewProduct;
       tpProductTail++;
       if ( tpProductTail >= &taProduct[ MAX ] )
         tpProductTail = &taProduct[ MAX ];
    }

    我也可以用这样的方式(方式 B )

    /* 方式 B */
    Produce( PRODUCT tNewProduct )
    {
       taProduct[ uiProductTail ] = tNewProduct;
       uiProductTail++;
       if ( uiProductTail >= MAX )
         uiProductTail = 0;
    }

  (为了便于讨论,以上代码去掉了队列满的判断)。

   那么这两种方式有什么区别呢?对于方式 A,位置的调整工作是对指
针进行的,对于DOS程序的LARGE和HUGE模式以及WINDOWS下的程序,都是
双字运算,即4字节运算;对于方式 B,DOS程序下是单字运算,而对于32
位 WINDOWS 程序,由于整数是32位的,也为双字运算。因此总的说来,
位置的调整,两种方式区别不大,主要区别就看对指针赋值和使用下标
了。我们知道,对于*tpProductTail = tNewProduct;,由于已经知道
tpProductTail 的地址,只需间接引用一下就行了;

   但是对于taProduct[ uiProductTail ] = tNewProduct; 却不同,编
译器产生的代码是,先取taProduct的地址,然后将uiProductTail的内容
乘上PRODUCT结构的字节数,再将该结果加到taProduct的偏移中,才得到
新的地址,最后进行赋值。计算机的乘法指令是很慢的,显然方式 B 不
如方式 A 快。

   这是一种“微效率”现象,它可能对程序的总体效率有影响,也可能没
有影响。对方式 B 来说,如果对于“产品”的“生产”是一个很复杂的拷
贝动作,则下标运算所消耗的时间是微不足道的。

   在有些情况下,乘法运算的开销会降低。例如,当类型PRODUCT的大小为
1 时,经过优化就可以将乘法运算省去(一个值乘以1仍然等于这个值);
当类型PRODUCT的大小是2的幂时(此时PRODUCT通常是系统固有类型),乘法
运算就可以被优化为左移位运算(就象一个十进制的数乘以10一样)。

   方式 B 速度是不够快,但是方式 B也有它的优点,那就是使用下标时会
时刻提醒自己注意下标越界的问题,而指针则没有这么强烈——这是一个很
奇怪的现象——好象我一用下标就会联想到下标越界。因此从安全性的角度
来看,我更喜欢用下标一些。

   总的说来,两种方式个有优缺点。如果效率是一个非常突出的问题,连这
种“微效率”都要计算在内的话,就应该优先采用方式 A 了。否则的话,我
觉得方式 B 更可取一些。

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.103.137.34]

[关闭][返回]