1.请问prinf函数的参数中含有指针表达式,是按照什么顺序运算的,代码运算结果中显然不是从左到右进行的。
#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; }
光阴似箭催人老,日月如移越少年。
在一条语句里多次改变一个变量属于未定义行为,在不同平台可能有不同结果。这个问题没有意义。
printf{"%d",++i} 表示两个操作
printf{"%d",++i}
先执行i=i+1,再输出i
而 i++ 表示的是
先输出后,再执行 i=i+1
函数参数的运算顺序,跟函数的内部逻辑关系不大,应该是入栈前(函数执行前)先计算++p,函数结束后,再计算p++。如果想知道具体的顺序,可以参照汇编代码(具体含义等我明天更新,抱歉)
++p
p++
.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
1 3 2 1 1
题外话:结果中出现的2和3还可以说的通。4很奇怪,非要勉强地解释的话,*(++p)++括号外面的++也对p起作用了,*(++p)++括号外面的++也对p起作用了,但是形如p++运算符,应该在语句结束后才自增的,所以这样解释明显不对。我在Cygwin + gcc (GCC) 5.4.0但是形如p++运算符,应该在语句结束后才自增的,所以这样解释明显不对。
*(++p)++
++
p
Cygwin + gcc (GCC) 5.4.0
函数参数压栈的顺序是一定的,只是参数的求值顺序是未指定的,编译器只保证在printf调用之前,所有参数的值是已知的这方面的资料可以搜索序列点(Sequence Point)
参数的求值顺序是未指定
printf
序列点(Sequence Point)
在一条语句里多次改变一个变量属于未定义行为,在不同平台可能有不同结果。这个问题没有意义。
printf{"%d",++i}
表示两个操作先执行i=i+1,再输出i
而 i++ 表示的是
先输出后,再执行 i=i+1
函数参数的运算顺序,跟函数的内部逻辑关系不大,应该是入栈前(函数执行前)先计算
++p
,函数结束后,再计算p++
。如果想知道具体的顺序,可以参照汇编代码(具体含义等我明天更新,抱歉)题外话:
我在结果中出现的2和3还可以说的通。
4很奇怪,非要勉强地解释的话,
*(++p)++
括号外面的++
也对p
起作用了,*(++p)++
括号外面的++
也对p
起作用了,但是形如
p++
运算符,应该在语句结束后才自增的,所以这样解释明显不对。我在
Cygwin + gcc (GCC) 5.4.0
但是形如p++
运算符,应该在语句结束后才自增的,所以这样解释明显不对。Cygwin + gcc (GCC) 5.4.0
环境,运行的结果如下,没有出现4,请问题主用了什么环境?🎜 rrreee函数参数压栈的顺序是一定的,只是
参数的求值顺序是未指定
的,编译器只保证在
printf
调用之前,所有参数的值是已知的这方面的资料可以搜索
序列点(Sequence Point)