1.指针的声明
String *ps1, ps2;
String *ps1, *ps2;
前者表示声明一个指向string 类型对象的指针和一个string类型对象。
后者表示声明两个指向string 类型对象的指针。
一个有效指针必然是以下三种状态之一:
1)保存一个特定对象的地址;
2)指向某个对象后的另一个对象;
3)0值,表示不保存任何对象。
未初始化的指针是无效的,直到给指针赋值后,才可以使用它。
2.Typedef
C 语言允许用typedef说明一种新类型名,来代替已有类型名,形式为:
Typedef 类型名(已有类型名) 标识符(新类型名);
Typedef 未产生新的类型,相当于给原类型名起别名,而原类型名依然有效。
需注意:
Typedef char * string_t;
#define string_d char*; (前为新标识符, 后为已有字符串)
前者声明类型别名,在编译时处理,有类型检查。
后者是一个简单替换,在预编译时处理,无类型检查。
使用上来说:string_t a,b; a和b都是char类型,但String_d a,b; 只有a 是char* 类型,b是char类型的。
3.void*指针
C++提供了一个特殊类型的指针void*,它可以保存任何类型对象的指针,void*表示该指针与一地址值有关,但并不清楚此地址上对象的类型。Void*指针只包含几种操作:
1)与另一指针进行比较;
2)向函数传递void*指针或者从函数返回void*指针;
3)给另一个void*指针赋值。
不允许void*指针操控它所指向的对象,当函数返回void*类型时表示返回一个特殊指针类型,而不是表示无返回值。
4.指向指针的指针
指针本身也是可用指针指向的内存对象。指针占用内存空间存放其值(值为地址),因此指针的存储地址也可放在指针中。如下:
Int ival = 1024;
Int *pi = &ival;
Int **ppi = π
定义了指向指针的指针ppi,C++使用** 操作符指派一个指针指向另一个指针。
5.函数指针
函数指针指向函数而非指向对着那个的指针。如:
Bool (*pf)(const string &, const string &);
表示pf为指向函数的指针,它所指向的函数带有两个const string& 类型的形参和bool类型的返回值,(*pf)两侧的圆括号不可省略。
用typedef简化函数指针的定义:
Typedef bool (*cmpFcn)(const string &, consr string &);
表示cmpFcn是一种指向函数的指针类型的名字,要使用这种函数指针类型时,只需直接使用cmpFcn即可,每次都把整个类型声明全部写出来。
在引用函数名但又没用调用该函数时,函数名将自动解释为指向函数的指针,可使用函数名对指针做初始化或赋值,指向不同函数类型的指针之间不存在转换。
函数指针的使用:
指向函数的指针可用于它所指向的函数,如:
Typedef bool (*compare)(const string &, const string &);
Bool lengthCompare(const string &, const string &);
则:
cmpFcn pf = lengthCompare;
lengthCompare(“hi”, “bye”);//直接调用lengthCompare函数
Pf(“hi”,”bye”);//利用函数指针调用lengthCompare函数,未使用*
(*pf)(“hi”,”bye”);//利用函数指针调用lengthCompare函数,使用*
函数指针形参:
函数的形参可以是指向函数的指针。这种形参形参可以用两种方式编写
Void useBigger(const string &, const string &, bool(const string &, const string &));
上述定义等价于:
Void useBigger(const string &, const string & ,bool (*)(const string &, const string &));
返回指向函数的指针:
函数可以返回指向函数的指针,这种函数指针声明的写法为
Int (*ff(int))(int*,int);
分析:这是一个函数声明,该函数返回值为ff(int),类型为int (*)(int *, int),即指向函数的指针。
但是该指针指向的函数的参数不是(int*,int),而是(int),由ff(int)也可以看出ff是函数名,其实也就是指向该函数的指针。这一点不同于int (*ff)(int *, int),这是一个指针声明,指向
(int*, int)。
允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,而不能是函数。
指向重载函数的指针:
C++允许使用函数指针指向重载的函数,且必须与重载函数的一个版本精确匹配,否则返回错误, 如:
Extern void ff(vector<double>);
Extern void ff(unsigned int);
若有 void (*pf1)(unsigned int) = &ff;
则 pf1 指向参数为unsigned int 版本的函数ff。
6.引用
所谓引用,就是对象的另外一个名字,从本质上来说,引用还是一个指针,指向它所绑定对象的地址,只不过这个指针不能修改,任何对对它的操作都会发生在这个指针所指向的地方,而不是这个指针上。所以C++规定,一旦定义了引用,就必须把它跟一个变量绑定起来,并且不能修改这个绑定。不能定义引用类型的引用,但可以定义其它类型的引用。
引用和指针之间的重要区别:
1)引用不能为空值,创建时必须初始化。指针可以为空值,在任何时候都可以初始化。
2)引用所绑定的对象一旦绑定不能改变,指针可随时指向另一个对象。
3)不可能为NULL引用,必须确保引用和一块合法地址关联。
4)Sizeof(引用)得到引用所绑定对象的大小,sizeof(指针)得到指针本身大小。
5)给引用赋值修改引用关联对象的值,而非使引用重新关联其它对象。
6)引用使用时不需要解引用,指针需要解引用。
7)返回动态动态分配的对象或内存,必须使用指针,引用可能引起内存泄露。
8)用&作用于引用,其值为所引用变量的地址。对指针使用&运算,其值为指针变量的地址。
Const 引用是指向const对象的引用,当引用的对象是const对象时,引用也必须是const。
Ru: const int ival = 1024;
Const int &refVval = ival; //正确
Const $ref2 = ival; //错误
引用是可以作为类的数据成员的,其初始化有以下特点:
1)不能直接在类的构造函数里初始化,必须用到初始化列表。
2)凡是有引用类型的数据成员的类,必须定义构造函数。