s=s+x[i];/*s=s+*(x+i);*/
return(s);
}
等价关系:
强化对“数组元素的引用方法”的理解!
intsum(int*x,intn);
intsum(intx[],intn);
s=s+x[i];
s=s+*(x+i)
10.4字符指针+一维字符数组(字符串)
字符串:
存储于“一维字符数组”中的有效字符。
10.3.1字符串的表现形式
可以用字符指针指向一个字符串
初始化字符串的二类方法:
字符数组
字符指针
chars[10]="abcde";
char*p="abcde";
chars[]="abcde";
char*p;
p="abcdef";
p="xyzw";/*p是变量*/
初始化字符串的错误形式:
字符数组
字符指针
chars[10];
s="abcde";
数组名是常数,不能赋值
char*p;
*p="abcdef"
*p表示一个字符单元
chars[10];
s[]="abcde";
表达式不合法
chars[10];
s[10]="abcde";
表达式不合法,且数组越界
输入字符串的二类方法:
字符数组
字符指针
chars[10];
scanf("%s",s);
chars[10],t[10],*p;
p=s;
scanf("%s",p);
p=t;
scanf("%s",p);
在函数被执行之初,系统已为数组变量分配空间。
在使用指针变量之前,程序员要确保指针变量指向已分配的单元!
10.3.2用一维字符数组(字符指针)作为函数参数
10.3.2.1实现strcpy(dest,src)
#defineN10
voidmystrcpy(char*dest,char*src);
main()
{chars[N]="abcdef",t[N]="12345",tmp[N];
mystrcpy(tmp,s);
mystrcpy(s,t);
mystrcpy(t,tmp);
}
voidmystrcpy(char*dest,char*src)
{for(;*dest=*src;dest++,src++);}
等价关系:
voidmystrcpy(chardest[],charsrc[]);
voidmystrcpy(char*dest,char*src);
src[i];
*src;src++;
10.3.2.2实现strcmp(s1,s2)
intmystrcmp(char*s1char*s2);
main()
{chars1[]="abcdef",s2[]="abc";
intresult;
result=mystrcmp(s1,s2);
if(result==0)printf("%s=%s\n",s1,s2);
if(result>0)printf("%s>%s\n",s1,s2);
if(result<0)printf("%s<%s\n",s1,s2);
}
intmystrcmp(char*s1,char*s2)
{for(;*s1&&*s2;s1++,s2++)
if(*s1!
=*s2)break;
return(*s1-*s2);
}
上机实验:
使用字符指针实现大小写字母的转换。
10.5数组指针+二维数组
数组指针:
整数数组指针、浮点数数组指针.....
10.5.1复习、对比已学相关章节
8.5.3二维数组名作为函数参数
(在形参定义中,必须说明一维数组的大小!
)
数组表示法
指针表示法
floata[][10]
float(*a)[10]
a是一个数组名;
a中元素类型为float[10]
a是一个地址;
所指元素类型为float[10]
数组指针的加减运算:
(时刻注意指针所指元素的类型)
float*p;
p指向float
p++
地址加4
float(*p)[10];
p指向float[10]
地址加40
10.5.2深入分析二维数组的表示方式
设有数组floata[3][4];
基本引用
a[i][j]/*一个浮点数*/
a[i]/*一个一维数组:
&a[i][0]*/
浮点数指针引用
float*p=a;/*缺省类型转换*/
*(p+i*N+j);
main()
{floata[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
float*p=a;
}
观察&a[0][0]、&a[1][0]、&a[2][0]
观察p、p+1、p+2、p+3、p+4、p+5
观察*p、*(p+1)、*(p+2)、*(p+3)、*(p+4)、*(p+5)
数组指针引用
float(*p)[4];p=a;
p+i/*a[i]的地址,指向一维数组*/
*(p+i)/*a[i][0]的地址,指向浮点数*/
*(p+i)+j/*a[i][j]的地址*/
*(*(p+i)+j)/*a[i][j]的值*/
特别提醒:
p+i和*(p+i)的值相等,但对象不同!
main()
{floata[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
float(*p)[4]=a;
}
观察&a[0][0]、&a[1][0]、&a[2][0]
观察p、p+1、p+2
观察*p、*(p+1)、*(p+2)
观察*(*p+1)、*(*(p+1)+1)、*(*(p+2)+2)
10.5.3打印二维数组
voidprint1(float*p,intn);
voidprint2(float(*p)[4],intm);
main()
{floata[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
print1(a,12)
print2(a,3);
}
voidprint1(float*p,intn)
{inti;
for(i=0;iprintf("%f\t",*p);
}
思考:
如何编写print2()函数?
10.5.4数组指针和二维数组的对等关系
inta[M][N];
int(*p)[N];
p=a;
类型
对象
等价形式
p
指针
一维数组
&a[0]
p+i
指针
一维数组
&a[i]
*(p+i)
指针
整数
&a[i][0]
*(p+i)+j
指针
整数
&a[i][j]
*(*(p+i)+j)
整数
a[i][j]
点评:
指向一维数组的指针基本等价于二维数组。
a[M][N]:
a是指针常量,指向小数组。
int(*p)[N]:
p是指针变量,指向小数组。
10.6字符数组指针+二维字符数组
10.6.1在无序的字符串数组中,查找字符串的位置
intsearch(chars[][10],intn,charkey[]);
main()
{charnames[5][10]={"aa","cc","ee","bb","dd"};
charname[10]="bb";
intpos=search(names,5,name);
}
intsearch(chars[][10],intn,charkey[])
{inti;
for(i=0;iif(strcmp(s[i],key)==0)break;
if(i==n)return(-1);
elsereturn(i);
}
思考:
如果函数定义为intsearch(char(*s)[10],intn,char*key),该如何实现该函数?
intsearch(char(*s)[10],intn,char*key)
{inti;
for(i=0;iif(strcmp(*s,key)==0)break;
if(i==n)return(-1);
elsereturn(i);
}
10.7指针数组+指针的指针
int*p[4];
整数指针数组,包含4个指针,
其中每个指针指向int。
float*q[5];
浮点数指针数组,包含5个指针,
其中每个指针指向float。
char*s[6];
字符指针数组,包含6个指针,
其中每个指针指向char。
10.7.1整数/浮点数指针数组练习
main()
{inta[5]={1,2,3,4,5},*p[5],i;
for(i=0;i<5;i++)p[i]=&a[i];
for(i=0;i<5;i++)*p[i]=i;
}
程序有何效用?
10.7.2指针的指针
对整数数组的检索:
引出“整数的指针”
对指针数组的检索:
引出“指针的指针”
main()
{inta[5],*p[5],i,**pp;
for(i=0;i<5;i++)p[i]=&a[i];
for(i=0;i<5;i++)*p[i]=i;
for(pp=p,i=0;i<5;i++)
printf("%x%d\n",*(pp+i),**(pp+i));
print(p,5)
}
10.7.3字符指针数组练习
char*p[4];
p是个数组,每个元素指向char。
指针指向char时,一般我们关注的是一串char。
main()
{chara[4][10]={"abcdefg","xyzw","12345","qrst"};
char*s[4]={"abcdefg","xyzw","12345","qrst"};
s[0]="xxxabcdefg";s[1]="123xyzw";
}
字符指针数组:
可以存储长度不同的字符串
二维字符数组与字符指针数组的区别:
charname[5][9]={“gain”,“much”,“stronger”,“point”,“bye”};
char*name[5]={“gain”,“much”,“stronger”,“point”,“bye”};
其中二维字符数组存储空间固定,而字符指针数组相当于可变列长的二维数组。
另外,指针数组中元素是指针变量
二维数组的行名是地址常量。
小结:
指针p和所指对象*p的内存形象
意义
sizeof(p)
sizeof(*p)
float*p;
实数
指针
2
4
float(*p)[5];
数组
指针
2
4*5=20
float*p[5];
指针
数组
2*5=10
sizeof(*p):
2
sizeof(p[0]):
2
sizeof(*p[0]):
4
sizeof(**p):
4
float**p;
指针的指针
2
2