指针
全局指针变量的默认初始值式NULL,而对于non-static局部指针变量p,必须显式地指定其初值,否则p地初始值是不可预测地。
规则:
不管指针是全局还是局部,静态还是非静态,应当在声明它的同时初始化它,要么赋予它一个有效的地址,要么赋予它NULL
编译器不是把指针解释为signed int类型值,而是解释为unsigned int类型数。
指针加/减一个正整数i,其含义并不是在其值上直接加/减i,还要包含指针所指对象的字节数信息。
因此void *类型的指针不能参与算术运算,只能进行赋值,比较和sizeof操作。
指针传递其实是在传递一个地址而不是该地址指向的对象。
数组
任何数组,无论是静态还是动态创建的,其所有元素在内存中都是连续字节存放的。
数组名字本身就是一个指针,是一个指针常量,即a等价于int * const a。数组名的值就是数组第一个元素的内存单元首地址,即a 等价于 &a[0];
数组不能做为 return返回,但数组可以作为函数参数传递。
数组传递在c/c++默认就是地址传递,如果你想按值来传递,可以把数组封装起来,例如放在struct或class里面,因为结构和类对象默认都是按值传递的。
动态创建多维数组
char (*p3)[4] = new char[5][4];
c/c++中char *默认表示字符串
函数指针
在c++动态决议的虚拟机制中使用的vtable就是一个用来保存虚成员函数地址的函数指针数组。
函数指针数组:
double __cdecl (*fp[5])(double) = {sqrt,fabs,cos,sin,exp};
for (int k = 0;k<5;k++)
{
cout << "result " << fp[k](10.25) << endl;
}
连接器把这个通过函数指针的调用推迟到运行时再绑定。
引用和指针的区别
1 引用在创建的时候必须初始化,即引用到一个有效的对象;而指针在定义的时候不必初始化,可以在定义后任何地方重新赋值。
2 不存在NULL引用,不要用字面常量来初始化引用。
3 引用一旦初始化为指向一个对象,它就不能改变为对另一个对象的引用。
int a = 10, b = 100;
int &rInt = a;
rInt = b; //rInt 和 a都变成了100!
4 引用的创建和销毁并不会调用类的构造函数和析构函数。
5 在二进制层面,引用一般都是通过指针实现的,只不过编译器完成了转换。
引用的主要用途是:修饰函数的形参和返回值。
引用传递的性质像指针传递,而书写方式像值传递。
引用体现了最小特权原则,即给予程序元素足以完成其功能的最小权限。
(c是没有引用的!)