1 指向数组元素的指针
例如:
int a[10]; ( 定义a为包含10个整型数据的数组 )
int *p ; ( 定义p为指向整型变量的指针变量 )
注意:如果数组为 int 型,则指针变量的基本类型也应为 int 型。
p = &a[0]; // 对该指针进行赋值,也就是说 p指向a数组的第0号元素
p = a ; // C语言规定数组名代表数组中首元素的地址
因此 p = &a[0] 和 p = a 是等价的
2 通过指针引用数组元素
C语言规定:如果指针变量 p 已指向数组中的一个元素,则 p+1 指向同一数组中的下一个元素
如果 p 的初值为 &a[0] :
则 (1) p + i 和 a + i 就是 a的地址
(2) *( p + i ) 或 *( a + i ) 是 p + i 或 a + i 所指向的数组元素,即 a
(3) 指向数组的指针变量也可以带下标,如 p 与 *( p + i )等价 注意:
使用指针变量指向数组元素时,如果用指针变量p来指向元素,用p++可以使p的值不断改变从而指向不同的元素;如果不是用指针变量p而使用数组名a变化,则不能使用a++,因为数字组名a代表数组首元素的地址,它是一个指针常量,所以a++无法实现。
关于指针变量的运算:(1)p++(或p+=1)使 p 指向下一元素,即 a[1]。 (2) *p++。由于++和*优先级相同,结合方向由右至左,因此等价于*(p++) (3) *(p++)与*(++p)作用不同。前者是先取*p值,然后使p加1。后者是先使p+1,再取*p。 例如: int *p; p =&a[0]; *(p++)为a[0], 而*(++p)为a[1]。 (4) ++(*p)表示p所指向的元素的值加1,如果p=a,则++(*p)相当于++a[0]。若a[0]=3,则在执行++(*p)即(++a[0])后,a[0]的值为4。注意:是元素a[0]加1,而不是指针p的值加1。 ++和--运算符用于指针变量十分有效,可以使指针变量自动向前或向后移动,指向上一个或下一个数组元素。 3 数组名作函数参数
C语言中,当变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组元素地址,因此传递的是地址,所以要求形参在这里为指针变量。
注意:实参数组代表一个固定的地址,或者说是指针常量,但形参数组并不是一个固定的地址值,而是作为指针变量,在函数调用时,它的值等于实参数组元素的地址,在函数执行期间,它可以再被赋值。
归纳:
如果有一个实参数组,要想在函数中改变此函数数组中的元素的值,实参与形参的对应关系有下面几种情况:
(1)形参和实参都用做数组名,如
void main() void f ( int x [ ] , int n )
{ {
int a [ 10 ] ; ...
... }
f ( a, 10 ) ;
...
}
(2)实参用做数组名,形参用做指针变量,如
void main() void f ( int *x , int n)
{ {
int a [ 10 ] ; ...
...
f ( a , 10 ) ; }
...
}
实参 a 为数组名 ,形参 x 为指向整型变量的指针变量,函数开始执行时,x 指向 a[0] , 即 x = & a [0] ,通过 x 值的改变,可以指向 a 数组的任一元素。
(3) 实参形参都用指针变量,如
void main() void f ( int *x , int n )
{ {
int a [ 10 ] , *p = a ; ...
...
f ( p , 10 ) ; }
...
}
实参 p 和形参都是指针变量,先使实参指针变量 p 指向数组 a , p 的值是 & a [ 0 ] 。然后将 p 的值传给形参指针变量 x , x 的初始值也是 &a [ 0 ] 。
(4) 实参为指针变量,形参为数组名,如
void main() void f(int x [ ] , int n)
{ {
int a [ 10 ] , *p = a ; ...
...
f ( p , 10 ) ; }
...
}
实参 p 为指针变量,它指向 a [ 0 ] 。形参为数组名x,编译时把x作为指针变量处理,将 a [ 0 ] 的地址传给形参 x ,使指针变量 x 指向 a [ 0 ] 。
还有一点应该注意:如果用指针变量作实参,必须使指针变量有确定的值,指向一个已经定义的单元。