通过使用指向第一个参数的指针迭代函数的参数

我想知道以下C代码是否符合C99和/或C11标准:
void foo(int bar0,int bar1,int bar2) {
    int *bars = &bar0;

    printf("0: %d\n1: %d\n2: %d\n",bars[0],bars[1],bars[2]);
}

int main(int argc,char **argv) {
    foo(8,32,4);

    return 0;
}

在使用visual studio 2013并打印时,此代码段按预期编译和运行:

0: 8
1: 32
2: 4

解决方法

不,不在附近.

C标准不保证函数参数存储在连续的内存位置(或者,任何特定的顺序,就此而言).由编译器和/或平台(体系结构)决定如何将函数参数传递给函数.

为了进一步增加清晰度,甚至不能保证将要传递的参数存储在存储器(例如,堆栈)中.对于部分或全部参数,他们也可以使用硬件寄存器(适用时),以便快速进行操作.例如,

> PowerPC

The PowerPC architecture has a large number of registers so most functions can pass all arguments in registers for single level calls. […]

> MIPS

The most commonly used calling convention for 32 bit MIPS is the O32 ABI which passes the first four arguments to a function in the registers $a0$a3; subsequent arguments are passed on the stack. […]

> X86

The x86 architecture is used with many different calling conventions. Due to the small number of architectural registers,the x86 calling conventions mostly pass arguments on the stack,while the return value (or a pointer to it) is passed in a register.

等等.检查full wiki article here.

因此,在您的情况下,bars [0]是一个有效的访问,但bar [1]和bars [2]是否有效,完全取决于底层环境(平台/编译器).最好不要依赖你期望的行为.

也就是说,如果你不打算使用传递给main()的参数(如果有的话),你可以简单地将签名减少到int main(void){.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...