10数组与指针
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数组与指针
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址,所谓数组元素的指针就是数组元素的地址。引用数组元素可以用下标(如a[3]),也可以用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使目标程序质量高(占内存少,运行速度快)。
一维数组和指针
1.指向数组元素的指针
例:int a[10]; /*定义a为包含10个整型数据的数组*/
int *p; /*定义p为指向整型变量的指针变量*/
p=&a[0]; 把a[0]元素的地址赋给指针变量p。也就是说,p指向a数组的第0号元素。C 语言规定数组名代表数组中第一个元素(即序号为0的元素)的地址,因此下面两个语句等价:p=&a[0]; 与p=a 等价。注意:数组名不代表整个数组,“p=a”的作用把a数组的首元素的地址赋给指针变量p,而不是把数组a各元素的值赋给p.
在定义指针变量时,可以对它赋初值:int *p=&a[0];或int *p=a;
2.通过数组的首地址引用数组元素
由以上可知:a是a数组元素的首地址,a(即:a+0)的值就等于&a[0];则a+1的值,就等于&a[1], a+2就等于&a[2],……a+9就等于&a[9]
这里,可以通过”取地址运算符*”来引用地址所在的存储单元,因此,对于数组元素a[0],可以通过表达式*&a[0]来引用,也可以用*(a+0)来引用,对此也可以写成:*a;而对于数组元素a[1],可以用表达式*&a[1]来引用,也可以用*(a+1)来引用……对于a[9]可以用*&a[9]来引用,也可以用*(a+9)来引用。
因此可以通过以下的语句输出a数组元素中的值:
for(k=0;k<10;k++) printf(“%4d”,*(a+k));
就相当于:for(k=0;k<10;k++) printf(“%4d”,a[k]);
3.通过指针引用数组元素
假如p已定义为一个指向整型数据的指针变量,并已给它赋了个整型数组元素的地址,使它指向某一个数组元素。如果有以下定义语句:*p=1;表示对p当前所指向数组元素赋予一个值1。
按C的规定,如果指针变量p已指向数组元素中的一个元素,则p+1指向同一数组中的下一个元素(而不将p的值简单的加1)。
如果p的初值为&a[0],即p=a或p=&a[0],也可以使用“间接访问运算符*”,通过指针变量p不引用a数组中的元素,对于数组a[0],可以用表达式*(p+0)即*p来引用,a[1],也可以用表达式*(p+1)来引用,p+1的值就是数组元素a[1] 的地址……对于数组元素a[9]就可以用*(p+9)来引用。所以当指针变量p指向a数组的起始地址时,可以通过以下语句输出a数组的元素:for(p=a,k=0;k<10;k++) printf(“%4d”,*(p+k);
指针变量p可以移动:
for(p=a,k=0;k<10;k++) { printf(“%4d”, *p), p++;}
4用带下标的指针变量引用数组元素
若有以下的定义:int *p , s[10],i ; p=s;
可以用&s[i], s+i; 和p+i三种表达式来表示s[i]的地址,同时可以用s[i], *(s+i)和*(p+i)三种表达式来表示数组元素s[i];s[i]可以用表达式*(s+i)来表示,同理*(p+i)也应该可以用表达式p[i]的形式来表示。因此,当p指向s数组的首地址时,表示数组元素s[i]的表达式有以下四种:
(1)s[i] (2) *(s+i) (3)*(p+i) (4)p[i]
这里,面s和p有着明显的区别,s是不可变的,而p中的地址却是可变的,因此,s++, s=p,p=&s 等运算都是不合法的,而p++,p=s,p=&s[i]则都是合法的表达式。
说明:
(1)p+i和a+i就是a[i]的地址,或者说它们指向a数组的第i个元素,这里a代表数组元素的
首地址,a+i也是地址。
(2)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i],即按数组首元素的地址加上相对位移
量得到要找的元素的地址,然后找出该单元中的内容。
(3)指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价。
注意:指针变量的运算:先使p指向数组a的首元素,则
①p++或(p+=1),使p指向下一元素,即a[1]。若再执行*p,取出下一个元素a[1]值。
②*p++,由于++和*同优先级,结合方向自右至左,因此它等价于*(p++)。作用是先得到p
指向的变量的值(即*p),然后再使p+1=>p.
③*(p++)与*(++p)不同,前者是先取*p的值,然后使p加1。后者是先使p加1 ,再取*p。若p初值为a(即a[0]),输出*(p++)时,得a[0]的值;而输出*(++p),则得a[1]的值。
④(*p)++表示p所指向的元素值加1,即(a[0])++,如果a[0]=3;则(a[0])++的值为4。
函数与数组
1用数组名作函数参数
前面已经介绍过可用数组名和数组元素作函数参数。数组元素实际上代表内存中的一个存储单元,和普通变量一样。实参数组名代表该数组首元素的地址。而形参是用来接收从实参传递过来的数组首元素的地址。因此,形参应该是一个指针变量(只有指针能存放地址)。例:编写程序,通过函数给数组输入若干大于等于0的整数,用负数作为输入结束的标志;调用函数输出该数组中的数据。
#define M 100
void arrout(int *,int);
arrin(int * );
main()
{ int s[M],k;
k=arrin(s);
arrout(s,k);
}
arrin(int *a)
{ int i,x;
i=0;
scanf("%d",&x);
while(x>=0)
{ *(a+i)=x;
i++;
scanf("%d",&x);
}
return i;
}
void arrout(int *a,int n)
{ int i;
for(i=0;i