改善c++程序的150个建议(读后总结)-------19-26

19. 明白在c++中如何使用c
c++可以兼容c的绝大部分代码,但是还是有一部分不能兼容。
c语言的编译器在调用函数时会把函数翻译成 : “_函数名”,例如:
int nasa(int a,intb)
c语言编译器会将其翻译成:“_nasa”的形式,当调用此函数时就去寻找这个字符串。
c++语言的编译器在调用函数时会把函数翻译成:“_函数名_参数类型_参数类型”,例如:
int nasa(int a,int a)
c++编译器会将其翻译成:“_nasa_int_int” 的形式,当调用此函数时就去寻找这个字符串。
这也是c语言没有函数重载,而c++有函数重载的原因

在c++程序中使用c就需要解决这个问题,通过使用extren “c”

有三种方式使用其来在c++程序中使用c
(1)

/*在c语言的头文件中在函数的声明前加上extren “c”
//例如:

//c语言头文件   c_1.h
extren "c"  int nasa(int x,int y);

//c语言文件    c_2.c
#include "c_1.h"
int nasa(int x,int y)
{
		//code
}

//c++调用文件  
#include "c_1.h"
int main()
{
		int m=nasa(1,2);
		return 0;
}		

(2)

/*在c语言头文件中函数声明前加上extren,在c++调用文件中再次声明函数并在前面加上extren “c”
//例如:

//c语言头文件   c_1.h
extren   int nasa(int x,int y);

//c语言文件    c_2.c
#include "c_1.h"
int nasa(int x,int y)
{
		//code
}

//c++调用文件  
#include "c_1.h"
extren "c"  int nasa(int x,int y);
int main()
{
		int m=nasa(1,2);
		return 0;
}		

(3)

/*在c语言头文件函数声明前加上extren,在c++调用文件时在引用头文件前加上extren “c”  */
//例如:

//c语言头文件   c_1.h
extren   int nasa(int x,int y);

//c语言文件    c_2.c
#include "c_1.h"
int nasa(int x,int y)
{
		//code
}

//c++调用文件  
extren "c"
{
#include "c_1.h"
}
int main()
{
		int m=nasa(1,2);
		return 0;
}		

20.使用memcpy系列函数时不能操作类类型的对象

21. 尽量用new/delete,代替malloc/free
new/delete是c++中新增的关键字,而malloc/free是c的标准库函数。
(1)对于普通类型的对象而言
用二者没有太大区别,但注意malloc动态分配内存返回void *,需要进行强制类型转换后才能使用,而new则不同,其直接返回相应类型的指针,可以直接使用。
(2)对于类类型的对象而言
因为new在动态申请空间的同时会调用构造函数(delete会调用析构函数)
而malloc则不会调用构造函数,不能用malloc来动态建立类类型的对象。
总结 :c++保留malloc/free是为了解决一些兼容性的问题,new/delete的功能完全找过它,所以在使用时尽量使用new,而不用malloc。

22. 灵活使用不同风格的注释
(1)版权声明,文件名称等一些信息用C语言风格的 /* /
(2)内嵌注释用 c++风格的注释 //
(3)宏尾端的注释用 /
*/
(4)因为函数的声明语句一般是在头文件中,而函数的定义语句是在源程序文件中,
如果函数的参数中含有默认参数那么在声明语句中要注明,如此在定义语句中为了更直观准确的使用此函数需要利用注释的形式来表示含有默认参数的参数。
int nasa(int a,int y /*=2*/)
有c风格的注释 /* */ 来表示参数y的默认参数值为2,而用c++风格的注释就不能实现此功能

23. 使用c++标准的iostream
即使用operator<<和operator>>,而不使用printf( )和scanf( )
printf()缺点是
(1)不支持自定义类型
(2)不支持类型安全检查
(3)使用较复杂,格式控制较麻烦

24. 尽量使用c++类型的强制转换
尽量少使用强制类型转换,但是有时候不得不用。

25. 尽量用const,enum,inline替代#define
源程序文件要经过 (预处理-》编译-》链接) 三个过程以后才能被计算机执行。
其中预处理是由预处理器完成的,定义的宏也是在这一过程中被处理的。
但是预处理器处理宏时只是单纯的进行符号替换,如:
(1)#define PI 3.14159
预处理器把所有的PI符号都换成3.1415926,那么如果程序因为PI出错误,而编译器肯本接触不到PI这个符号,只能试图去寻找3.14159数值的出处(如果这个宏定义是在他人的头文件中定义的,则去寻找会很费事费力)
我们应该使用const PI=3.1415926
这是定义一个PI常量,出错之后编译器可以接触到,找错比较方便清晰。
(2)#define add(a,b) ((a)+(b))
“函数宏”:但是其并不等同函数,如果误把其当成函数使用会带来意想不到的错误。
但其优点是加快了程序执行的效率。(有利有弊)

inline  int add(int& a,int& b)
{
		return a+b;
}

这时候考虑使用内联函数,其也实现了在预处理阶段把调用函数的语句直接换成函数体从而提高程序的运行效率,而且其他方面其和普通函数无异(但注意内联函数只包含一些简单的语句,不包含像循环这样费时的语句,因为包含这些语句其就没有什么实际意义了)

26.使用引用代替指针
引用可以理解为 “变量的别名”。
为什么用引用代替指针呢,因为指针理解起来较困难,是程序看起来很复杂,晦涩难懂。
而引用很容易理解,增加了代码的可读性。
而且指针在使用的时候需要额外申请空间来存放变量地址,而引用在使用时不需要去申请任何空间

原文地址:https://www.cnblogs.com/revercc/p/13287092.html