在 C 中使用省略号传递参数 [英] Parameter passing with ellipsis in C
问题描述
我需要在 C 中实现我自己的 printf 函数.但是我在将省略号 ("...") 功能与我的函数一起使用时遇到了问题(我们需要使用省略号).
I need to implement my own printf function in C. However I am having trouble using the ellipsis ("...") feature with my function (we are required to use ellipsis).
根据我的教科书,传递给带有省略号的函数的参数应该位于存储第一个参数的堆栈正上方.但是,我在堆栈上的任何地方都找不到我传递的任何附加参数!这是我用来测试我的函数和输出的一些代码:
According to my textbook, the parameters passed to a function with an ellipsis should be located on the stack right above where the first parameter is stored. I can not find any of the the additional parameters I am passing anywhere on the stack though! Here is some code I used to test my function and the output:
#include<stdio.h>
#include<stdlib.h>
int myprintf(char *str, ...)
{
//test code to view data around str on the stack:
int i;
for (i = -8; i <= 8; i++)
{
char *ptr = str + (i * 4); // ptr will iterate through the 8 bytes above and
// below str[0] on the stack
printf ("Bytes from str: %+03d \t
Ptr Addr: %x \t
Val int: %d \t
Val char: %c \n",
(i*4), ptr, *ptr, *ptr);
}
//my implementation of printf...
}
int main(void)
{
myprintf("test string", 1111, 2222, 3333);
}
这是 myprintf 函数的输出(堆栈的打印输出):
Here is the output of the myprintf function (a printout of the stack):
Bytes from str: -32 Ptr Addr: 8048922 Val int: 48 Val char: 0
Bytes from str: -28 Ptr Addr: 8048926 Val int: 97 Val char: a
Bytes from str: -24 Ptr Addr: 804892a Val int: 104 Val char: h
Bytes from str: -20 Ptr Addr: 804892e Val int: 32 Val char:
Bytes from str: -16 Ptr Addr: 8048932 Val int: 0 Val char:
Bytes from str: -12 Ptr Addr: 8048936 Val int: 118 Val char: v
Bytes from str: -08 Ptr Addr: 804893a Val int: 93 Val char: ]
Bytes from str: -04 Ptr Addr: 804893e Val int: 37 Val char: % <- my other variables should be here and above
Bytes from str: +00 Ptr Addr: 8048942 Val int: 116 Val char: t <-"test string"
Bytes from str: +04 Ptr Addr: 8048946 Val int: 32 Val char: <-" string"
Bytes from str: +08 Ptr Addr: 804894a Val int: 105 Val char: i <-"ing"
Bytes from str: +12 Ptr Addr: 804894e Val int: 0 Val char:
Bytes from str: +16 Ptr Addr: 8048952 Val int: 3 Val char:
Bytes from str: +20 Ptr Addr: 8048956 Val int: 0 Val char:
Bytes from str: +24 Ptr Addr: 804895a Val int: 0 Val char:
Bytes from str: +28 Ptr Addr: 804895e Val int: -1 Val char: �
Bytes from str: +32 Ptr Addr: 8048962 Val int: 0 Val char:
据我所知,值 1111、2222 和 3333 应该位于此堆栈打印输出中的某个位置.当我进行函数调用时,这些值会去哪里?
From what I understand, the values 1111, 2222, and 3333 should be located somewhere in this stack printout. Where are these values going when I make the function call?
我无法在我的实现中使用stdarg.h"库.
I cannot use the "stdarg.h" library in my implementation.
推荐答案
这个程序的行为可能不被规范所允许,但是对于这个从堆栈中搜索参数的实验,你必须移动指针指向 参数而不是指针 作为 参数传递.
Behavior of this program may not granteed by the specification, but for this experiment of searching argument from the stack, you have to move the pointer pointing at the argument instead of the pointer passed as the argument.
#include<stdio.h>
#include<stdlib.h>
int myprintf(char *str, ...)
{
//test code to view data around str on the stack:
int i;
for (i = -8; i <= 8; i++)
{
/* add & before str to get the address of the argument */
char *ptr = (char*)&str + (i * 4); // ptr will iterate through the 4 * 8 bytes above and
// below str on the stack
printf ("Bytes from str: %+03d \t"
"Ptr Addr: %p \t"
"Val int: %d \t"
"Val char: %02X \n",
(i*4), (void*)ptr, *(int*)ptr, (unsigned int)(unsigned char)*ptr);
}
//my implementation of printf...
return 0;
}
int main(void)
{
myprintf("test string", 1111, 2222, 3333);
return 0;
}
在我的本地环境中的结果:
Result in my local environment:
Bytes from str: -32 Ptr Addr: 0028FF10 Val int: 213 Val char: D5
Bytes from str: -28 Ptr Addr: 0028FF14 Val int: 1662423109 Val char: 45
Bytes from str: -24 Ptr Addr: 0028FF18 Val int: -2 Val char: FE
Bytes from str: -20 Ptr Addr: 0028FF1C Val int: 1972834658 Val char: 62
Bytes from str: -16 Ptr Addr: 0028FF20 Val int: 2130567168 Val char: 00
Bytes from str: -12 Ptr Addr: 0028FF24 Val int: 0 Val char: 00
Bytes from str: -08 Ptr Addr: 0028FF28 Val int: 0 Val char: 00
Bytes from str: -04 Ptr Addr: 0028FF2C Val int: 4227938 Val char: 62
Bytes from str: +00 Ptr Addr: 0028FF30 Val int: 4235431 Val char: A7
Bytes from str: +04 Ptr Addr: 0028FF34 Val int: 1111 Val char: 57
Bytes from str: +08 Ptr Addr: 0028FF38 Val int: 2222 Val char: AE
Bytes from str: +12 Ptr Addr: 0028FF3C Val int: 3333 Val char: 05
Bytes from str: +16 Ptr Addr: 0028FF40 Val int: 0 Val char: 00
Bytes from str: +20 Ptr Addr: 0028FF44 Val int: 0 Val char: 00
Bytes from str: +24 Ptr Addr: 0028FF48 Val int: 2686824 Val char: 68
Bytes from str: +28 Ptr Addr: 0028FF4C Val int: 4198992 Val char: 50
Bytes from str: +32 Ptr Addr: 0028FF50 Val int: 1 Val char: 01
正如@Joe 所说,使用 va_*
宏来读取可变数字参数.否则,该程序可能无法在某些环境中运行——例如,x86_64,其中参数在寄存器上传递,而不是在堆栈上.
As @Joe says, use va_*
macro to read variable number arguments.
Otherwise, the program may not work in some environment -- for example, x86_64 where arguments are passed on register, not on the stack.
我做了一些修改
- 扩大搜索范围
- 打印传递的字符串地址
并在 Wandbox 上运行代码.
and ran the code on Wandbox.
结果变成了这样:
Bytes from str: -64 Ptr Addr: 0x7fff2308b498 Val int: -1473084125 Val char: 23
Bytes from str: -60 Ptr Addr: 0x7fff2308b49c Val int: 0 Val char: 00
Bytes from str: -56 Ptr Addr: 0x7fff2308b4a0 Val int: 4196088 Val char: F8
Bytes from str: -52 Ptr Addr: 0x7fff2308b4a4 Val int: 0 Val char: 00
Bytes from str: -48 Ptr Addr: 0x7fff2308b4a8 Val int: 35 Val char: 23
Bytes from str: -44 Ptr Addr: 0x7fff2308b4ac Val int: 0 Val char: 00
Bytes from str: -40 Ptr Addr: 0x7fff2308b4b0 Val int: -1473063104 Val char: 40
Bytes from str: -36 Ptr Addr: 0x7fff2308b4b4 Val int: 32682 Val char: AA
Bytes from str: -32 Ptr Addr: 0x7fff2308b4b8 Val int: -1470881080 Val char: C8
Bytes from str: -28 Ptr Addr: 0x7fff2308b4bc Val int: 32682 Val char: AA
Bytes from str: -24 Ptr Addr: 0x7fff2308b4c0 Val int: 0 Val char: 00
Bytes from str: -20 Ptr Addr: 0x7fff2308b4c4 Val int: 0 Val char: 00
Bytes from str: -16 Ptr Addr: 0x7fff2308b4c8 Val int: 4195810 Val char: E2
Bytes from str: -12 Ptr Addr: 0x7fff2308b4cc Val int: 0 Val char: 00
Bytes from str: -08 Ptr Addr: 0x7fff2308b4d0 Val int: 0 Val char: 00
Bytes from str: -04 Ptr Addr: 0x7fff2308b4d4 Val int: 0 Val char: 00
Bytes from str: +00 Ptr Addr: 0x7fff2308b4d8 Val int: 4196155 Val char: 3B
Bytes from str: +04 Ptr Addr: 0x7fff2308b4dc Val int: 0 Val char: 00
Bytes from str: +08 Ptr Addr: 0x7fff2308b4e0 Val int: 587773152 Val char: E0
Bytes from str: +12 Ptr Addr: 0x7fff2308b4e4 Val int: 32767 Val char: FF
Bytes from str: +16 Ptr Addr: 0x7fff2308b4e8 Val int: -1477724000 Val char: A0
Bytes from str: +20 Ptr Addr: 0x7fff2308b4ec Val int: 5 Val char: 05
Bytes from str: +24 Ptr Addr: 0x7fff2308b4f0 Val int: -1475311104 Val char: 00
Bytes from str: +28 Ptr Addr: 0x7fff2308b4f4 Val int: 32682 Val char: AA
Bytes from str: +32 Ptr Addr: 0x7fff2308b4f8 Val int: 1111 Val char: 57
Bytes from str: +36 Ptr Addr: 0x7fff2308b4fc Val int: 0 Val char: 00
Bytes from str: +40 Ptr Addr: 0x7fff2308b500 Val int: 2222 Val char: AE
Bytes from str: +44 Ptr Addr: 0x7fff2308b504 Val int: 0 Val char: 00
Bytes from str: +48 Ptr Addr: 0x7fff2308b508 Val int: 3333 Val char: 05
Bytes from str: +52 Ptr Addr: 0x7fff2308b50c Val int: 0 Val char: 00
Bytes from str: +56 Ptr Addr: 0x7fff2308b510 Val int: 4196064 Val char: E0
Bytes from str: +60 Ptr Addr: 0x7fff2308b514 Val int: 0 Val char: 00
Bytes from str: +64 Ptr Addr: 0x7fff2308b518 Val int: -1473063104 Val char: 40
pointer passed = 4196155 0x40073b
如您所见,值作为 Bytes from str: +00
上的指针传递,但其他参数的值不接近该值.
As you see, the valued passed as pointer on Bytes from str: +00
, but value of the other arguments are not near the value.
这篇关于在 C 中使用省略号传递参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!