指针与数组

int a[10];
int *pa = &a[0];
pa++;

(1)首先指针pa指向a[0]的地址,注意后缀运算符的优先级高于单目运算符,所以是取a[0]的地址,而不是取a的地址。然后pa++让pa指向下一个元素(也就是a[1]),由于pa是int *指针,一个int型元素占4个字节,所以pa++使pa所指向的地址加4,注意不是加1。

(2)a[2]和pa[2]本质上是一样的,都是通过指针间接寻址访问元素。

(3)由于a做右值使用时和&a[0]是一个意思,所以int *pa = &a[0];通常不这么写,而是写成更简洁的形式int *pa = a;。

(4)C语言允许数组下标是负数,在上面的例子中,表达式pa[-1]是合法的,它和a[0]表示同一个元素。

(5)指针之间的比较运算比的是地址, C语言正是这样规定的,不过C语言的规定更为严谨,只有指向同一个数组中元素的指针之间相互比较才有意义,否则没有意义。

(6)指针相减表示两个指针之间相差的元素个数,同样只有指向同一个数组中元素的指针之间相减才有意义。

(7)C语言也规定两个指针不能相加。

(8)在取数组元素时用数组名和用指针的语法一样,但如果把数组名做左值使用,和指针就有区别了。例如pa++是合法的,但a++就不合法, pa = a + 1是合法的,但a = pa + 1就不合法。数组名做右值时转换成指向首元素的指针,但做左值仍然表示整个数组的存储空间,而不是首元素的存储空间,数组名做左值还有一点特殊之处,不支持++、赋值这些运算符,但支持取地址运算符&,所以&a是合法的。

(9)在函数原型中,如果参数是数组,则等价于参数是指针的形式,例如:

void func(int a[10])
{
...
}

等价于:

void func(int *a)
{
...
}

第一种形式方括号中的数字可以不写,仍然是等价的:

void func(int a[])
{
...
}

参数写成指针形式还是数组形式对编译器来说没区别,都表示这个参数是指针,之所以规定两种形式是为了给读代码的人提供有用的信息,如果这个参数指向一个元素,通常写成指针的形式,如果这个参数指向一串元素中的首元素,则经常写成数组的形式。

posted @ 2018-04-07 23:19  刘-皇叔  阅读(721)  评论(0编辑  收藏  举报