4.1.1
非 const 变量以及要到运行阶段才知道其值的 const变量都不能用于定义数组的维数。
int staff_size = 27; // nonconst
const unsigned sz = get_size(); // const value not known until run time
double salaries[staff_size]; // error: non const variable
int test_scores[get_size()]; // error: non const expression
void*指针
它可以保存任何类型对象的地址,该指针与一地址值相关,但不清楚存储在此地址上的对象的类型。void* 指针只支持几种有限的操作:与另一个指针进行比较;向函数传递void* 指针或从函数返回 void* 指针;给另一个 void* 指针赋值。不允许使用void* 指针操纵它所指向的对象。 (详见5.12.4)
指针和引用的比较
第一个区别在于引用总是指向某个对象:定义引用时没有初始化是错误的。第二个重要区别则是赋值行为的差异:给引用赋值修改的是该引用所关联的对象的值,而并不是使引用与另一个对象关联。引用一经初始化,就始终指向同一个特定对象,不能修改绑定(这就是为什么引用必须在定义时初始化的原因,在条款05中也有涉及)
int ival = 1024, ival2 = 2048;
int *pi = &ival, *pi2 = &ival2;
pi = pi2; // pi now points to ival2
int &ri = ival, &ri2 = ival2;
ri = ri2; // assigns ival2 to ival
pi 所指向的 ival 对象值保持不变,赋值操作修改了 pi 指针的值,使其指向另一个不同的对象。第二个例中
赋值操作修改了 ri 引用的值 ival 对象,而并非引用本身。赋值后,这两个引用还是分别指向原来关联的对象,此时这两个对象的值相等。
使用下标访问数组时,实际上是使用下标访问指针: 使用下标访问数组时,实际上是对指向数组元素的指针做下标操作。只要指针指向数组元素,就可以对它进行下标操作
int ia[] = {0,2,4,6,8};
int i = ia[0]; // ia points to the first element in ia
int *p = &ia[2]; // ok: p points to the element indexed by 2
int j = p[1]; // ok: p[1] equivalent to *(p + 1),
// p[1] is the same element as ia[3]
int k = p[-2]; // ok: p[-2] is the same element as ia[0]
C++ 允许计算数组或对象的超出末端的地址,但不允许对此地址进行解引用操作。而计算数组超出末端位置之后或数组首地址之前的地址都是不合法的。
4.2.5
不能使用 void* 指针(第 4.2.2 节)保存 const 对象的地址,而必须使用 const void* 类型的指针保存 const 对象的地址:const int universe = 42;
const void *cpv = &universe; // ok: cpv is const
void *pv = &universe; // error: universe is const
指针和typedef
typedef string *pstring;
const pstring cstr;
请问 cstr 变量是什么类型?
很多人都认为真正的类型是:const string *cstr; 指向 string 类型的 const 对象,但这是错误的。 错误的原因在于将 typedef 当做文本扩展了。声明 const pstring 时,const 修饰的是 pstring 的类型,这是一个指针。因此,该声明语句应该是把cstr 定义为指向 string 类型对象的 const 指针。4.3 C风格字符串
C 风格字符串既不能确切地归结为 C 语言的类型,也不能归结为 C++ 语言的类型,而是以空字符 null 结束的字符数组。C++ 语言通过(const)char*类型的指针来操纵 C 风格字符串。例如,C语言标准库中strcmp(s1,s2)比较s1和s2两个字符串的大小,而在C++中调用strcmp(p1,p2),p1和p2分别是指向s1和s2的(const)char *。
可以把 C 风格字符串用在任何可以使用字符串字面值的地方 ,在要求 C 风格字符串的地方不可直接使用标准库 string 类
型对象 。例如,无法使用 string 对象初始化字符指针:
char *str = st2; // compile-time type error
但是,string 类提供了一个名为 c_str 的成员函数,以实现我们的要求:
char *str = st2.c_str(); // almost ok, but not quite
c_str 函数返回 C 风格字符串,其字面意思是:“返回 C 风格字符串的表示方法”,即返回指向字符数组首地址的指针,该数组存放了与 string 对象相同的内容,并且以结束符 null 结束。
指针数组和数组指针:
int *ip[4]; // array of pointers to int
int (*ip)[4]; // pointer to an array of 4 ints