C 递增结构成员
假设我有一个定义如下的结构C 递增结构成员,c,struct,increment,pre-increment,C,Struct,Increment,Pre Increment,假设我有一个定义如下的结构 struct my_struct { int num; }; 这里有一个指向my_struct的指针,我想对num void foo(struct my_struct* my_ptr) { // increment num // method #1 my_ptr->num++; // method #2 ++(my_ptr->num); // method #3 my_
struct my_struct
{
int num;
};
这里有一个指向my_struct
的指针,我想对num
void foo(struct my_struct* my_ptr)
{
// increment num
// method #1
my_ptr->num++;
// method #2
++(my_ptr->num);
// method #3
my_ptr->++num;
}
这三种递增num
的方法是否也有相同的作用?
当我们这样做的时候,是不是增量前比增量后更有效
谢谢 前两种方法具有相同的效果(当它们自己在一行上时),但第三种方法不是有效的C代码(不能将
++
放在那里)
至于效率,没有区别。你可能听到人们所谈论的差异是,在C++中,你增加了一个非指针数据类型,比如迭代器。在某些情况下,预增量可能更快
您可以使用查看生成的代码
输出:
foo(my_struct*): # @foo(my_struct*)
incl (%rdi)
ret
bar(my_struct*): # @bar(my_struct*)
incl (%rdi)
ret
正如你所看到的,没有任何区别
前两者之间唯一可能的区别是在表达式中使用它们时:
my_ptr->num = 0;
int x = my_ptr->num++; // x = 0
my_ptr->num = 0;
int y = ++my_ptr->num; // y = 1
如果您的唯一目的是增加num的值,那么第一个和第二个方法将向被调用方方法产生相同的预期结果 但是,如果将代码更改为以下内容,则可以看到gcc生成的代码(程序集级代码)之间的差异: 现在使用:gcc-masm=intel-S structTest.c-o structTest.S编译它 这要求gcc生成汇编代码: 在文本编辑器中打开structTest.s
foo:
.LFB0:
push rbp
mov rbp, rsp
sub rsp, 16
**mov QWORD PTR [rbp-8], rdi**
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
mov edx, eax
**lea ecx, [rax+1]**
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], ecx
mov eax, OFFSET FLAT:.LC0
mov esi, edx
mov rdi, rax
mov eax, 0
call printf
leave
ret
.cfi_endproc
main:
.LFB1:
push rbp
mov rbp, rsp
sub rsp, 16
**mov DWORD PTR [rbp-16], 10
lea rax, [rbp-16]
mov rdi, rax
call foo**
leave
ret
.cfi_endproc
当您将操作更改为预增量时,将生成以下代码:
foo:
.LFB0:
.cfi_startproc
push rbp
mov rbp, rsp
sub rsp, 16
**mov QWORD PTR [rbp-8], rdi**
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
**lea edx, [rax+1]**
mov rax, QWORD PTR [rbp-8]
**mov DWORD PTR [rax], edx**
mov rax, QWORD PTR [rbp-8]
**mov edx, DWORD PTR [rax]**
mov eax, OFFSET FLAT:.LC0
mov esi, edx
mov rdi, rax
mov eax, 0
call printf
leave
ret
.cfi_endproc
因此,您将看到在第二种情况下,编译器增加num值并将该num值传递给printf()
就性能而言,我希望post增量会更有效,因为内存位置的接触次数更少
在上述代码中,重要的行已标记在**之间
foo:
.LFB0:
push rbp
mov rbp, rsp
sub rsp, 16
**mov QWORD PTR [rbp-8], rdi**
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
mov edx, eax
**lea ecx, [rax+1]**
mov rax, QWORD PTR [rbp-8]
mov DWORD PTR [rax], ecx
mov eax, OFFSET FLAT:.LC0
mov esi, edx
mov rdi, rax
mov eax, 0
call printf
leave
ret
.cfi_endproc
main:
.LFB1:
push rbp
mov rbp, rsp
sub rsp, 16
**mov DWORD PTR [rbp-16], 10
lea rax, [rbp-16]
mov rdi, rax
call foo**
leave
ret
.cfi_endproc
foo:
.LFB0:
.cfi_startproc
push rbp
mov rbp, rsp
sub rsp, 16
**mov QWORD PTR [rbp-8], rdi**
mov rax, QWORD PTR [rbp-8]
mov eax, DWORD PTR [rax]
**lea edx, [rax+1]**
mov rax, QWORD PTR [rbp-8]
**mov DWORD PTR [rax], edx**
mov rax, QWORD PTR [rbp-8]
**mov edx, DWORD PTR [rax]**
mov eax, OFFSET FLAT:.LC0
mov esi, edx
mov rdi, rax
mov eax, 0
call printf
leave
ret
.cfi_endproc