当前位置:编程学习 > C/C++ >>

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

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.关于指针和数组的效率
在此笔者不想通过反汇编来实验数组与指针的效率,读者暂时可以这样记住:
“假定这两种方法都是正确的,下标绝不会比指针更有效率,但是指针有时会比下标更有效率”


 摘自 Kernel & UI 
补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,