C++-C编程指南 学习笔记

《C++-C编程指南 ---林锐博士》 学习笔记 (一)

该指南中对很多经常忽略的细节进行了深入的探讨。
细细阅读和思考,逐步建立起自己的比较完备的概念。

一、函数设计
    函数接口两个要素是函数参数和函数的返回值
    C语言中,函数参数有值传递和指针传递两种方式。
    C++语言中,增加了引用传递方式
  规则:
  1、如果参数是指针,且仅作为输入使用,则应在该类型前面加上const,防止该指针在函数体内被以外修改。
  2、如果输入参数一直传递的方式传递对象,则宜改成“const &”方式来传递,可以省去临时对象的构造和析构过程,提高效率。
  3、避免函数有太多的参数,参数的个数控制在5个以内。如果参数过多,可以用结构体来封装部分参数。提高参数的可读性。
  4、尽量不要使用类型和数目不确定的参数(类型检查)。
  5、不要省略函数的返回值类型,无类型时用void替代。
  6、正常值和错误标志混在一起返回。 正常值用输入参数获取,错误标志用return语句返回。
  函数内部实现的规则:
  1、在函数体的入口处,对参数的有效性进行检查。充分理解并正确适使用断言来防止此类的错误。
  2、在函数的出口处,对return语句的风趣恶性和效率进行检查。
  3、函数功能单一,规模小。无记忆功能,相同的输入产生相同的输出。
  4、不仅检查输入参数的有效性,还要检查通过其他途径进入函数体的变量的有效性。如全局变量,文件句柄等。
  5、用于出错处理的返回值要清楚。
 一般教科书都鼓励程序员进行防错设计,这种设计可能会隐瞒错误。当进行防御性设计时,如果“不可能发生”的事情发生了,则需要使用断言进行报警。

内存管理
 
内存分配方式有3种
1、静态存储区分配
   该区域在程序编译的时候就已经分配好了,这块内存在程序的运行过程中都存在。
   如全局变量,static变量。
2、在站上创建
   在执行函数时,函数内部的局部变量的存储单元都可以在栈上创建,在函数执行结束时,这些存储单元自动释放。效率高,但分配的内存容量有限。
3、从堆上分配
   程序在运行时程序员malloc或new申请的任意多的内存,程序员负责free或delete释放该内存。

常见内存错误即其对策

1、内存分配未成功,却使用了它。
    在使用内存值钱检查指针时候为null,如果指针p是函数的参数,那么在函数的路口处用 assert(p!= null)进行检查,如果使用malloc或new来申请内存,应该用if(p==null)或if(p!=null)进行防错处理。
 2、内存分配成功,但是为初始化就引用了它。没有初始化的概念,而是误以为内存的缺省初值权威零。
 3、内存分配成功并且已经初始化,但操作越过了内存的边界。
 4、忘记了释放内存,造成内存的泄露。
 5、释放了内存却继续使用了它。
使用free或delete释放内存后,没有将指针设置为null,导致产生了野指针

  1、用malloc或new申请内存后,应该立即检查指针值时候为nulll,防止指针值为null的内存。
  2、不要忘记为数组和动态内存赋初值,防止将位被初始化的内存作为右值使用。
  3、避免数组或指针的小标越界,特别当心发生多1 少1的操作
  4、动态内存的申请和释放工作必须配对,防止内存泄露
  5、使用free或delete释放内存之后,立即将指针设置为null,防止产生野指针。

附1:类String的成员实现:
class String
{
public:
 String(const char *str = NULL);//普通构造函数
 String(const String &other);   //拷贝构造函数
 ~String(void);                 //析构函数
 String& operate =(const String &other);//赋值函数
protected:
private:
 char  *m_data;
};
//析构函数 释放资源
String::~String(void)
{
 delete [ ] m_data;
}
String::String(const char *str)
{
 if (str==NULL)
 {
  m_data = new char[1];
  *m_data = '/0';
 }
 else
 {
  int length=strlen(str);
  m_data = new char[length+1];
  strcpy(m_data,str);
 }
}
String::String(const String &other)
{
 int length =strlen(other.m_data);
 m_data = new char[length+1];
 strcpy(m_data,other.m_data);
}
String& String::operate =(const String& other)
{
 if(this==&other)
  return *this;
 int length=strlen(other.m_data);
 m_data = new char[length+1];
 strcpy(m_data,other.m_data);
 return *this;
}

附2:strcpy函数的实现:
char *strcpy(char *strDest,const char *strSrc)
{
   assert((strDest != NULL ) && (strSrc != NULL)
   char *address = strDest;
   while((*strDest++=*strSrc++) != ‘/0’)
   NULL;
   return address;
}

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值