`
0769
  • 浏览: 83666 次
  • 性别: Icon_minigender_1
  • 来自: 东莞
社区版块
存档分类
最新评论

C/C++编程新手错误语录

阅读更多
C/C++编程新手错误语录


 
 1.引言

  还记得当年学数学、英语都有个窍门,那就是搞个错题集。经常复习一下这个错题集,就可以避免下次犯同样的错误。而几乎所有的程序员都是从犯错误开始的,我们也很有必要总结一下编程新手的常见错误,本文的目的在于此。文中所列出的都是笔者在项目开发中接触到的新手真实的言谈,笔者学学文革腔调,姑且称之为“错误语录”。

  2.语录

<iframe border="0" marginwidth="0" marginheight="0" src="http://219.239.88.50:80/adsunion/get/;pl=pl-20-pip-software;tp=if;sk=0;ck=0;/?" frameborder="0" noresize="noresize" width="1" scrolling="no" height="1"></iframe>  (1)“我的程序都是对的,可结果不对”

  想想你的周围,是不是也有人说这样的话?如果你也曾经说过,那就此打住,不要再说这句话,因为这句话只会显示说话者的无知。既然程序都是对的,那为什么结果不对?

  (2)“程序=算法+数据结构

  如果刚刚学完C语言,我们说这样的话,完全可以理解,而且可以说是正确的。但是如果你是一位即将从事C/C++编程的程序员,那么很遗憾,这个说法只能判错,殊不知,世界上还有另一种说法:

  程序 = 对象 + 消息

  “程序=算法+数据结构”只对面向过程的语言(C)成立,而对面向对象的语言(C++),则只能表述为“程序=对象+消息”。传统的过程式编程语言以过程为中心以算法为驱动,面向对象的编程语言则以对象为中心以消息为驱动。这里的消息是广义的,对象A调用了对象B的成员函数,可看作对象A给B发消息。

  (3)“程序编出来,运行正确就行了”

  运行正确的程序并不一定是好程序,程序员时刻要牢记的一条就是自己写的程序不仅是给自己看的,要让别人也能轻易地看懂。很遗憾,许多的编程新手不能清晰地驾驭软件的结构,对头文件和实现文件的概念含糊不清,写出来的程序可读性很差。

  C程序采用模块化的编程思想,需合理地将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求,在模块的划分上主要依据功能。模块由头文件和实现文件组成,对头文件和实现文件的正确使用方法是:

  规则1 头文件(.h)中是对于该模块接口的声明,接口包括该模块提供给其它模块调用的外部函数及外部全局变量,对这些变量和函数都需在.h中文件中冠以extern关键字声明;

  规则2 模块内的函数和全局变量需在.c文件开头冠以static关键字声明;

  规则3 永远不要在.h文件中定义变量;

  许多程序员对定义变量和声明变量混淆不清,定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。如:

/*模块1头文件:module1.h*/
int a = 5; /* 在模块1的.h文件中定义int a */
/*模块1实现文件:module1 .c*/
#include “module1.h” /* 在模块1中包含模块1的.h文件 */
/*模块2实现文件: module2.c*/
#include “module1.h” /* 在模块2中包含模块1的.h文件 */
/*模块2 实现文件:module3 .c*/
#include “module1.h” /* 在模块3中包含模块1的.h文件 */

  以上程序的结果是在模块1、2、3中都定义了整型变量a,a在不同的模块中对应不同的地址单元,这明显不符合编写者的本意。正确的做法是:

/*模块1头文件:module1.h*/
extern int a; /* 在模块1的.h文件中声明int a */
/*模块1实现文件:module1 .c*/
#include “module1.h” /* 在模块1中包含模块1的.h文件 */
int a = 5; /* 在模块1的.c文件中定义int a */
/*模块2 实现文件: module2 .c*/
#include “module1.h” /* 在模块2中包含模块1的.h文件 */
/*模块3 实现文件: module3 .c*/
#include “module1.h”   /* 在模块3中包含模块1的.h文件 */

  这样如果模块1、2、3操作a的话,对应的是同一片内存单元。

  规则4 如果要用其它模块定义的变量和函数,直接包含其头文件即可。

  许多程序员喜欢这样做,当他们要访问其它模块定义的变量时,他们在本模块文件开头添加这样的语句:

extern int externVar; 

  抛弃这种做法吧,只要头文件按规则1完成,某模块要访问其它模块中定义的全局变量时,只要包含该模块的头文件即可。

  (4)“数组名就是指针

  许多程序员对数组名和指针的区别不甚明了,他们认为数组名就是指针,而实际上数组名和指针有很大区别,在使用时要进行正确区分,其区分规则如下:

  规则1 数组名指代一种数据结构,这种数据结构就是数组;

  例如:

char str[10];
char *pStr = str;
cout << sizeof(str) << endl;
cout << sizeof(pStr) << endl;

  输出结果为:

10
4

  这说明数组名str指代数据结构char[10]。

  规则2 数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;

char str[10];
char *pStr = str;
str++; //编译出错,提示str不是左值 
pStr++; //编译正确

  规则3 指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址;

  规则4 数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

  例如:

void arrayTest(char str[])
{
cout << sizeof(str) << endl;   //输出指针长度
    str++; //编译正确
}
int main(int argc, char* argv[])
{
 char str1[10] = "I Love U";
 arrayTest(str1);
return 0;
}

  (5)“整形变量为32位”

  整形变量是不是32位这个问题不仅与具体的CPU架构有关,而且与编译器有关。在嵌入式系统的编程中,一般整数的位数等于CPU字长,常用的嵌入式CPU芯片的字长为8、16、32,因而整形变量的长度可能是8、16、32。在未来64位平台下,整形变量的长度可达到64位。

  长整形变量的长度一般为CPU字长的2倍。

  在数据结构的设计中,优秀的程序员并不会这样定义数据结构(假设为WIN32平台):

typedef struct tagTypeExample
{
unsigned short x;
unsigned int y;
}TypeExample;

  他们这样定义:

#define unsigned short UINT16 //16位无符号整数
#define unsigned int UINT32 //32位无符号整数
typedef struct tagTypeExample
{
UINT16 x;
UINT32 y;
}TypeExample;

  这样定义的数据结构非常具有通用性,如果上述32平台上的数据发送到16位平台上接收,在16位平台上仅仅需要修改UINT16、UINT32的定义:

#define unsigned int UINT16 //16位无符号整数
#define unsigned long UINT32 //32位无符号整数

  几乎所有的优秀软件设计文档都是这样定义数据结构的。

  (6)“switch和if …else…可随意替换”

  switch语句和一堆if…else…的组合虽然功能上完全一样,但是给读者的感受完全不一样。if…else…的感觉是进行条件判断,对特例进行特别处理,在逻辑上是“特殊与一般”的关系,而switch给人的感觉是多个条件的关系是并列的,事物之间不存在特殊与一般的关系,完全“对等”。

  譬如:

//分别对1-10的数字进行不同的处理,用switch
switch(num)
{
case 1:

case 2:

}
//对1-10之间的数字进行特殊处理,用if
if(num < 10 && num > 1)
{

}
else
{

}

  许多时候,虽然不同的代码可实现完全相同的功能,但是给读者的感觉是完全不同的。譬如无条件循环:

while(1)
{
}

  有的程序员这样写:

for(;;)
{
}

  这个语法没有确切表达代码的含义,我们从for(;;)看不出什么,只有弄明白for(;;)在C/C++语言中意味着无条件循环才明白其意。而不懂C/C++语言的读者看到while(1)也可猜到这是一个无条件循环。

  (7)“免得麻烦,把类里面的成员函数都搞成public算了”

  许多人编C++程序的时候,都碰到这样的情况,先前把某个成员函数定义成类的private/protected函数,后来发现又要从外面调用这个函数,就轻易地将成员函数改为public类型的。甚至许多程序员为了避免访问的麻烦,干脆把自己添加的成员函数和成员变量都定义成public类型。

  殊不知,这是一种规划的失败。在类的设计阶段,我们就要很清晰地知道,这个类的成员函数中哪些是这个类的接口,哪些属于这个类内部的成员函数和变量。一般的准则是接口(public成员)应在满足需求的前提下尽可能简单!

  所以不要轻易地将private/protected成员改为public成员,真正的工作应该在规划阶段完成。

  3.结束语

  所有的程序员都要经历一个从糊涂到清晰的过程,文中的错误如果你也犯了,切勿自惭。

  更多的错误语录,希望能在后续文章中陆续推出。
分享到:
评论

相关推荐

    林锐-高质量c/c++编程指南

    ### 林锐-高质量C/C++编程指南 #### 概述 《林锐-高质量C/C++编程指南》是一份由林锐博士编撰的专业文档,旨在为C/C++开发者提供一套规范化的编程指导原则。这份文档对于希望提升编程技能、编写出高质量代码的C++...

    林锐 《高质量C/C++编程》

    "林锐 《高质量C/C++编程》" 通过分析林锐的《高质量C/C++编程》DOC文档,我们可以提取出以下重要的知识点: 1. 文件结构: * 版权和版本的声明:在编写C/C++程序时,需要在文件开头声明版权和版本信息,以确保...

    Oracle9iPro*C/C++编程指南源码

    Oracle9i Pro*C/C++编程指南源码是一个深入学习Oracle数据库与C/C++结合编程的重要资源,它提供了丰富的示例代码和实践指导,帮助开发者掌握如何利用Pro*C/C++工具进行数据库应用程序开发。Pro*C/C++是Oracle公司...

    C/C++语言编程安全子集

    C/C++语言编程安全子集

    《精通Oracle 10g Pro*C/C++编程》源代码与学习笔记

    《精通Oracle 10g Pro*C/C++编程》是一本专为数据库开发人员设计的教程,作者王海亮和张立民通过这本书深入探讨了如何使用C或C++语言与Oracle 10g数据库进行高效交互。源代码与学习笔记的提供,为读者提供了实践操作...

    高质量C/C++编程指南(PDF)

    高质量C++/C 编程指南,v 1.0 2001 Page 4 of 101 6.1 参数的规则. 6.2 返回值的规则. 6.3 函数内部实现的规则. 6.4 其它建议. 6.5 使用断言. 6.6 引用与指针的比较. 第7 章 内存管理 7.1 内存分配方式 7.2 常见...

    win7 64位可用的c/c++编程软件

    标题中的“win7 64位可用的c/c++编程软件”指的是适用于Windows 7操作系统64位版本的C/C++编程环境。在Windows 7 64位系统上进行C或C++编程,需要一个兼容该系统的集成开发环境(IDE)或者编译器。描述中的“很好用...

    高质量C/C++编程

    高质量C/C++编程 养成良好的编程习惯 如何让代码看起来更令人舒畅

    高质量的C/C++编程.rar

    C/C++是两种底层编程语言,C语言以其简洁高效而著名,而C++则在其基础上加入了面向对象特性。理解它们的基本语法、数据类型、控制结构、指针操作等是构建高质量程序的基础。 2. **内存管理**: C/C++程序员需要对...

    从缺陷中学习C/c++

    标题和描述中提及的知识点主要集中在C/C++编程中常见的缺陷、陷阱以及如何从这些错误中学习和成长。以下是对这些知识点的详细阐述: ### C/C++编程陷阱概览 在C/C++编程中,程序员经常会遇到各种陷阱,这些陷阱...

    Pro*C/C++ 编程

    **Pro*C/C++ 编程** Pro*C/C++ 是一种集成在C或C++编程语言中的预处理器,它允许程序员直接在源代码中嵌入PL/SQL语句,用于与Oracle数据库进行交互。这种编程方式提供了高效且灵活的数据库访问手段,特别适合于开发...

    C/C++编程规范--北京软通动力信息技术有限公司

    C/C++编程规范 C/C++编程规范是软件开发过程中不可或缺的一部分,对于编写高质量的C/C++代码非常重要。北京软通动力信息技术有限公司编写的C/C++编程规范文档,旨在为程序员提供统一的编程标准,提高代码的可读性、...

    VisualC/C++案例编程精选集锦PDF之二,科学出版社,共502页,有实用.

    《Visual C/C++案例编程精选集锦》是针对C++编程语言的一本深入实践的教程,由科学出版社出版,共计502页,涵盖了丰富的案例和实用技巧。这本书旨在帮助读者通过实例学习和掌握C/C++编程技术,提升在实际项目中的...

    C/C++程序员实用大全-C/C++最佳编程指南

    《C/C++程序员实用大全——C/C++最佳编程指南》是一本专为C/C++开发者设计的详尽参考资料,旨在帮助读者深入理解这两种强大的编程语言,并掌握高效的编程实践。本书涵盖了从基础知识到高级特性的全面内容,对于初学...

    编程及C/C++初学者 FAQ

    ### 编程及C/C++初学者 FAQ #### 一、引言 本文档旨在帮助初学者快速上手C/C++编程语言,并解答在学习过程中可能遇到的各种常见问题。通过集中整理与解答这些问题,帮助读者更好地理解编程的基本概念,顺利运行...

Global site tag (gtag.js) - Google Analytics