您的位置:首页 > 其它

深入浅出C指针(二)一维数组

2012-03-22 11:15 363 查看
1.数组名

我们看一下下面两个声明:

int a;

int b[10];

我们把变量a称为标量,因为它是个单一的值。我们把变量b称为数组,因为它是一些值的集合。b[0]表示数组中的第一个数,b[1]表示数组中的第二个数,以此类推。

我们知道b[0]的类型是整形,那么,b的类型是什么呢?它所表示的是什么呢?一个合乎逻辑的答案似乎是它表示整个数组,但事实并非如此。在C语言中,数组名永远代表一个指针常量,也就是数组第一个元素的地址,即 &b[0]。它的类型取决于数组的类型。

注意,这里说的是“指针常量”,而不是上一篇文章说的“指针变量”。指针常量即不能改变指针所指向的值。即这样的代码是错误的:

int number = 0;

int a[10] = {0};

a = &number;

a虽然是一个整形指针,但是他是一个指针常量,不能将其值改变。

请不要根据数组名是指针这个事实得出指针和数组是相同的结论。数组具有一些和指针完全不同的特性。例如,数组具有确定的数量值,而指针只是一个标量值。

2.下标引用

在前面的声明的上下文环境中,下面这个表达式是什么意思呢?

*(b + 3);

首先,b的值是一个指向整形的指针常量。所以3这个值根据整形值得长度进行调整。加法运算的结果是另一个指向整形的指针,即 &b[3]。再通过*号对其解引用操作,相当于

*(&b[3])或者直接表示为b[3].

我们姑且可以这样认为:除了优先级顺序不同外,下标引用和指针间接访问完全相同。例如,下面这两个表达式是等同的:

array[subsricpt]

*(array + (subsript) )

让我们看一个例子,巩固复习一下刚才的知识

int array[10];

int *ap = array + 2;

在下面有关ap的表达式中,看看你能不能写出对应的array表达式:

ap ,这个很容易,&array[2]或者*(array + 2)

*ap ,这个也很容易,相当于对ap进行解引用操作,相当于array[2]或者*(array+2)

ap[0],将其转化成为*(ap + 0),即*ap,和上一个表达式等价。

ap+6,这个表达式相当于&array[2+6]或者*(array+2+6),即&array[8]或者

*(array+8)

*ap+6,小心,这里有两个操作符,不过间接访问的优先级高于加法操作,所以该式等价于array[2]+6

ap[6],你也许会疑问?这是错的吗?的确,在别的语言里他也许是错的,但是在C语言里他是正确的,我们说过,C语言中的下表操作与指针间接访问操作完全相同,即

*(ap+6)

&ap,这个表达式是完全合法的,它表示ap指针的地址,即指针的指针。

好了如果上面的问题都难不倒你的话,拿来看看下面这个:

2[ap]

是的,你没有看错,2[ap],不是ap[2].

他的答案也许会令你大吃一惊:它是合法的。把它转化成为对等的间接访问表达式,你就会发现它的有效性:

*(2 + (array))

内层的括号是多余的,即他和*(array + 2)是等价的。

3.关于指针和数组的效率

在此笔者不想通过反汇编来实验数组与指针的效率,读者暂时可以这样记住:

“假定这两种方法都是正确的,下标绝不会比指针更有效率,但是指针有时会比下标更有效率”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: