我在C aptitude论文中发现了这个难题.
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
}
int main()
{
int i = 5;
change();
i = 10;
printf("%d", i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
任何解决方案.?
小智 27
限定?
#include <stdio.h>
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
#define printf_ printf
#define printf(a, b) printf_("5");
}
int main()
{
int i = 5;
change();
i = 10;
printf("%d", i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
小智 27
这是一个POSIX答案,真正做到了问题的问题:)
它不适用于某些架构/编译器,但它确实在这里.
#include <stdio.h>
void
change () {
void _change();
_change();
}
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
void
_change()
{
int main();
uintptr_t m=(uintptr_t)main;
uintptr_t ps=sysconf(_SC_PAGESIZE);
m/=ps;
m*=ps;
mprotect((void*)m,ps,PROT_READ|PROT_WRITE|PROT_EXEC);
char *s=(char*)(intptr_t)main;
s=memchr(s,10,ps);
*s=5;
mprotect((void*)m,ps,PROT_READ|PROT_EXEC);
}
int
main() {
int i=5;
change();
i=10;
printf ("%d\n",i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:这应该使抵制标题的人更健壮.
Lau*_*ves 25
void change()
{
//write something in this function so that output of printf in main function
//should always give 5.you can't change the main function
#define i a=5,b
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*ung 21
这是一个非常便宜的答案:
void
change()
{
printf("%d", 5);
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
:-P
moo*_*dow 20
这是另一种可能性:
void change()
{
char const *literal = "%d";
char * ptr = (char*)literal;
ptr[0] = '5';
ptr[1] = 0;
}
Run Code Online (Sandbox Code Playgroud)
这比更改返回地址要便携得多,但要求你(a)有一个汇编字符串文字的编译器(大多数都这样做),(b)有一个不将常量放在只读部分的编译器,或者在没有MMU的架构上运行(这些天不太可能).
有人想过使用atexit吗?
void change (void)
{
static int i = 0;
if (i == 0) atexit (change);
if (i == 1) printf ("\r5 \b\n");
++i;
}
请注意,main函数中没有终止换行符,如果我们向stdout发送2个退格符,则10将被删除,并且只打印5个.
调用必需的#include,并用括号 - 不平衡文本替换注释:
}
int printf(const char *s, ...) {
return fprintf(stdout,"%d",5);
测试成功.感谢dreamlax和Chris Lutz的错误修正.
堆栈中有一个局部变量i,其值为5.
使用change(),您需要将下一条指令修改为5,因此您需要将覆盖缓冲区设置为设置为10的位置,并将其设置为5.
该printf("%d", i);呼叫main()没有结束它在一个换行符输出,程序的行为是实现定义的.
我断言,在我的实现中,一个无法为最后一行写一个终止换行的程序总是打印5后跟换行作为最后一行.
因此,无论定义如何,输出总是为5 change().:-)
(换句话说,这些问题的重点是什么,除非它们意味着在特定的硬件,编译器等上运行?)