爱 做 网站,wordpress安装怎么填,做网站与不做网站的区别,个人网站开发软件点击蓝字关注我们因公众号更改推送规则#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络#xff0c;侵删公司每年都会有一定的人员流动#xff0c;相应地也会招一些应届生补充进来#xff0c;指导应届生已经成为老员工的必修课了。平日里会我们会经…点击蓝字关注我们因公众号更改推送规则请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络侵删公司每年都会有一定的人员流动相应地也会招一些应届生补充进来指导应届生已经成为老员工的必修课了。平日里会我们会经常帮新人排查代码中的问题在此过程中发现了 C 新手容易犯的一些编程错误在此简单的总结一下给新人们提供一个参考。1、有些关键字在 cpp 文件中多写了对于 C 类一些关键字只要写在 .h 中就好cpp 中就不用再加上了比如 virtual、static 等关键字如果在 cpp 中多写编译器会报错。比如如下的虚接口与静态成员变量的定义只要在头文件中声明就可以了。class shape
{virtual Draw();//...static int nLevel;
}2、函数参数的默认值写到函数实现中了带有参数默认值的函数默认值是加在函数声明处的函数实现处的参数是不需要带上的。为了方便查看代码在函数实现处的参数中将默认值注释起来。正确的做法是头文件中有默认值BOOL CreateConf( const CString strConfName, const BOOL bAudio FALSE );
在函数实现处的参数中不用添加默认值
BOOL CreateConf( const CString strConfName, const BOOL bAudio/* FALSE*/ );
{// ......
}3、在编写类的时候在类的结尾处忘记添加 ; 分号了在类的结尾处忘记添加分号编译会报错新人们有可能找了半天也没找出引起编译错误的原因。其实很简单在类的结尾处忘记添加分号了。class Shape
{// ...
};4、只添加了函数声明没有函数实现在添加类的函数时只在类的头文件中添加了函数声明但在 cpp 中却没有添加函数的实现。如果其他地方调用到该函数在编译链接的时候会报unresolved external symbol错误。因为没有实现所有没有供链接使用的 obj 文件。5、cpp 文件忘记添加到工程中导致没有生成供链接使用的 obj 文件在添加 C 类时我们一般会添加 .h 头文件和一个 .cpp 源文件。结果忘记把 .cpp 文件添加到工程中了即没有参与编译没有生成供链接使用的 obj 文件。如果有代码调用到该 C 类的接口则在编译链接的时候会报unresolved external symbol错误即链接不到该 C 类对应的接口。6、函数中返回了一个局部变量的地址或者引用在函数中返回了一个局部变量的地址或者引用而这个局部变量在函数结束时其生命周期就结束了内存就被释放了。当外部访问到该变量的内存会触发内存访问违例的异常因为该变量的内存已经释放了。比如如下的错误代码char* GetResult()
{char chResult[100] { 0 };// ......return chResult;
}7、忘记将父类中的接口声明 virtual 函数导致多态没有生效代码中本来要借助于 C 多态的虚函数调用调用子类实现的接口结果忘记在父类中将对应的接口声明为 virtual导致没有调用到子类实现的函数。一定要记住要实现多态下的函数调用父类的相关接口必须声明为 virtual。class Shape()
{// ...virtual void Draw();// ...
}8、该使用双指针的地方却使用了单指针有时我们需要调用一个接口去获取某些数据接口中将数据拷贝到传入的参数对应的内存中此时设计参数时会传入指针或引用。我们在调用GetData 之前定义了结构体指针p并 new 出了对应的结构体对象内存应该在定义 GetData 接口时应该使用双指针指针的指针的结果错写成了单指针。有问题的代码如下struct CodecInfo // 编码信息
{int nFrameRate// ...
}CodecInfo* pInfo new CodecInfo;GetAudioCodecPtr()-GetCodecInfo(pInfo); // 调用AudioCodec::GetCodecInfo获取编码信息AudioCodec::GetCodecInfo( CodecInfo* pInfo) // 此处的参数不应该使用单指针
{memcpy(pInfo, m_codecInfo, sizeof(CodecInfo));
}上面中的AudioCodec::GetCodecInfo接口的参数不应该为单指针应该用双指针修改后的代码应该如下AudioCodec::GetCodecInfo( CodecInfo** pInfo) // 此处的参数类型使用双指针
{memcpy(*pInfo, m_codecInfo, sizeof(CodecInfo));
}9、发布 exe 程序时忘记将 exe 依赖的 C 运行时库和 MFC 库带上比如新人用 VS-MFC 库编写一个测试用的工具软件结果在发布 release 版本程序时没有将程序依赖的 C 运行时库带上导致该工具软件在某些电脑中启动报错提示找不到 C 运行时库因为程序中依赖了动态版本的运行时库和 MFC 库在发布程序时要将这些库带上。有些系统中没有这些库程序启动时就会报找不到库就会启动失败。10、应该使用深拷贝却使用了浅拷贝本来应该要进行深拷贝的却使用了浅拷贝直接赋值导致另个不同生命周期的 C 对象指向了同一块内存一个对象将内存释放后另一个对象再用到这块内存就造成了内存访问违例产生异常。有个经典的 C 笔试题让我们实现 String 类的相关函数其主要目的就是用来考察对深拷贝与浅拷贝的理解的。题目中给出 String类的声明class String{
public:String();String(const String str);String(const char* str);String operator(String str);char* c_str() const;~String();int size() const;
private:char* data;
};让写出上述几个函数的内部实现。这些函数的实现代码如下//普通构造函数
String::String(const char *str)
{if (str NULL){m_data new char[1];// 得分点对空字符串自动申请存放结束标志\0的加分点对m_data加NULL判断 *m_data \0;}else{int length strlen(str);m_data new char[length 1];// 若能加 NULL 判断则更好strcpy(m_data, str);}
}// String的析构函数
String::~String(void)
{delete[] m_data; // 或delete m_data;
}//拷贝构造函数
String::String(const String other)// 得分点输入参数为const型
{ int length strlen(other.m_data);m_data new char[length 1];// 若能加 NULL 判断则更好 strcpy(m_data, other.m_data);
}//赋值函数
String String::operator (const String other) // 得分点输入参数为const型
{if (this other)//得分点检查自赋值 return *this; if (m_data)delete[] m_data;//得分点释放原有的内存资源 int length strlen(other.m_data);m_data new char[length 1];//加分点对m_data加NULL判断 strcpy(m_data, other.m_data);return *this;//得分点返回本对象的引用
}如果你年满18周岁以上又觉得学【C语言】太难想尝试其他编程语言那么我推荐你学Python现有价值499元Python零基础课程限时免费领取限10个名额▲扫描二维码-免费领取戳“阅读原文”我们一起进步