C 函数入参地址 为何都相同?

时间:2022-06-26 21:09:30
//  假设:栈向下增长
C 函数入参地址,  应按照入栈顺序(自右至左/自左至右)依次递增/减, 
而如下代码的运行结果显示,入参地址相同,令人匪夷所思?
求解释!!

#include <stdio.h>
#include <stdarg.h>

void vaParamFun(int i, ...)
{
    long double ld = 1.0; // don't be 0.0
    va_list ap;
    va_start(ap, i);
    while (ld != 0.0)
    {
        printf("%p    ", ap);
        ld = va_arg(ap, long double);
        printf("%Lf\n", ld);
    }
    va_end(ap);
}

int main ()
{
    vaParamFun(0, (long double)1, (long double)2, (long double)3, (long double)4, (long double)0);

    return 0;
}



运行结果

0x7fffd3c83d90    1.000000
0x7fffd3c83d90    2.000000
0x7fffd3c83d90    3.000000
0x7fffd3c83d90    4.000000
0x7fffd3c83d90    0.000000

10 个解决方案

#1


计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

#2


引用 1 楼 zhao4zhong1 的回复:
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
C 函数入参地址 为何都相同?

#3


ap不会依次指向每个参数的地址,而是始终指向起始变参的起始地址吧。

#4


引用 3 楼 baipv008 的回复:
ap不会依次指向每个参数的地址,而是始终指向起始变参的起始地址吧。


求解释, 这个va_list 的实现细节 是怎样的?

#5


 va_list ap未必是一个地址, 所以不能%p

#6


http://codepad.org/3S7X0Bcz

#7


这 是否说明  不同平台对va_list相关内容  有不同的实现?

#8


引用 5 楼 mujiok2003 的回复:
 va_list ap未必是一个地址, 所以不能%p


这 是否说明  不同平台对va_list相关内容  有不同的实现?

#9


引用 8 楼 leslietuang 的回复:
Quote: 引用 5 楼 mujiok2003 的回复:

 va_list ap未必是一个地址, 所以不能%p


这 是否说明  不同平台对va_list相关内容  有不同的实现?


肯定

#10


mark一下,下班在看

#1


计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

#2


引用 1 楼 zhao4zhong1 的回复:
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
C 函数入参地址 为何都相同?

#3


ap不会依次指向每个参数的地址,而是始终指向起始变参的起始地址吧。

#4


引用 3 楼 baipv008 的回复:
ap不会依次指向每个参数的地址,而是始终指向起始变参的起始地址吧。


求解释, 这个va_list 的实现细节 是怎样的?

#5


 va_list ap未必是一个地址, 所以不能%p

#6


http://codepad.org/3S7X0Bcz

#7


这 是否说明  不同平台对va_list相关内容  有不同的实现?

#8


引用 5 楼 mujiok2003 的回复:
 va_list ap未必是一个地址, 所以不能%p


这 是否说明  不同平台对va_list相关内容  有不同的实现?

#9


引用 8 楼 leslietuang 的回复:
Quote: 引用 5 楼 mujiok2003 的回复:

 va_list ap未必是一个地址, 所以不能%p


这 是否说明  不同平台对va_list相关内容  有不同的实现?


肯定

#10


mark一下,下班在看