边界计算与不对称边界

    C Traps and Pitfalls笔记。
    边界计算要注意的两条原则:
    (1) 首先考虑最简单情况下的特例,然后将得到的结果外推,这是原则一;
    (2) 仔细计算边界,绝不掉以轻心,这是原则二。
    不对称边界编程思想的两种考虑方式:
    1.用第一个入界点(包含在范围内)和第一个出界点(范围外的第一个数值)来表示一个数值范围;好处:1)取值范围的大小即为上界与下界之差,2)上界等于下界表示取值范围为空,3)即使取值范围为空,上界也永远不可能小于下界;
    2.将上界视作某序列中第一个被占用的元素,下界视作某序列中第一个被释放的元素。
    不对称边界应用举例和分析:考虑这样一个函数,该函数的功能是将长度无规律的输入数据送到缓冲区(一块能够容纳N个字符的内存),当缓冲区已满,就将缓冲区的全部内容写出。
    缓冲区的可以是如下形式:
#define N 1024
static char buffer[N];
//根据不对称边界思想,bufptr应始终指向缓冲区中第一个未被占用的字符,而不是指向第一个已被占用的字符
static char *bufptr;

//将缓冲区的内容写出并重置bufptr指针
flushbuffer();

//写入函数,一次只能转移一个字符到缓冲区
void bufwrite(char* p, int n)
{
    while(--n >= 0)        // (--n >= 0)是n次迭代的一种方法,至少与等效的(n-- > 0)一样快
    {
        if(bufptr == &buffer[N]) 
 //应用不对称边界思想,buffer[N]只能对其地址赋值和比较,不能直接引用其值,因为N超出了数组的元素的下标范围1~N-1
            flushBuffer();

        *bufptr++ = *p++;
    }
}

//对上述算法的改进,这个程序的绝大部分开销来自于每次迭代时都要进行两个检查:一个检查用于判断循环计数器是否达到终值,另一个检查用于判断缓冲区是否已满,利用memcpy函数每次迭代转移k个字符到缓冲区

void bufwrite(char* p, int n)
{
    while(n > 0)
    {
        int k,rem;
        if(bufptr == &buffer[N])
            flushBuffer();
        rem = N - (bufptr - buffer);
        k = n > rem ? rem : n;
        memcpy(bufptr,p,k);

        bufptr += k;
        p += k;
        n -= k;
    }
}

//memcpy函数为C自带库函数,用汇编语言编写以提高运行速度,如果没有可以自己定义成如下形式
void memcpy(char* dest, const char* source, int n)
{
    while(--k >= 0)
    {
        *dest++ = *source++;
    }
}


原文地址:https://www.cnblogs.com/kimimaro/p/2006117.html