最近在浏览一些C ++博客时,我在其中一个博客中遇到了一个小型的预告片。
#include<stdio.h>
int find_addr()
{
/*fill your code here*/
}
int main()
{
int i,j;
clrscr();
find_addr();
return 0;
}
问题是找到变量i&amp;的地址。 j没有触及主要功能。我还没弄清楚。感觉很糟糕,我甚至无法解决这个小问题:((。
编辑:
上面的程序有很多非标准语句,比如使用包含conio.h和其他非标准头文件及其函数,getch()和其他语句,我匆忙编辑它,忘了省略void void main(),为此道歉。
EDIT2:由于我通过此处发布的回复认为存在与该问题相关的非标准问题,因此我已经投了一票来关闭此帖子。
答案 0 :(得分:6)
我想我找到了where you read the puzzles。大多数程序使用无类型main()
,或者更糟,void main()
。它们假定了很多系统和/或编译器特定的东西。页面上的程序质量不是很好,并且是一个糟糕的教程。请远离它。
例如,这是第一个程序:
main()
{
int i = 300;
char *ptr = &i;
*++ptr = 2;
printf("%d",i);
getch();
}
第三项计划:
void main()
{
int num[] = {10,11,12,13};
printf("%u %u",num,&num);
}
我可以继续,但真的没有必要。正如我所说,远离这个页面!
答案 1 :(得分:5)
我认为它可能如下所示,但它不符合规定,你不应该在实践中使用它。
int find_addr()
{
int t;
int* i_addr = &t - <some platform&compiler&whatever specific constant>;
int* j_addr = &t - <some platform&compiler&whatever specific constant>;
}
这个想法是i
和j
放在堆栈上,你可以通过在堆栈上使用另一个变量的地址来找到堆栈的地址。
您应该注意,有时无法找到i
和j
的地址,因为编译器不会因为优化而为它们分配内存。这再一次证实了你不应该尝试编写这样的代码。
答案 2 :(得分:1)
在Windows上,可以使用_AddressOfReturnAddress
内在函数来完成。此函数为您提供包含返回地址的堆栈上的地址。 i,j
的地址将是该地址的常数负偏移量。
请注意,任何此类“解决方案”都是高度不可移植的,并且在许多情况下可能会失败。一个这样的情况是,如果编译器由于某种原因决定生成i和j寄存器。编译器可能决定这样做,因为你从未明确地获取i或j的地址,因此就其而言,它是安全的。在这种情况下,i,j实际上没有地址,因此你将获得堆栈中其他东西的地址,并且在其上写入很可能会使程序崩溃。
答案 3 :(得分:0)
我发现这适用于VC编译器..
函数名在堆栈中占用2个int32,然后是a的定义。
int find_addr()
{
int a;
printf("&a = %u &i = %u & j = %u\n", &a, &a+4, &a+3);
}