通过指针进行迭代和通过索引进行迭代是否产生相同代码

原创 2005年03月04日 11:31:00

编译器对通过指针进行迭代和通过索引进行迭代是否产生相同代码?问题来自于《The C++ Program Language》第五章习题8。

 

测试代码如下:(采用vc.net向导自动生成控制台应用程序)

#include "stdafx.h"

void fi (char v[]) // line 5

{

    for (int i = 0; v[i] != 0; ++i) {

        v[i] += 1;

    }

}

 

void fp (char v[]) // line 12

{

    for (char *p=v; *p != 0; ++p) {

         *pa += 1;

    }

}

 

int _tmain(int argc, _TCHAR* argv[]) // line 19

{

    char a[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g' , 'h'};

    fp (a);

    fi (a);

    return 0;

}

 

vc++7.net上使用参数FA(仅列出程序集),产生的汇编代码如下(未优化):

 

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

 

       TITLE       ./5_8.cpp

       .386P

include listing.inc

... ... ... ...

INCLUDELIB LIBCD

INCLUDELIB OLDNAMES

 

PUBLIC       ?fi@@YAXQAD@Z                              ; fi,函数fi的代码开始

EXTRN       __RTC_InitBase:NEAR

EXTRN       __RTC_Shutdown:NEAR

;      COMDAT rtc$IMZ

; File d:/vsproject/5_8/5_8.cpp

rtc$IMZ       SEGMENT

__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase

rtc$IMZ  ENDS

;      COMDAT rtc$TMZ

rtc$TMZ       SEGMENT

__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown

; Function compile flags: /Odt /RTCsu /ZI

rtc$TMZ ENDS

;       COMDAT ?fi@@YAXQAD@Z

_TEXT       SEGMENT

_i$10435 = -8                                    ; size = 4

_v$ = 8                                             ; size = 4

?fi@@YAXQAD@Z PROC NEAR                                 ; fi, COMDAT

; Line 6

       push       ebp

       mov ebp, esp

       sub  esp, 204                       ; 000000ccH

       push       ebx

       push       esi

       push       edi

       lea   edi, DWORD PTR [ebp-204]

       mov ecx, 51                                ; 00000033H

       mov eax, -858993460                         ; ccccccccH

       rep stosd

; Line 7  // ********************************

       mov       DWORD PTR _i$10435[ebp], 0

       jmp       SHORT $L10436

$L10437:

       mov eax, DWORD PTR _i$10435[ebp]

       add  eax, 1

       mov       DWORD PTR _i$10435[ebp], eax

$L10436:

       mov eax, DWORD PTR _v$[ebp]

       add  eax, DWORD PTR _i$10435[ebp]

       movsx       ecx, BYTE PTR [eax]

       test  ecx, ecx

       je       SHORT $L10434

; Line 8

       mov eax, DWORD PTR _v$[ebp]

       add  eax, DWORD PTR _i$10435[ebp]

       movsx       ecx, BYTE PTR [eax]

       add  ecx, 1

       mov edx, DWORD PTR _v$[ebp]

       add  edx, DWORD PTR _i$10435[ebp]

       mov BYTE PTR [edx], cl

; Line 9

       jmp       SHORT $L10437

$L10434:

; Line 10

       pop  edi

       pop  esi

       pop  ebx

       mov esp, ebp

       pop  ebp

       ret   0

?fi@@YAXQAD@Z ENDP                                  ; fi

_TEXT   ENDS

 

PUBLIC       ?fp@@YAXQAD@Z                                  ; fp,函数fp的代码开始

; Function compile flags: /Odt /RTCsu /ZI

;       COMDAT ?fp@@YAXQAD@Z

_TEXT       SEGMENT

_p$10442 = -8                                          ; size = 4

_v$ = 8                                             ; size = 4

?fp@@YAXQAD@Z PROC NEAR                                 ; fp, COMDAT

; Line 13

       push       ebp

       mov ebp, esp

       sub  esp, 204                       ; 000000ccH

       push       ebx

       push       esi

       push       edi

       lea   edi, DWORD PTR [ebp-204]

       mov ecx, 51                                ; 00000033H

       mov eax, -858993460                         ; ccccccccH

       rep stosd

; Line 14       // ******************************

       mov eax, DWORD PTR _v$[ebp]

       mov       DWORD PTR _p$10442[ebp], eax

       jmp       SHORT $L10443

$L10444:

       mov eax, DWORD PTR _p$10442[ebp]

       add  eax, 1

       mov       DWORD PTR _p$10442[ebp], eax

$L10443:

       mov eax, DWORD PTR _p$10442[ebp]

       movsx       ecx, BYTE PTR [eax]

       test  ecx, ecx

       je       SHORT $L10441

; Line 15

       mov eax, DWORD PTR _p$10442[ebp]

       movsx       ecx, BYTE PTR [eax]

       add  ecx, 1

       mov edx, DWORD PTR _p$10442[ebp]

       mov BYTE PTR [edx], cl

; Line 16

       jmp       SHORT $L10444

$L10441:

; Line 17

       pop  edi

       pop  esi

       pop  ebx

       mov esp, ebp

       pop  ebp

       ret   0

?fp@@YAXQAD@Z ENDP                               ; fp

_TEXT   ENDS

 

PUBLIC  _main

EXTRN       @_RTC_CheckStackVars@8:NEAR

EXTRN       __RTC_CheckEsp:NEAR

; Function compile flags: /Odt /RTCsu /ZI

;      COMDAT _main

... ... ... ...

END

注意上面Line8Line15前后的汇编语句,就是一模一样的。也就是说,在没有任何优化的情况下,通过指针进行迭代和通过索引进行迭代将产生相同代码。

如果进行全面的优化,结果会怎么样呢?对同一个文件,在vc7.net采用RELEASE,打开全局优化,产生的汇编代码如下。可以看到,两个函数的代码仍然是相同的。

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077

 

       TITLE       ./5_8.cpp

       .386P

include listing.inc

... ... ... ...

INCLUDELIB LIBC

INCLUDELIB OLDNAMES

 

PUBLIC       ?fi@@YAXQAD@Z                              ; fi,函数fi的代码开始

; Function compile flags: /Ogty

;       COMDAT ?fi@@YAXQAD@Z

_TEXT       SEGMENT

_v$ = 8                                             ; size = 4

?fi@@YAXQAD@Z PROC NEAR                                 ; fi, COMDAT

; File d:/vsproject/5_8/5_8.cpp

; Line 7

       mov eax, DWORD PTR _v$[esp-4]

       cmp BYTE PTR [eax], 0

       je       SHORT $L9624

       npad       7

$L9622:

; Line 8

       inc   BYTE PTR [eax]

       mov cl, BYTE PTR [eax+1]

       inc   eax

       test  cl, cl

       jne       SHORT $L9622

$L9624:

; Line 10

       ret   0

?fi@@YAXQAD@Z ENDP                                  ; fi

_TEXT   ENDS

 

PUBLIC       ?fp@@YAXQAD@Z                                  ; fp,函数fp的代码开始

; Function compile flags: /Ogty

;       COMDAT ?fp@@YAXQAD@Z

_TEXT       SEGMENT

_v$ = 8                                             ; size = 4

?fp@@YAXQAD@Z PROC NEAR                                 ; fp, COMDAT

; Line 14

       mov eax, DWORD PTR _v$[esp-4]

       cmp BYTE PTR [eax], 0

       je       SHORT $L9631

       npad       7

$L9629:

; Line 15

       inc   BYTE PTR [eax]

       mov cl, BYTE PTR [eax+1]

       inc   eax

       test  cl, cl

       jne       SHORT $L9629

$L9631:

; Line 17

       ret   0

?fp@@YAXQAD@Z ENDP                               ; fp

_TEXT   ENDS

 

PUBLIC  _main

EXTRN       ___security_cookie:DWORD

EXTRN       @__security_check_cookie@4:NEAR

; Function compile flags: /Ogty

;      COMDAT _main

... ... ... ...

END

实战c++中的vector系列--将迭代器转换为索引

stl的迭代器很方便 用于各种算法。但是一想到vector,我们总是把他当做数组,总喜欢使用下标索引,而不是迭代器。这里有个问题就是如何把迭代器转换为索引:#include typedef std::...
  • wangshubo1989
  • wangshubo1989
  • 2015年12月15日 21:26
  • 4768

vector容器的三种遍历方法

STL(Standard Template Library)中vector容器是最常见的容器之一,设计中经常需要遍历vector容器,本文介绍三种常用的vector遍历方式。 一、下标索引遍历  ...
  • u013575812
  • u013575812
  • 2015年12月02日 10:53
  • 4758

iterator迭代器和指针的区别

迭代器与指针的差别: 迭代器: (1)迭代器不是指针,是类模板,表现的像指针。他只是模拟了指针的一些功能,通过重载了指针的一些操作符,->,*,++ --等封装了指针,是一个“可遍历STL...
  • gogoky
  • gogoky
  • 2016年05月05日 22:00
  • 9516

android如何进行版本迭代及代码审核

android如何进行版本迭代及代码审核
  • swebin
  • swebin
  • 2017年03月25日 12:34
  • 508

Linux Shell 之 对文件中的行、单词、字符进行迭代

在进行文本文件进行处理时,对文件件中的行、单词、字符进行迭代和遍历是非常常用的操作。而将一个简单的循环用于迭代,再加上来自stdin或文件的重定向,这就是对文件中的行、单词、和字符进行迭代的基本方法。...
  • ljianhui
  • ljianhui
  • 2013年07月16日 16:55
  • 7369

Linux Shell 之 对文件中的行、单词、字符进行迭代

说起函数调用,相信大家也不会陌生,然而对于初学Shell的我来说,Shell中函数调用方式却有点让我不太习惯,自己也走了不少的弯路,因为传递参数时出了一个很“自然”的错误,也让我吃了不少的苦头,所以总...
  • wjw208151131
  • wjw208151131
  • 2017年04月27日 15:06
  • 61

集合迭代时对集合进行修改抛ConcurrentModificationException原因的深究以及解决方案

绝对原创, 转载请标明文章出处:http://blog.csdn.net/izard999/article/details/6708738 大家应该都知道, 在java中, 在对一些集合...
  • izard999
  • izard999
  • 2011年08月24日 09:44
  • 6631

Java-集合 list对象进行指定位置插入、删除、迭代、遍历输出(具体习题讲解)

原题: 创建一个 List,在 List 中增加三个工人,基本信息如下: 姓名 年龄 工资 zhang3 18 3000li4 25 3500wang5 22...
  • xc121566
  • xc121566
  • 2017年12月10日 20:38
  • 85

怎么在map上进行迭代(java)

在java中的map有很多种迭代方式,我们来看一下一些最常用的方式并且看一下他们的优点和缺点,因为java中的map都继承自Map接口,下边的接口适用于实现map接口的所有形式(HashMap、Tre...
  • maoyeqiu
  • maoyeqiu
  • 2016年01月04日 11:21
  • 354

Java-集合 list对象进行指定位置插入、删除、迭代、遍历输出(具体习题讲解)

原题: 创建一个 List,在 List 中增加三个工人,基本信息如下: 姓名   年龄    工资 zhang3 18      3000 li4    25      3500 wang5 ...
  • xc121566
  • xc121566
  • 2017年07月18日 23:23
  • 416
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:通过指针进行迭代和通过索引进行迭代是否产生相同代码
举报原因:
原因补充:

(最多只允许输入30个字)