深入浅出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.关于指针和数组的效率
在此笔者不想通过反汇编来实验数组与指针的效率,读者暂时可以这样记住:
“假定这两种方法都是正确的,下标绝不会比指针更有效率,但是指针有时会比下标更有效率”
我们看一下下面两个声明:
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.关于指针和数组的效率
在此笔者不想通过反汇编来实验数组与指针的效率,读者暂时可以这样记住:
“假定这两种方法都是正确的,下标绝不会比指针更有效率,但是指针有时会比下标更有效率”
相关文章推荐
- 一维指针与一位数组的关系(转载\整理)
- 一维数组、二维数组、字符数组、指针 相关的 sizeof 计算
- 从键盘输入十个整数存入一维数组中,求出它们的和及平均值并输出(要求用指针访问数组元素)?
- 多维数组用一维指针来读取数组的值
- 如何将一维数组借助指针复制到另一个数组,并输出新数组?
- 【C语言】12-指向一维数组元素的指针
- 一维数组 与指针 sizeof strlen int char
- c 和指针 二维数组赋予一维数组指针 数组长度 数组与指针长度区别
- 一维数组及指针
- 指向一维数组的指针学习笔记
- c_指针_一维数组名作为函数参数
- 【C语言】12-指向一维数组元素的指针
- 指针与一维数组,用指针指向数组,以及指针的使用
- 【C语言】12-指向一维数组元素的指针
- 二级指针用在一维数组上
- [指针二]指向一维数组、二维数组的指针使用
- C语言 指针与一维数组,指针遍历一维数组的多种方法
- 数组(一维和二维)与指针(C语言)
- 一维数组与指针
- 【C语言】12-指向一维数组元素的指针