我在哪里可以找到++运算符的实现?

时间:2013-01-05 06:00:53

标签: c++ c algorithm

在哪里可以找到数字和指针的++运算符的C / C ++实现?

我环顾网络但发现并不多......

4 个答案:

答案 0 :(得分:6)

实现在您的编译器的源代码中。

通常,您的编译器将执行以下操作:

  • 推断i
  • 的类型
  • 如果i是普通整数类型或对整数的引用,编译器将生成一个中间表示,指示内存中的负载(如果需要)和简单的+1增量。
  • 如果i是指针,编译器将生成一个中间表示,指示内存中的负载(如果需要),后跟添加sizeof(*i)而不是+1的添加指令。
  • 如果i是一个重载operator++()在其范围内的类型,它会生成一个中间表示,指示对重载运算符定义的函数调用。

这里没有魔力。 i++通常映射到整数类型的简单addinc指令,并可能映射到C ++中的函数调用。

答案 1 :(得分:4)

可能是我的答案(对于数字)在一定程度上有所帮助:
你可以开车回答指针

i++如何在低级别工作。

int main(){
    int i=0,j=0;
    j=i++;  // expresion includes two operations `+, =      
    printf("%d %d",j,i);
}

您可以使用-S标记gcc (g++)来反汇编它:
我的代码名称为m.c

$ gcc -S m.c

它将创建一个m.s程序集文件。

阅读评论我补充道:

pushl   %ebp
movl    %esp, %ebp
andl    $-16, %esp
subl    $32, %esp

movl    $1, 28(%esp)            // i due to declarations 
movl    $0, 24(%esp)            // j

movl    28(%esp), %eax          // this two lines are j = i
movl    %eax, 24(%esp)

addl    $1, 28(%esp)            // increment to i, i++

movl    $.LC0, %eax
movl    28(%esp), %edx
movl    %edx, 8(%esp)
movl    24(%esp), %edx
movl    %edx, 4(%esp)
movl    %eax, (%esp)
call    printf

分配=首先发生++。如果++是后缀。

编译器的工作原理:

(根据我的编译器)

表达式j = i ++的抽象语法树的自下而上评估。

源代码:

j = i++;  

在低级别分为两个指令(如汇编代码所示):
    j = i     我+ +

i++i = i + 1

的位置
// abstract syntax tree

       + (post)
      / \
     /   \  
    =     1 
   / \       
  /   \
 j     i  

前缀案例++ (++ i):

另外假设表达式是j = ++i,那么我直接编写抽象语法树:

首先递增++然后=执行;

// abstract syntax tree for j = ++i  

    =
   / \       
  /   \
 j     \ 
       + (prefix)
      / \
     /   \  
    i     1 

最初j = ++ij=0 i=1的汇总代码:

movl    $1, 28(%esp)          // i declaration 
movl    $0, 24(%esp)          // j  
addl    $1, 28(%esp)          // First  Add 1 to i because i++ (before = perform)
movl    28(%esp), %eax        // Below two steps: = performed  j = i 
movl    %eax, 24(%esp)

答案 2 :(得分:3)

我认为您希望查看为此操作生成的机器代码。在这里:

//sg
int main()
{
    int i=0;
    ++i;
    return 0;
}

编译:{{1​​}}

这是集会(相关部分):

gcc -S -fverbose-asm -masm=intel test.c

将此与

进行比较
mov DWORD PTR [ebp-4], 0    # i,
add DWORD PTR [ebp-4], 1    # i,

这将生成更长的asm:

//sg
int main()
{
    int i=0,j;
    j=i+1;
    return 0;
}

另请注意,现代编译器会自动将mov DWORD PTR [ebp-4], 0 # i, mov eax, DWORD PTR [ebp-4] # tmp62, i add eax, 1 # tmp61, mov DWORD PTR [ebp-8], eax # j, tmp61 更改为较短的i=i+1

答案 3 :(得分:1)

这是非常基本的问题,您最好从教科书中了解

但无论如何

数字

内置++会将数值增加1,从而更改内存内容。您可以对整数和浮点对象使用此运算符。您可以将其用作前缀运算符,编写++x,以及作为 postfix 运算符,编写x++

区别在于前缀和后缀变体产生的表达式值。前缀++x递增x并生成新值x(在C ++中,我记得它产生了对x的引用,带有新值)。后缀x++会增加x并生成原始x

指针的

前缀和后缀之间的差异是相同的,但“增加1”的定义是不同的

指向类型为T*的指针指向T数组的第i项,在递增该指针后指向数组的第i + 1项。

这意味着机器代码级地址增加了sizeof(T)

表达式p+n其中n是一个整数,如果最终值是明确定义的,则产生与n增量相同的最终值。这也可以写成n+p