查看文章 |
第五章 指针与数组(二)
指针数组和指向指针的指针: char *ptrarray[LENGTH]; 声明了一个指针数组ptrarray,数组元素ptrarray[i]是一个字符指针,而*ptrarray[i]是它所指向的字符。由于数组名ptrarray本身也是一个指针,因此它是一个指向指针的指针, **(ptrarray+i)等价于*ptrarray[i]。 char *month_name(int n) { static char *name[] = { "Illegal month","Jan","Feb",...,"Dec"}; return (n < 1 || n > 12) ? name[0] : name[n]; } 函数返回一个指向字符串的指针,name[i]保存了指向第i个字符串的指针,编译程序自动计算数组的大小。
多维数组: 在C语言中,多维数组实际上仍然是按行存储的,越靠近右侧的下标变化越快。任何n维数组可以看成一个以n-1维数组为元素的一维数组。 由于数组在作为参数传递时,实际上是传递指向数组首元素的指针,因此多维数组作为参数传递时,最左侧的下标可以省略: f(int array[2][13]) {...} 等价于 f(int array[][13]) {...} 也等价于f(int (*array)[13]) {...} 它表明参数是一个指针,指向由13个整型元素构成的一维数组,圆括号是必须的,因为int *array[13] 是一个一维指针数组。
指针数组和多维数组: int a[10][20]; int *b[10]; a是一个分配了200个整型大小空间的二维数组。b定义并分配了10个指向整型的指针,并没有对他们初始化。假设b[i]是指向具有20个元素的整型数组,那么编译程序还要分配200个整型大小的空间。此时a[3][4]和b[3][4]都是对一个整数的合法引用。 指针数组的优势在于每个指针可以指向不同大小的对象,从而节省空间,因此常用于保存不同长度的字符数组,如前面的name[]。
命令行参数(command-line argument): 在支持C语言的环境中,可以在程序开始执行时向它传递命令行参数。当main被调用时,两个参数随之调用:argc(argument counts)代表命令行参数的个数;argv(argument vector)是指向包含命令行参数的字符数组的指针,每个字符数组一个。 如命令:echo hello, world argc等于3,argv[0]指向字符串"echo",是调用程序的命令名,arg[1]和arg[2]分别为"hello,"和"world"。特别地,C要求argv[argc]为一个空指针。
指向函数的指针: 在C语言中,函数本身不是变量,但可以定义指向函数的指针。这种指针可以被赋值、存入数组、传递给函数、作为函数返回值等等。 int (*comp)(void *, void *); 声明comp是一个指向函数的指针,它指向的函数有两个void*类型的参数,返回一个整型值。*comp间接引用该函数,(*comp)(v[i], v[left])调用该函数。 声明中的圆括号是必须的,否则int *comp(void*, void*);声明的是一个返回整型指针的函数。 函数名实质上是函数的地址,就像数组名一样,不用再加取址运算符&。 下面的调用根据数据类型令函数指针指向不同的函数: if(isdigit(c)) comp = numcmp; else comp = strcmp;
|