关于捉虫大赛的蛋疼想法

捉虫大赛,顾名思义就是找bug,找啊找啊找bug。奋斗做题过程比较蛋疼,没带书什么的又不让上网。

A 今夕是何年

unsigned char year[]="\xB8\x12\x20\x00\x00\xC3";
int main(int argc, char* argv[])
{
    printf("%x\n", (int(*)())&year());
    return 0;
}

这个直接就是,字符串指针转换函数指针然后执行,错在少加一对括号。

unsigned char year[]="\xB8\x12\x20\x00\x00\xC3";
int main(int argc, char* argv[])
{
    printf("%x\n", ((int(*)())&year)());
    return 0;
}

B 数组的节操

#include <stdio.h>
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))

int main()
{
    int d = -1;
    int x;
    int array[10];

    array[0] = 1;
    array[1] = 2;
    if (d <= TOTAL_ELEMENTS - 2)
        x = array[d+1];

    printf("%i\n",x);
    return 0;
}
这题弱弱的跪了,后来一问,大家都会做,原因是sizeof返回的是一个无符号整形,和-1比较的时候,会把-1转换成无符号型的一个很大的数,导致结果错误。

这个···谁知道嘛,出题者太阴险了。

C 数组数组快显灵

#include <iostream>
using namespace std;
void a()
{
         volatile int array[10];
         for (int i= 0; i<10; i++)
                array[i] = i;
}
void b()
{
          int array[10];
          for (int i=0; i<10; i++)
                cout<<array[i]<<endl;
}
int main()
{
     a();
     b();
}
这题比较牛逼,volatile这个修饰符是确保变量不会变编译优化,每次读取强制读取内存中的值,多线程的时候用得较多,不过这题还是会因为编译器不同而产生不同结果,

原因是c的内部变量,存储在堆栈中不会自动释放内存,函数b的数组堆栈空间,有可能与函数a的数组空间,有一部分吻合。

D 二进制转换器

#include <iostream>
using namespace std
int main()
{  

    short int number = 43690;//二进制形式为:1010101010101010
    short int temp = 1 << 16;

    for (int i = 0;i <= 16;i++)
    {
        if (number && temp)
            cout << "1";
        else
            cout << "0";
        temp >> 1;
    }
    return 0;
}
这题主要考一下位运算,问题也比较多,重要的一个问题是,做右移处理的时候左边最高一位以符号位补全,所以只有符号位的时候,做右移操作会在左边最高位得到两个一

类似这样   100000000000 >> 1 == 11000000000000

#include <iostream>
using namespace std;
int main()
{
    unsigned short int number = 43690;//二进制形式为:1010101010101010
    unsigned short int temp = 1 << 15;
    for (int i = 0;i < 16;i++)
    {
        if (number & temp)
            cout << "1";
        else
            cout << "0";
        temp >>= 1;
    }
return 0;
}

E 疯狂的支票本

#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;

class check_info {
public:
    string date; // Date the check was written
    string what;// What the entry is about
    float amount; // Amount of check or deposit
public:
    check_info():
        date(""),
        what("")
    {};
public:
    void read();    
};
// The STL vector to hold the check data
typedef std::vector<check_info> check_vector;


void check_info::read()
{
    cin >> date;
    cin >> what;
    cin >> amount;
}

int main()
{

    // Checkbook to test
    check_vector checkbook;
    while (1) {
        check_info next_info; // Current check
        next_info.read();
        checkbook.push_back(next_info);
        if (cin.eof())
            break;
    }

    float total = 0.00; // Total in the bank
    for (check_vector::iterator
         cur_check = checkbook.begin();
         cur_check != checkbook.end();
         cur_check++)
    {
        total += cur_check->amount;
    }

    cout << "Total:"  << setiosflags(ios::fixed) << setprecision(2) << total << endl;
    return (0);

}
这个题也给跪了,问题出在数据结束时会有一个\n在吧\n读完后,cin.eof()的值才会为true,所以会多读入一次数据。

还有就是,浮点数的精度问题,这个比较坑爹,这个问题教育了我们,浮点数在任何情况下都是有误差的(两位有效数字也有),特别是在运算过程比较多的情况下,整形在任何情况下都是没误差的,用高精度或者是整形代替浮点数运算,可以消除这种误差。

#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;
class check_info {
public:
    string date; // Date the check was written
    string what;// What the entry is about
    unsigned long long amount; // Amount of check or deposit
public:
    check_info():
        date(""),
        what(""),
        amount(0)
    {};
public:
    void read();
};
// The STL vector to hold the check data
typedef std::vector<check_info> check_vector;
void check_info::read()
{
    unsigned long long temp;
    
cin >> date >> what >> temp;
    amount = temp * 100;
    cin.get();
cin >> temp;
    amount += temp;

F 数据hold不住

/************************************************
* test the data_holder class.                   *
************************************************/
#include <iostream>
/************************************************
* data_holder -- A class to hold a single       *
* integer                                       *
* Note: By default the value of the data is 5.  *
* Warning: More member functions need to be     *
* added to this to make it useful.              *
************************************************/
class data_holder
{
private:
    int data; // Data to store
public:
    // Constructor -- Set value to default (5)
    data_holder(void):data(5) {};
    // Destructor defaults
    //
    // Copy constructor
    data_holder(const data_holder &old)
    {
        *this = old;
    }

    // Assignment operator
    data_holder operator = (
        data_holder old_data_holder)
    {
        data = old_data_holder.data;
        return (*this);
    }

    // Get the data item
    int get(void)
    {
        return (data);
    }
};

int main()
{
    // A data holder
    data_holder var1;
    // Copy of a data holder
    data_holder var2(var1);
    return (0);
}

这题的错误在于函数不断递归调用,直到程序堆栈溢出。

原因是重载操作符时,调用了一个值参变量,这种调用方法会生成一个新的拷贝,并调用初始化函数,但是程序中重载的初始化函数又调用了重载的操作符,所以会产生

无限递归调用。只要把传参的方式改成传递地址就可以了。

data_holder &operator=(
    const data_holder &old_data_holder)

G 谁动了我的内核

void * memcpy (void * dst, const void * src, size_t count)
{
         void * ret = dst;
         while (count--) {
                 *(char *)dst = *(char *)src;
                 dst = (char *)dst + 1;
                 src = (char *)src + 1;
         }
         return(ret);
}

#define BBSIZE 1024
char kbuf[BBSIZE];

int copy_from_kernel(void *user_dest, int maxlen)
{
   int len = BBSIZE < maxlen ? BBSIZE : maxlen;
   memcpy(user_dest, kbuf, len);
   return len;
}

这题也是无符号型和有符号型的问题,吧有符号负数赋给无符号型,会产生一个很大的数。


H URL解码器

/**********************************************************
 * urldecode.c
 * decode url code
 * change %** to ASCII and print other characters
***********************************************************/
#include <stdio.h>

int main()
{
    // n - encoded hexadecimal char
    // c - current reading char
    int n;
    char c;
    while(1)
    {
        // read the character.
        scanf("%c",&c);
        if(c=='%')
        {
            // decode the hex value.
            // use "%x" format to read the value directly.
            if(scanf("%x",&n))
                printf("%c",(char)n);
            else
                printf("\nInvalid code!\n");
        }
        else
            // is other character. print it.
            printf("%c",c);
    }
    return 0;
}

这个题也很蛋疼,我又跪了,需要判断文件末尾,题目描述也不算很清楚,不多说了。

/**********************************************************
* urldecode.c
* decode url code
* change %** to ASCII and print other characters
***********************************************************/
#include <stdio.h>
int check(int *n)
{
    if((*n)>='0' && (*n)<='9')(*n)-='0';
    else if((*n)>='a' && (*n)<='f')(*n)-=('a'-10);
    else if((*n)>='A' && (*n)<='F')(*n)-=('A'-10);
    else
{
        printf("\nInvalid code!\n%c",*n);
        return 1;
    }
return 0;
}
int main()
{
    // n - encoded hexadecimal char
    // c - current reading char
    char c;    int n,x;
    while(scanf("%c",&c)!=EOF)
    {
        if(c=='%')
        {
            // decode the hex value.
// read the first
if((n=getchar())==EOF)
            {
                printf("\nInvalid code!\n");
                break;
            }
if(check(&n))continue;
            x=n<<4;
            // read the second
if((n=getchar())==EOF)
            {
                x>>=4;
                printf("%c",x);
                break;
            }
if(check(&n))continue;
            x|=n;
            printf("%c",x);
        }
else
            // is other character. print it.
printf("%c",c);
    }
return 0;
}

I 艺术就是消失

#include <stdlib.h>
#include <iostream>
#include <cstring>

/************************************************
* info -- A class to hold information.          *
*                                               *
* Note:                                         *
* Because someone is walking all over our       *
* memory and destroying our data, we            *
* have put two guards at the beginning          *
* and end of our class. If someone              *
* messes with us these numbers will             *
* be destroyed.                                 *
*                                               *
* Member functions:                             *
* set_data -- Store a string in our data.       *
* get_data -- Get the data string.              *
* check_magic -- Check the magic numbers.       *
************************************************/
// Magic numbers for the start and end of the
// data in the class info
const int START_MAGIC = 0x11223344;
const int END_MAGIC = 0x5567788;
class info
{
private:
// Magic protection constant
    const int start_magic;

// String to be stored
    char data[30];

// Magic protection constant
    const int end_magic;
public:
    info(void):
        start_magic(START_MAGIC),
        end_magic(END_MAGIC)
    {}

// Copy constructor defaults
// Assignment operator defaults
// Destructor defaults

// Store some data in the class
    void set_data(
// Data to be stored
        const char what[]
    )
    {
        strcpy(data, what);
    }

// Get the data from the class
    char *get_data(void)
    {
        return (data);
    }

// Verify that the magic
// numbers are correct
    void check_magic(void)
    {
        if ((start_magic != START_MAGIC) ||
                (end_magic != END_MAGIC))
        {
            std::cout <<
                      "Info has lost its magic\n";
        }
    }
};

/************************************************
* new_info -- Create a new version of the       *
* info class.                                   *
************************************************/
struct info *new_info(void)
{
    struct info *result; // Newly created result.

    result = (struct info *)
             malloc(sizeof(struct info));

// Make sure the structure is clear
    memset(result, '\0', sizeof(result));

    return (result);
}
int main()
{
// An info class to play with
    class info *a_info = new_info();

    a_info->set_data("Data");
    a_info->check_magic();
    return (0);
}

这道题不知道出题者要搞啥,提供了一种用malloc为类分配内存空间的方法.

接法是在return之前加上

new(result) info;
最后说一下,在c++中class和struct极其相像,转来转去应该没啥问题。


J 学长的困惑

蛋疼题,不说了





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值