一、定义
除了类型外,指针变量与其他变量类似。我们可以创建整型数组,也可以创建指针型数组,即
int *api[10];
二、解释
为了弄清这个复杂的声明,我们假定它是一个表达式,并对它进行求值。下标引用的优先级高于间接访问,所以在这个表达式中,首先执行下标引用。因此,api是某种类型的数组(噢,顺便说一下,它包含的元素个数为10)。在取得一个数组元素之后,随即执行的是间接访问操作。这个表达式不再有其他操作符,所以它的结果是一个整型值。那么api到底是什么东西?对数组的某个元素执行间接访问操作后,我们得到一个整型值。所以api肯定是个数组,它的元素类型是指向整型的指针。
三、实例
指针数组(也就是元素为指针类型的数组)常常作为二维数组的一种便捷替代方式。一般情况下,这种数组中的指针会指向动态分配的内存区域。
例如,如果需要处理字符串,可以将它们存储在一个二维数组中,该数组行空间大小必须足以存储下可能出现的最长字符串:
#define ARRAY_LEN 100
#define STRLEN_MAX 256
char myStrings[ARRAY_LEN][STRLEN_MAX] =
{
"会出错的事,总会出错。",
"世上没有绝对正确的事情。",
"每个解决办法都会衍生出新的问题。"
};
然而,这个方式造成内存浪费,25600 字节中只有一小部分被实际使用到。一方面,短字符串会让大部分的行是空的;另一个方面,有些行根本没有用到,但却得为它预留内存。
一个简单的解决方案是,使用指针数组,让指针指向对象(在此处的对象就是字符串),然后只给实际存在的对象分配内存(未用到的数组元素则是空指针)。
#define ARRAY_LEN 100
const char *myStrPtr[ARRAY_LEN] = // char指针的数组
{
"会出错的事,总会出错。",
"世上没有绝对正确的事情。",
"每个解决办法都会衍生出新的问题。"
};
图 1 展示了对象在内存中的存储情况:
四、其他实例
int *ptrs[10]; 首先ptrs是一个数组,int *定义数组元素的类型。
int &refs[10]; 这是一个错误的声明,因为引用是一个变量的别名,引用没有自己的内存空间,其和被引用的变量共用一块内存空间,因此引用数组无法分配空间,引用数组也就无法存在。
int (*Parray)[10]; 首先Parray是一个指针,指向有10个元素的数组,数组元素类型是整型。
int (&arrRef)[10]; 首先arrRef是一个引用,引用的对象是有10个元素的数组,数组元素类型是整型。
int *(&arry)[10]; 首先arry是一个引用,引用的对象是有10个元素的数组,数组元素类型是整型指针。
参考: