指针数组和多重指针
- 什么是指针数组
- 指向指针数组的指针变量
- 指针数组作main函数的形参
指针数组的概念
一个数组,若起元素均为指针类型数据,称为指针数组。
也就是说,指针数组中的每一个元素都粗放一个地址,相当于一个指针变量。
定义一维指针数组
类型名 * 数组名[数组长度];
类型名中应该包括符号*
,如int *
表示是指向整型数据的指针类型
如
int * p[4]
由于[]
比*
优先级高,因此p先与[4]
结合,形成p[4]
形式,这显然是数组形式,表示p数组有4个元素
然后再与p前面的*
结合,*
表示此数组是指针类型的,每个数组元素(相当于一个指针变量)都可指向一个整型变量
指针数组与指向数组的指针变量的区别
- 指针数组本质是一个数组,而指向数组的指针变量本质是一个指针变量。
- 指针数组和指向数组的指针变量形式上的区别
- 指针数组:
int * a[4]
// a先与变址运算符结合,形成p[4]
形式,这显然是数组形式,
然后在与p前面的*
运算符结合,表示此数组是指针类型- 指向数组的指针变量:
int (* a)[4]
,因为有括号,因此a先与*
结合,表明是一个指针变量,而这个指针是指向一维数组的。
指针数组的应用场景
指针数组比较适合用来指向若干个字符串,使字符串处理更加方便了灵活。
例如,图书馆有若干本书,想把书名放在一个数组中。然后要对这些书目进行排序和查询。
- 按照一般方法,字符串本身就是一个字符数组。
因此要设计一个二维的字符数组才能存放多个字符串。
但在定义二维数组时,需要指定列数,也就是说二维数组中每一行包含的元素个数(即列数)相等
而实际上个字符串(书名)长度一般是不相等的。如按最长的字符串定义列数,则会浪费许多内存单元- 可以分别定义一些字符串,然后用指针数组中的元素分别指向各字符串。
如果想对字符串排序,不必改动字符串的位置,只须改动指针数组中铬元素的指向(即改变个元素的值,这些值是各字符串的首地址)。
这样,各字符串长度可以不同,而且移动指针变量的值(地址)要比移动字符串所化的时间少的多。
指向指针数据的指针变量
指向指针数据的指针变量,简称为指向指针的指针。
定义一个指向指针数据的指针变量
char **p;
*
运算符的结合性是从右到左,因此**p
相当于*(*p)
,显然*p
是指针变量的定义形式。
利用指针变量访问另一个变量就是“间接访问”。
如果在一个指针变量中存放一个目标变量的地址,这就是单级间址。
指向指针数据的指针用的是二级间址方法。从理论上来说,间址方法可以延伸到更多的级,即多重指针。
但实际上在程序中很少有超过二级间址的。
指针数组作main函数的形参
指针数组的一个重要应用是作为main函数的形参。
- 一般情况下
int main()
或int main(void)
表明main函数没有参数,调用main函数时不必给楚实参 - 在某些情况下,main函数可以有参数
int main(int argc,char *argv[])
其中argc和argv就是main函数的形参,它们是程序的“命令行参数”。
argc(argument count的缩写,意思是参数个数),
argv(argument vector缩写,意思是参数向量),它是一个* char
指针数组,
数组中每一个元素(其值为指针)指向命令行中的一个字符串的首字符。
如果用带参数的main函数
- 其第一个形参必须是int型,用来接收形参个数,
- 第二个形参必须是字符指针数组,用来接受从操作系统命令行传来的字符串中首字符的地址
命令行的一般形式:
命令名 参数1 参数2 ... 参数n
参数和参数之间用空格分隔
命令名是可执行文件名(此文件包含main函数)
举例说明,如敲下如下命令file1 China Beijing
file1为可执行文件名
China和Beijing是调用函数时的实参。