VC软件开发规范(断言,引用与指针的比较)_雨霏霏的空间_百度空间

4.4 其它建议

       【建议4.4-1      函数的功能要单一,不要设计多用途的函数;

       【建议4.4-2      函数体的规模要小,尽量控制在150行代码之内;

       【建议4.4-3      尽量避免函数带有“记忆”功能。相同的输入应当产生相同的输出带有“记忆”功能的函数,其行为可能是不可预测的,因为它的行为可能取决于某种“记忆状态”。这样的函数既不易理解又不利于测试和维护。在C/C++语言中,函数的static局部变量是函数的“记忆”存储器。建议尽量少用static局部变量,除非必需。

       【建议4.4-4      不仅要检查输入参数的有效性,还要检查通过其它途径进入函数体内的变量的有效性,例如全局变量、文件句柄等;

       【建议4.4-5      用于出错处理的返回值一定要清楚,让使用者不容易忽视或误解错误情况。

4.5 使用断言

程序一般分为Debug版本和Release版本,Debug版本用于内部调试,Release版本发行给用户使用。

断言assert是仅在Debug版本起作用的宏,它用于检查“不应该”发生的情况。示例4.5是一个内存复制函数。在运行过程中,如果assert的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。

         void *memcpy(void *pvTo, const void *pvFrom, size_t size)

{

        assert((pvTo != NULL) && (pvFrom != NULL));     // 使用断言

        byte *pbTo = (byte *) pvTo;     // 防止改变pvTo的地址

        byte *pbFrom = (byte *) pvFrom; // 防止改变pvFrom的地址

        while(size -- > 0 )

            *pbTo ++ = *pbFrom ++ ;

        return pvTo;

}

示例4.5 复制不重叠的内存块

assert不是一个仓促拼凑起来的宏。为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。所以assert不是函数,而是宏。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。如果程序在assert处终止了,并不是说含有该assert的函数有错误,而是调用者出了差错,assert可以帮助我们找到发生错误的原因。

       【规则4.5-1      使用断言捕捉不应该发生的非法情况,不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的;

       【规则4.5-2      在函数的入口处,使用断言检查参数的有效性(合法性);

       【建议4.5-1      在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查;

       【建议4.5-2      一般教科书都鼓励程序员们进行防错设计,但要记住这种编程风格可能会隐瞒错误。当进行防错设计时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。

4.6 引用与指针的比较

引用是C++中的概念,初学者容易把引用和指针混淆一起。一下程序中,nm的一个引用(reference),m是被引用物(referent)。

    int m;

    int &n = m;

n相当于m的别名(绰号),对n的任何操作就是对m的操作。所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。

引用的一些规则如下:

1       引用被创建的同时必须被初始化(指针则可以在任何时候被初始化);

2       不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL);

3       一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。

    以下示例程序中,k被初始化为i的引用。语句k = j并不能将k修改成为j的引用,只是把k的值改变成为6。由于ki的引用,所以i的值也变成了6

    int i = 5;

    int j = 6;

    int &k = i;

    k = j; // ki的值都变成了6;

    上面的程序看起来象在玩文字游戏,没有体现出引用的价值。引用的主要功能是传递函数的参数和返回值。C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。

    以下是“值传递”的示例程序。由于Func1函数体内的x是外部变量n的一份拷贝,改变x的值不会影响n, 所以n的值仍然是0

    void Func1(int x)

{

    x = x + 10;

}

int n = 0;

    Func1(n);

    cout << n = << n << endl; // n = 0

   

以下是“指针传递”的示例程序。由于Func2函数体内的x是指向外部变量n的指针,改变该指针的内容将导致n的值改变,所以n的值成为10

    void Func2(int *x)

{

    (* x) = (* x) + 10;

}

int n = 0;

    Func2(&n);

    cout << n = << n << endl;      // n = 10

    以下是“引用传递”的示例程序。由于Func3函数体内的x是外部变量n的引用,xn是同一个东西,改变x等于改变n,所以n的值成为10

    void Func3(int &x)

{

    x = x + 10;

}

int n = 0;

    Func3(n);

    cout << n = << n << endl;      // n = 10

对比上述三个示例程序,会发现“引用传递”的性质象“指针传递”,而书写方式象“值传递”。



郑重声明:资讯 【VC软件开发规范(断言,引用与指针的比较)_雨霏霏的空间_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——