我在哪里可以找到++运算符的实现?
在哪里可以找到数字和指针的++
运算符的C / C ++实现?
我环顾网络,但没有找到太多……
可能是我的答案(数量)在某种程度上有帮助:
你可以为指针开车答案
i++
如何在低级别工作。
int main(){ int i=0,j=0; j=i++; // expresion includes two operations `+, = printf("%d %d",j,i); }
您可以使用带有gcc (g++)
-S
标志来反汇编它:
我的代码名称是mc
$ gcc -S mc
它将创建一个ms
程序集文件。
阅读我添加的评论 :
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 = i + 1
// abstract syntax tree + (post) / \ / \ = 1 / \ / \ ji
案例前缀++
(++ i):
还假设如果表达式是j = ++i
那么我直接编写抽象语法树:
它将首先递增++
然后=
执行;
// abstract syntax tree for j = ++i = / \ / \ j \ + (prefix) / \ / \ i 1
j = ++i
汇编代码,其中j=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)
实现位于编译器的源代码中。
通常,您的编译器将执行以下操作:
- 推断
i
的类型。 - 如果
i
是普通整数类型或对整数的引用,则编译器将生成一个中间表示,指示内存中的负载(如果需要)和简单的+1增量。 - 如果
i
是指针,编译器将生成一个中间表示,指示来自内存的加载(如果需要),后跟添加sizeof(*i)
而不是+1的add指令。 - 如果
i
是重载operator++()
在范围内的类型,则它生成一个中间表示,指示对重载运算符定义的函数调用。
这里没有魔力。 i++
通常映射到整数类型的简单add
或inc
指令,并可能映射到C ++中的函数调用。
我想你想看到为这个操作生成的机器代码。 这里 :
//sg int main() { int i=0; ++i; return 0; }
编译: gcc -S -fverbose-asm -masm=intel test.c
这是集会(相关部分):
mov DWORD PTR [ebp-4], 0 # i, add DWORD PTR [ebp-4], 1 # i,
比较这个
//sg int main() { int i=0,j; j=i+1; return 0; }
这会产生更长的asm:
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
更改为更短的i++
。
这是一个非常基本的问题,你最好从教科书中学到这个问题
但无论如何
对于数字
内置++
将数值增加1,从而改变内存内容。 您可以对整数和浮点对象使用此运算符。 你可以将它用作前缀运算符,编写++x
,以及作为后缀运算符,编写x++
。
区别在于前缀和后缀变体产生的表达值。 前缀++x
递增x
并生成x
的新值(在C ++中,因为我记得它产生了对x
的引用,带有新值)。 后缀x++
递增x
并生成x
的原始值。
指针
前缀和后缀之间的区别是相同的,但“增加1”的定义是不同的
对于指向T*
数组的第i项的T*
类型的指针,在递增该指针之后它指向数组的第i + 1项。
这意味着机器代码级地址增加了sizeof(T)
。
如果最终值是明确定义的,则表达式p+n
,其中n
是整数,产生与n
增量相同的最终值。 这也可以写成n+p
。