理解C ++程序中的代码

时间:2013-02-11 13:57:44

标签: c++

我试图从编码网站解决方案中理解代码但却无法弄清楚很多东西。我能理解BIT和fenwick部分,但无论我无法理解,我都在下面写下:
这段代码的来源是 http://www.codechef.com/viewsolution/1816336
如果有人解释了这些概念,而不是使用标准定义的输入输出函数,为什么我们倾向于使用这些概念,这将是非常有用的:

char ioSpace[500000 * 17 + 128];
unsigned popcnt(unsigned x)
{
    #ifndef ONLINE_JUDGE
    return __builtin_popcount(x);
    #else
    unsigned ret;
    asm("popcntl %1, %0;":"=r"(ret) :"r"(x));
    return ret;
    #endif
}

unsigned readUInt(char*& readPos)
{
    unsigned num = 0;
    unsigned c;
    while ((c = *readPos++) >= '0')
    num = num * 10 + (c - '0');
    return num;
}

template<unsigned D>
void writeDigit(char*& writePos, unsigned& advance, unsigned& num)
{
    unsigned digit = num / D;
    num %= D;
    if (digit)
    advance = 1;
    *writePos = digit + '0';
    writePos += advance;
}

void writeUInt(char*& writePos, unsigned num)
{
    unsigned advance = 0;
    writeDigit<100000>(writePos, advance, num);
    writeDigit<10000>(writePos, advance, num);
    writeDigit<1000>(writePos, advance, num);
    writeDigit<100>(writePos, advance, num);
    writeDigit<10>(writePos, advance, num);
    advance = 1; // for zero number
    writeDigit<1>(writePos, advance, num);
    *writePos++ = '\n';
}

然后在主输入功能中:

    read(STDIN_FILENO, ioSpace, sizeof(ioSpace));

有人可以向我解释整个过程,因为我一直在尝试将这些样式合并到我的C ++编程中,并且由于缺乏理解而不可避免地会这样做。

2 个答案:

答案 0 :(得分:1)

首先,我没有看到任何证据表明此代码是一个值得学习的优秀范例。完全没有任何评论本身就让我不信任代码。你没有说你在这个代码中的位置,如果你真的想要了解它在调试器中逐步完成它应该变得清晰。为了帮助您入门,有关阅读的一些观察。

似乎很清楚readUint()和writeUint()方法正在对缓冲区起作用,可能是ioSpace,虽然你没有显示实际的调用,所以我们无法确定,但你的

  read(STDIN_FILENO, ioSpace, sizeof(ioSpace));

显示STDIN的iospace获取日期。如果文件比iospace大,那么会发生什么事情并不清楚你所展示的内容。也没有做错误处理。

readUint()的代码是:

 while ((c = *readPos++) >= '0')

抓取下一个字符,并递增readPosition。当我们看到我们应该立刻想知道什么时候停止。在这种情况下,当字符c不是

 >= '0'

换句话说,当我们看到的角色小于ascii'0'时,可以是任何字符,例如'&amp;'或'#',但可能是作者期待一个新行'\ n',因为它似乎是他们在writeUint()中终止数字 - 看看我的意思是缺乏评论?然后

c - '0'

产生字符'9'的数字值 - '0'是ascii代码,用于减少9,而不是ascii代码为0,57 - 48,当然是9。

while ((c = *readPos++) >= '0')
    num = num * 10 + (c - '0');

然后我们通过多次使用10并添加我们最近读取的值来构建十进制值。

现在这段代码容易受到包含字母的文件的攻击。看看如果你有像

这样的行会发生什么
 23A4\n

因此,如果您使用此代码,则需要有一些理由信任您的输入。

写入只是通过调用writedigit()函数从数字中获取个别数字。

答案 1 :(得分:0)

嗯...我很确定readUInt函数用于将字符串数转换为实际数,即等效于atoi()函数。我认为WriteDigit是相反的,但我不确定。