C语言进修教程第六章-指针(4)
二、多维数组的指针变量
把二维数组a 解析为一维数组a[0],a[1],a[2]之后,设p为指向二维数组的指针变量。可界说为: int (*p)[4] 它暗示p是一个指针变量,它指向二维数组a 或指向第一个一维数组a[0],其值便是a,a[0],或&a[0][0]等。而p+i则指向一维数组a[i]。从前面的阐明可得出*(p+i)+j是二维数组i行j 列的元素的地点,而*(*(p+i)+j)则是i行j列元素的值。
二维数组指针变量说明的一般形式为: 范例说明符 (*指针变量名)[长度] 个中“范例说明符”为所指数组的数据范例。“*”暗示其后的变量是指针范例。 “长度”暗示二维数组解析为多个一维数组时, 一维数组的长度,也就是二维数组的列数。应留意“(*指针变量名)”双方的括号不行少,如缺少括号则暗示是指针数组(本章后头先容),意义就完全差异了。
[Explain]main(){
static int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
int(*p)[4];
int i,j;
p=a;
for(i=0;i<3;i++)
for(j=0;j<4;j++) printf("%2d ",*(*(p+i)+j));
}
‘Expain字符串指针变量的说明和利用字符串指针变量的界说说明与指向字符变量的指针变量说明是沟通的。只能按对指针变量的赋值差异来区别。 对指向字符变量的指针变量应赋予该字符变量的地点。如: char c,*p=&c;暗示p是一个指向字符变量c的指针变量。而: char *s="C Language";则暗示s是一个指向字符串的指针变量。把字符串的首地点赋予s。
请看下面一例。
main(){
char *ps;
ps="C Language";
printf("%s",ps);
}
运行功效为:
C Language
上例中,首先界说ps是一个字符指针变量, 然后把字符串的首地点赋予ps(应写出整个字符串,以便编译系统把该串装入持续的一块内存单位),并把首地点送入ps。措施中的: char *ps;ps="C Language";等效于: char *ps="C Language";输出字符串中n个字符后的所有字符。
main(){
char *ps="this is a book";
int n=10;
ps=ps+n;
printf("%s\n",ps);
}
运行功效为:
book 在措施中对ps初始化时,即把字符串首地点赋予ps,当ps= ps+10之后,ps指向字符“b”,因此输出为"book"。
main(){
char st[20],*ps;
int i;
printf("input a string:\n");
ps=st;
scanf("%s",ps);
for(i=0;ps[i]!=’\0′;i++)
if(ps[i]==’k’){
printf("there is a ‘k’ in the string\n");
break;
}
if(ps[i]==’\0′) printf("There is no ‘k’ in the string\n");
}
本例是在输入的字符串中查找有无‘k’字符。 下面这个例子是将指针变量指向一个名目字符串,用在printf函数中,用于输出二维数组的各类地点暗示的值。但在printf语句顶用指针变量PF取代了名目串。 这也是措施中常用的要领。
main(){
static int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
char *PF;
PF="%d,%d,%d,%d,%d\n";
printf(PF,a,*a,a[0],&a[0],&a[0][0]);
printf(PF,a+1,*(a+1),a[1],&a[1],&a[1][0]);
printf(PF,a+2,*(a+2),a[2],&a[2],&a[2][0]);
printf("%d,%d\n",a[1]+1,*(a+1)+1);
printf("%d,%d\n",*(a[1]+1),*(*(a+1)+1));
}
在下例是讲授,把字符串指针作为函数参数的利用。要求把一个字符串的内容复制到另一个字符串中,而且不能利用strcpy函数。函数cprstr的形参为两个字符指针变量。pss指向源字符串,pds指向方针字符串。表达式:
(*pds=*pss)!=`\0′
cpystr(char *pss,char *pds){
while((*pds=*pss)!=’\0′){
pds++;
pss++; }
}
main(){
char *pa="CHINA",b[10],*pb;
pb=b;
cpystr(pa,pb);
printf("string a=%s\nstring b=%s\n",pa,pb);
}
在上例中,措施完成了两项事情:一是把pss指向的源字符复制到pds所指向的方针字符中,二是判定所复制的字符是否为`\0’,若是则表白源字符串竣事,不再轮回。不然,pds和pss都加1,指向下一字符。在主函数中,以指针变量pa,pb为实参,别离取得确定值后挪用cprstr函数。由于回收的指针变量pa和pss,pb和pds均指向同一字符串,因此在主函数和cprstr函数中均可利用这些字符串。也可以把cprstr函数简化为以下形式:
cprstr(char *pss,char*pds)
{while ((*pds++=*pss++)!=`\0′);}
即把指针的移动和赋值归并在一个语句中。 进一步阐明还可发明`\0’的ASCⅡ码为0,对付while语句只看表达式的值为非0就轮回,为0则竣事轮回,因此也可省去“!=`\0’”这一判定部门,而写为以下形式:
cprstr (char *pss,char *pds)
{while (*pdss++=*pss++);}
表达式的意义可表明为,源字符向方针字符赋值, 移动指针,若所赋值为非0则轮回,不然竣事轮回。这样使措施越发简捷。简化后的措施如下所示。
cpystr(char *pss,char *pds){
while(*pds++=*pss++);
}
main(){
char *pa="CHINA",b[10],*pb;
pb=b;
cpystr(pa,pb);
printf("string a=%s\nstring b=%s\n",pa,pb);
}