最近仔细看了C++ primer,总结了一下C++中的一些值得注意的地方,与大家分享。也可以帮助一些从C过渡到C++的同学,更顺利地完成过渡。一共总结了88个小点,里面大都是我认为C++中比较重要的特性,还有一些易错点,还有一些在C的时候就没有弄明白的语法。
1.对于extern关键字,只有在函数外部时,才可以含有初始化式。
比如:
int main()
{
extern int a = 0;
return 0;
}
这样对a的定义是错误的。extern是声明某个变量或者某个函数可以在别的目标文件中找到定义,同时,extern声明的某个变量,编译器在寻找这个变量时只会在其他文件的非static全局变量区寻找定义。所以将a变量定义在main()中是不能被编译器发现的,但是可以在函数中声明变量。这部分听起来比较拗口,我们从具体下面一个实例中体会一下:
在test1.cpp中编写主函数,调用test2.cpp中的变量及函数:
test1.cpp:
#include <iostream>
using namespace std;
extern int number1;
extern void print();
void sum(int number2)
{
extern int number3;
cout << "the sum of number1~3 is " << number1 + number2 + number3 << endl;
return;
}
int main()
{
extern int number2;
cout << "number1 is " << number1 << endl;
cout << "number2 is " << number2 << endl;
print();
sum(number2);
return 0;
}
test2.cpp
#include <iostream>
int number1 = 10;
int number2 = 20;
int number3 = 30;
void print()
{
std::cout << "use print() successfully!" << std::endl;
return;
}
由于想尽快包含多的extern声明情况,所以声明了函数,在子程序中声明了变量,在全局声明了变量。
这样编译test1.cpp是完全没有问题的。
执行结果:
如果有朋友对头文件的作用,和程序编译过程还有静态和动态链接库有疑问,推荐看一下我写的:
静态链接库与动态链接库----C/C++
2.在C++中不能定义引用类型的引用,比如int &&a。
什么叫定义引用类型的引用,我们可以和理解指向指针的指针一样去看待它。比如:
int a = 0;
int &rb = a;
int &rc = rb;
这样是完全可以的。rc,rb都引用同一个对象。
3.在scanf()中,double型的输入只能入%lf,float型用%f,而输出double和float型都用%f。
有朋友会说我在printf()的时候一直都是用的%lf,这个确实可能正确输出,但是有许多系统没有定义它,为了保留可移植性,我推荐用%f输出double和float。其实printf中%f是输出double型的,但是由于输出float型类型时,自动提升为double型,所以%f即可以输出double也可以输出float型。
4. typedef 和define定义变量名时的语法区别
typedef 类型 名字
define 名字 类型名
对于typedef int *int_pointer;
int_pointer ptra;
这样就定义了一个ptra的整型指针。一个比较好理解的方式是将ptra替换typedef定义式中的int_pointer。可以很明显的看出ptra的整性指针定义。实际上,编译器也是这么干的。
上面这个例子没有很好的体现出typedef的便利性,下面我们定义一个函数指针:
typedef bool (*cmpFcn)(const string &, const string &);
bool lengthCompare(const string &, const string &);
cmpFcn pf1 = 0;
cmpFcn pf2 = lengthCompare; //等效于cmpFcn pf2 = &lengthCompare;
这样就可以很明显的看出typedef的便利性了。同样的,只要将pf1替换typedef中的cmpFcn就可以看清楚的看出定义。
在primer 112页有个typedef的事例,这个事例特别容易搞错,typedef凡是涉及定义const类型时都需要特别注意,这个问题我们以后再说。
5.迭代器相减后的类型为vector等容器内定义的difference_type类型,而指针相减则为标准库中的ptrdiff_t。
ptrdiff_t其实就可以看成signed long int, 而标准库另一种类型size_t则为unsigned long int。long型在linux中为一个字长,64位的机子是8个字节。
总结:difference_type与size_type为STL所有,这些类型与具体机器无关,可移植性好
size_t与ptrdiff_t为标准库所有。