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