赣菜菜谱:指针数组与数组指针2

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 05:31:02

数组中每个元素都具有相同的数据类型,数组元素的类型就是数组的基类型。如果一个数组中的每个元素均为指针类型,即由指针变量构成的数组,这种数组称之为指针数组,它是指针的集合。
指针数组说明的形式为:
类型 * 数组名[常量表达式]
例如: int * pa[5];
表示定义一个由5个指针变量构成的指针数组,数组中的每个数组元素--指针,都指向一个整数,其结构如图10-9所示。

注意"int *pa[5]"与"int (*pb)[5]"的区别。
int (* pb)[5];
表示定义了一个指向数组的指针pb,pb指向的数组是一维的体积为5的整型数组,其结构如图10-10所示。
char * line[5];
表示line是一个5个元素的数组,每个元素是一个指向字符型数据的一个指针。若设指向的字符型数据(字符串)分别是"ONE"、"TWO"、…、"FIVE",则数组line的结构如图10-11所示。

而:char (*line)[5];
表示line是指向一个长度为5的字符数组的指针。
指针数组常适用于指向若干字符串,这样使字符串处理更加灵活方便。
例10-16:输入字符串,判断该字符串是否是英文的星期几。使用指针数组实现。
#include
char *week_day[8]= {"sunday", "monday", "tuesday", "wednesday",
"thursday", "friday", "saturday", NULL
}; /* 说明指针数组。数组中的每个元素指向一个字符串 */
main( )
{ int m;
char string[20];
printf("Enter a string: ");
scanf("%s", string);
m=lookup(string);
printf("l=%d\n", m);
}
lookup (ch)
char ch[ ]; /* 传递字符串(字符数组) */
{ int i, j;
char *pc;
for (i=0; week_day[i]!=NULL; i++) /* 完成查找工作 */
{ for( pc=week_day[i],j=0; *pc==ch[j] && *pc!= ‘\0‘; j++,pc++ );
if ( *pc==‘\0‘ )
return(i); /* 若找到则返回对应的序号 */
}
return(-1); /* 若没有找到,则返回-1 */
}


程序中没有使用二维的字符数组,而是采用指针数组week_day。可以看到指针数组比二维字符数组有明显的优点,一是指针数组中每个元素所指的字符串不必限制在相同的字符长度,二是访问指针数组中的一个元素是用指针间接进行的,效率比下标方式要高。
例10-17:输入星期几,输出对应星期的英文名称。用指针数组实现。
#include
char * week_day[8]= {"sunday", "monday", "tuesday", "wednesday",
"thursday", "friday", "saturday", NULL };
/* 说明指针数组。数组中的每个元素指向一个字符串 */
main( )
{ int day;
char *p, *lookstr( );
printf("Enter day: ");
scanf("%d", &day);
p = lookstr (week_day, day);
printf("%s\n", p);
}
char * lookstr ( table, day ) /* 函数的返回值为指向字符的指针 */
char *table[ ]; /* 传递指向字符串的指针数组 */
int day;
{ int i;
for (i=0; iif (i==day && table[i]!=NULL)
return ( table[day] );
else return(NULL);
}


例10-18:修改程序10-11,用数组指针作为形参实现函数day_of_year。
#include
main( )
{ static int day_tab[2][13]={ 0,31,28,31,30,31,30,31,31,30,31,30,31,
0,31,29,31,30,31,30,31,31,30,31,30,31 };
int y, m, d;
scanf ("%d%d%d", &y, &m, &d);
printf("days=%d\n", day_of_year( day_tab, y, m, d ) );
}
day_of_year (day_tab, year, month, day)
int (*day_tab)[13], year, month, day; /* day_tab为数组指针 */
{ int i, j;
i = year%4==0 && year%100!=0 || year%400==0;
for (j=1; jday += (*(day_tab+i))[j]; /* 引用数组指针指向的数组中的元素 */
return (day);
}


   请将例C10-11.C和例C10-18.C函数day_of_year进行比较,体会不同类型的形式参数在函数中的使用方法。
事实上,在程序中可以用指针灵活地处理多维数组,使程序优化,并可提高程序的技巧。例如:对于一个三维数组
long a[100][100][100];
要将所有的元素都清0,可采用下面两种方法:
方法一:采用常规的多维数组处理方式 方法二:采用指针处理方式
  long a[100][100][100], i , j, k;   long a[100][100][100], i, *pa;
for (i=0; i<100; i++) pa = a;
for (j=0; j<100; j++) for (i=0; i<100*100*100; i++)
for (k=0; k<100; k++) *pa++ = 0;
a[i][j][k]=0;
方法一直接使用三维数组中的数组元素,访问其中的任一数组元素a[i][j][k]时,每次都要调用数组元素地址的计算公式。而方法二则利用三维数组在内存中是按行线性顺序存放的这一特性,通过一个指针顺序加1的方法实现对数组a中所有元素的赋0操作。两种处理方法相比较,方法二处理速度比方法一快得多。