1. The parameters of the prinf function contain pointer expressions. In what order are they calculated? The result of the code operation is obviously not from left to right.
#include <stdio.h>
int main() {
int a[5] = { 1,2,3,4,5 };
int *p = a;
printf("%d\n", *p);
printf("%d %d %d %d\n", *(++p)++,*p, *p++, *p);
getchar();
return 0;
}
给我你的怀抱2017-06-27 09:20:57
Changing a variable multiple times in one statement is undefined behavior and may have different results on different platforms. This question makes no sense.
学习ing2017-06-27 09:20:57
printf{"%d",++i}
represents two operations
First execute i=i+1, then output i
And i++ means
First output, then execute i=i+1
某草草2017-06-27 09:20:57
The order of operation of function parameters has little to do with the internal logic of the function. It should calculate ++p
before pushing it onto the stack (before the function is executed), and then calculate p++
after the function ends. If you want to know the specific sequence, you can refer to the assembly code (the specific meaning will be updated tomorrow, sorry)
.file "a.cpp"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "%d1
3 2 1 1
"
LC1:
.ascii "%d %d %d %drrreee"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB10:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %esi
pushl %ebx
andl $-16, %esp
subl , %esp
.cfi_offset 6, -12
.cfi_offset 3, -16
call ___main
movl , 40(%esp)
movl , 44(%esp)
movl , 48(%esp)
movl , 52(%esp)
movl , 56(%esp)
leal 40(%esp), %eax
movl %eax, 60(%esp)
movl 60(%esp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf
movl 60(%esp), %eax
movl (%eax), %ebx
movl 60(%esp), %eax
leal 4(%eax), %edx
movl %edx, 60(%esp)
movl (%eax), %ecx
movl 60(%esp), %eax
movl (%eax), %edx
addl , 60(%esp)
movl 60(%esp), %eax
leal 4(%eax), %esi
movl %esi, 60(%esp)
movl (%eax), %eax
movl %ebx, 16(%esp)
movl %ecx, 12(%esp)
movl %edx, 8(%esp)
movl %eax, 4(%esp)
movl $LC1, (%esp)
call _printf
call ___getreent
movl 4(%eax), %eax
movl %eax, (%esp)
call _getc
movl rrreee, %eax
leal -8(%ebp), %esp
popl %ebx
.cfi_restore 3
popl %esi
.cfi_restore 6
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE10:
.ident "GCC: (GNU) 5.4.0"
.def _printf; .scl 2; .type 32; .endef
.def ___getreent; .scl 2; .type 32; .endef
.def _getc; .scl 2; .type 32; .endef
Digression:
2 and 3 that appear in the results can still be explained.
4 is very strange. If I have to explain it reluctantly, the ++
outside the brackets of *(++p)++
also works for p
,
but the operator is in the form of p++
, which should be in It is incremented after the statement ends, so this explanation is obviously wrong.
I am in Cygwin + gcc (GCC) 5.4.0
environment. The running results are as follows. 4 does not appear. What environment did you use?
ringa_lee2017-06-27 09:20:57
The order in which function parameters are pushed onto the stack is certain, but the order in which the parameters are evaluated is not specified
. The
compiler only guarantees that the values of all parameters are known before printf
is called
Information on this is available Search Sequence Point