首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

一路笔试题。求答案

2013-11-06 
一道笔试题。。求答案给一个函数:void fun(void){}int main(){int x 1int y 2fun()printf(x,y%d %d\

一道笔试题。。求答案
给一个函数:

void fun(void)

{

}

int main()

{

    int x = 1;

    int y = 2;

    fun();

    printf("x,y%d %d\n",x,y);

}

问,如何实现函数fun,使得最后的打印结果不是1 2
[解决办法]


// 这个算不算?!
#include <stdlib.h>
#include <stdio.h>

void fun(void)

{
    int x = 10, y = 20; 
    printf("x,y%d %d\n",x,y);
    exit(0);
}

int main()

{
    int x = 1;
    int y = 2;
    fun();
    printf("x,y%d %d\n",x,y);

}

[解决办法]
我觉得这道题是想改内存吧,
在vs的Release模式下,你在fun中申请另外2个局部变量,
这个局部变量的地址和x,y的地址是连续的,这样就可以改内存了.

但是在vs的debug模式和Linux下都不是连续的...
[解决办法]
这种题目需要对Window的栈比较了解. 我对Windows的栈不太懂, 但是要实现该目标肯定要修改栈, 也就是手动做栈溢出. 以下代码在VS2008 debug下可以实现, 因为Release下会根据代码做各种优化, 我没找出压栈的规律(因为func太短,还涉及到内联).
#include <iostream>
using namespace std;

void func()
{
    int a[1] = {0};

    *(int*)((char*)&a[0] + 0xec) = 100;
    *(int*)((char*)&a[0] + 0xe0) = 200;
}

int main()
{
    int x = 1;
    int y = 2;

    func();

    cout << "x = " << x << endl;
    cout << "y = " << y << endl;

    system("pause");
    return 0;
}


其实就像楼上说的, 这种题目意义不大, 最多就是考察下是否了解函数压栈.
[解决办法]
利用数组越界来修改相邻内存区域内所保存的值,
考的就是栈的知识。
[解决办法]
#include <stdio.h>

#pragma pack(push)

int fun(void)
{
        int a=0;
        int *p;
        p=&a;
        while(*p!=1)
        {
         p++;
        }
        *p=10;
}

int main()
{
        int x=1;
        int y=2;
        fun();
        printf("%d %d\n",x,y);
}

#pragma pack(pop)
遍历下就可以吧
[解决办法]
开阔思路的题吧,除了前面说到的结束进程、堆栈溢出方法外,我再给一个:
int fun(void)
{
#define printf
}

[解决办法]
引用:
Quote: 引用:

Quote: 引用:

#include <stdio.h>

#pragma pack(push)

int fun(void)
{
        int a=0;
        int *p;
        p=&a;
        while(*p!=1)
        {
         p++;
        }
        *p=10;
}

int main()
{
        int x=1;
        int y=2;
        fun();
        printf("%d %d\n",x,y);
}

#pragma pack(pop)
遍历下就可以吧


运行确实是可以的,但是,,能不能解释下代码?
你可以把所有的地址都打印出来看看。。这个很好理解
因为编译程序会把 变量,程序代码 分开放在不同的节区
当然也有先后的排列顺序
所以从排在"前面的"变量的地址指针开始往后找... 


[解决办法]
引用:
Quote: 引用:

准确点说
void fun(void)
{
        int a=0;


        int *p=&a;
        while(1)
        {
           if((*p==1)&&(*(p-1)==2)) break;
           p++;
        }
        *p=88;       //x的地址
*(p-1)=99;   //y的地址
}


怎么可以确定p++一定能取到x的地址?局部变量有没有可能按照地址从小到大的顺序存储?


你分配的变量都是要压栈的,说白了就是一块内存,定义变量的时候就保存一个数据,连续的
如果*p==1并且*(p-1)==2,几本可以确定p就对准了x,p-1就对准了y

因为x,y先分配,处于栈的靠底一端,而a后分配,处于靠栈顶一端
所以用a的地址来找x的地址,要用++

确定了p对准x,p-1对准y后
直接通过对*p和*(p-1)赋值,就可以改变x,y的值,所以,输出自然就变了

热点排行