指针数组是由指针变量构成的数组,在操作时,既可以对数组元素进行赋值(地址值)和引用,也可以间接访问数组元素所指向的单元内容,改变或引用该单元的内容。
字符指针数组:
#include <stdio.h>
int main(void)
{
char *str[] = {"abg","cd"};//*单独拿出来,指的是数组里的内容是*型的,str的类型是char *[]型
printf("%c\n",*(*(str+1)+1)); //d
printf("%c\n",**str); //a
printf("%s\n",*str+1); //bg
printf("%s\n",*(str+1)); //cd
printf("%s\n",str[0]); //abg
printf("%p\n",&str); //数组整体的收地址,大小同下行代码的值
printf("%p\n",str); //数组的首地址,即存放内容——字符串"abg"的地址,并非'a'的地址
system("pause");
return 0;
}
/*
指针数组相当于二位数组
str-->"abg"的地址,str+1 --->"cd"的地址
*str-->"abg"的首地址,即'a'的地址,*(str+1)--->"cd"的首地址,即'c'的地址
*(str+1)+1--->"cd"的首地址+1,即'd'的地址
*(*(str+1)+1)--->对'd'的地址取值,即为'd'
**str-->'a'
*/
#include <stdio.h>
char **String(char *str[])
{
str[0] = "aa";
str[1] = "bb";
return str;
}
//返回*str[]时,因为[]是下标运算符号,可以当作*,所以返回值类新为char **
int main(void)
{
char **p;
char *str[2];
p = String(str);
printf("%s\n",*p);
printf("%s\n",*(p+1));
system("pause");
return 0;
}
指向指针的指针
在C语言中,指向指针的指针一般定义为:
类型名**变量名;
也称为二级指针。与一级指针相比,二级指针的概念较难理解,运算也更为复杂。
例如:
int a=10;
int *p=&a;
int **pp=&p;
定义了三个变量a,p,pp并初始化。一级指针p指向整型变量a,二级指针pp指向一级指针p。由于p指向a,所以p和&a的值一样,a和*p代表同一个单元;由于pp指向p,所以pp和&p的值一样,p和**p代表同一个单元。由此可知&&a,&p和pp等价,&a,p和*pp等价,a,*p,和**p代表同一个单元,它们的值相同。
用指针处理多个字符串
1.指针数组与二维数组
如果要处理多个字符串,通常使用二维字符数组或者指针数组。例如:
char ccolor[][7]={"red","blue","yellow"};
char *pcolor[]={"red","blue","yellow"};
定义了两个数组。ccolor是二维字符数组,3行7列共21个元素,每一行存放一个字符串,每个元素的类型都是字符型。pcolor是指针数组,有3个元素,占用3个存储单元,每个元素的类型都是字符指针,分别指向一个字符串。
定义二维字符数组的时候必须指定列长度,该长度要大于最大的字符串的有效长度,由于每个字符串的长度一般并不相同,会造成内存单元的浪费。而指针数组并不存放字符串,仅仅用数组元素指向各个字符串,就没有类似的问题。
2.用指针数组操作多个字符串
例:将5个字符串从小到大排序后输出
#include<stdio.h>
#include<string.h>
void fsort(char*color[], int n);
int main()
{
int i;
char*pcolor[] = { "red","blue","yellow","green","black" };
fsort(pcolor, 5);
for (i = 0; i < 5; i++) {
printf("%s", pcolor[i]);
}
system("pause");
return 0;
}
void fsort(char*color[], int n) //一个字符串冒泡
{
int k, j;
char*temp;
for (k = 1; k < n; k++) {
for (j = 0; j < n - k; j++) {
if (strcmp(color[j], color[j + 1]) > 0) {
temp = color[j];
color[j] = color[j + 1];
color[j + 1] = temp;
}
}
}
}
在程序的排序函数中,比较指针数组的元素所指向字符串的大小,需要交换时,直接交换数组元素的值,即改变它们的指向。
通过指针数组不仅可以对多个字符串整体操作,还可以对字符串中的字符进行操作。
例:解密藏头诗
//解密藏头诗
#include<stdio.h>
char*change(char s[][20]);
int main()
{
int i;
//指针数组初始化
char *poem[4] = { "一叶轻舟向东流,","帆梢轻握杨柳手,","风纤碧波微起舞,","顺水任从雅客悠。" };
char mean[10];
for (i = 0; i < 4; i++) { //每行取第一个汉字存入mean
mean[2 * i] = *(poem[i]);
mean[2 * i + 1] = *(poem[i] + 1);
}
mean[2 * i] = '\0';
printf("%s\n", mean);
system("pause");
return 0;
}
在此例中,分别从指针数组poem指向的四句诗中取出第一个汉字,然后按顺序存入字符数组mean中,尾部添加字符'\0'生成一个字符串,此字符串即为解密内容。由于一个汉字由两个字符组成,所以在实际操作时是取出每个字符串的前两个字符,程序中 *(poem[i]) 对应的第i个字符串中的第1个字符,*(poem[i] +1) 对应第i个字符串中的第2个字符。