c 语言 指针输出,C/C++语言printf函数输出指针指向的数组的值时,指针的值为什么这样变化?...

本文通过一段C++代码示例,详细分析了函数参数的运算顺序以及内存中的值变化过程。讨论了预增量运算符++p和后增量运算符p++在函数调用前后的应用,并结合汇编代码解释了其执行顺序。在特定环境下,代码运行结果为13211,揭示了运算符的优先级和作用时间。
摘要由CSDN通过智能技术生成

函数参数的运算顺序,跟函数的内部逻辑关系不大,应该是入栈前(函数执行前)先计算++p,函数结束后,再计算p++。如果想知道具体的顺序,可以参照汇编代码(具体含义参考注释)

.file "a.cpp"

.def ___main; .scl 2; .type 32; .endef

.section .rdata,"dr"

LC0:

.ascii "%d\12\0"

LC1:

.ascii "%d %d %d %d\12\0"

.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 $64, %esp

.cfi_offset 6, -12

.cfi_offset 3, -16

call ___main

movl $1, 40(%esp) ;从(esp+40)到(esp+56)间,依次放入1~5。int a[5] = { 1,2,3,4,5 };

movl $2, 44(%esp)

movl $3, 48(%esp)

movl $4, 52(%esp)

movl $5, 56(%esp)

leal 40(%esp), %eax ;(esp+40)的地址,放入(esp+60)。int *p = a;

movl %eax, 60(%esp)

movl 60(%esp), %eax ;从(esp+60)地址中取值,放入eax。*p

movl (%eax), %eax

movl %eax, 4(%esp) ; printf参数2, eax(即*p)

movl $LC0, (%esp) ; printf参数1, "%d\12\0"

call _printf ; 调用printf

movl 60(%esp), %eax ; 从(esp+60)地址中取值,放入ebx(即*p)

movl (%eax), %ebx

movl 60(%esp), %eax ; 把(esp+60)的值放入eax

leal 4(%eax), %edx ; eax中记录的地址+4的值,放入edx(即*(++p))

movl %edx, 60(%esp) ; 把edx的值,放入(esp+60)

movl (%eax), %ecx ; 从eax记录的原(esp+60)地址中的值,放入ecx(即*p)

movl 60(%esp), %eax ; 从(esp+60)地址中取值,放入edx

movl (%eax), %edx

addl $4, 60(%esp) ; (esp+60)的值+4,放入eax(即eax=*(p+2))

movl 60(%esp), %eax ; 从(esp+60)地址中取值,+4后的地址放入esi

leal 4(%eax), %esi

movl %esi, 60(%esp) ; 把esi的值,放入(esp+60),

movl (%eax), %eax ; eax = *eax

movl %ebx, 16(%esp) ; printf参数5, %ebx(即*p)

movl %ecx, 12(%esp) ; printf参数4, %ecx(即*p)

movl %edx, 8(%esp) ; printf参数3, %edx(即*(++p))

movl %eax, 4(%esp) ; printf参数2, %eax(即*(p+2))

movl $LC1, (%esp) ; printf参数1, "%d %d %d %d\12\0"

call _printf

call ___getreent

movl 4(%eax), %eax ; 把*(eax+4)的放入*esp

movl %eax, (%esp)

call _getc

movl $0, %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

题外话:

结果中出现的2和3还可以说的通。

4很奇怪,非要勉强地解释的话,*(++p)++括号外面的++也对p起作用了,

但是形如p++运算符,应该在语句结束后才自增的,所以这样解释明显不对。

我在Cygwin + gcc (GCC) 5.4.0环境,运行的结果如下,没有出现4。

1

3 2 1 1

请问题主用了什么环境?如果有汇编代码的话,贴出来可以一起分析下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值