C指针基础(四)
2017-03-14 22:02
148 查看
这篇文章我们来一起讨论一下指针与数组。指针与数组密不可分,但是绝不能将二者混为一谈。
通常情况下,
第一个栗子:一维数组求和
上面的例子中,我们将p指向数组a的第一个元素,然后依次对指针p自增从而遍历整个数组。你可能会怀疑
第二个栗子:二维数组的求和
如果我们要对一个二维数组进行求和,通常我们会用两个嵌套的
第三个栗子:二维数组的第i行求和
上面的代码很容易理解,但是我们可以进一步简化。
同样,第二个栗子的代码也可以简化成这样:
因为a[0]指向数组第i行的第一个元素,同样也是数组的第一个元素。
第四个栗子:二维数组的第i列求和
上面的代码有些晦涩。在声明中,我们把
其实,上面的代码还可以进一步简化:
理解上面这个代码,必须首先要理解
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
数组名用作指针
我们可以用数组的名字作为指向数组第一个元素的指针。因此通常情况下,a+i等同于
&a[i],
*(a+i)等同于
a[i],其中a是数组名。于是我们可以这样操作:
int a[100]; *a = 7; // 数组第一个元素赋值7 *(a+2) = 4; // 数组第2个元素赋值4
指针用作数组名
既然我们可以用数组名作为指针,那么反过来也是可以的。int a[9], *p = a; p[3] = 5; // 数组a的第三个元素赋值5
通常情况下,
p[i]可以看作
*(p+i)。
用指针处理数组
了解了上面的用法后,我们可以很轻松地用指针来处理数组。下面我们来吃几个栗子。第一个栗子:一维数组求和
#define N 10 ... int a , sum, *p; ... sum = 0; for (p = &a[0]; p < &a ; p++) sum += *p;
上面的例子中,我们将p指向数组a的第一个元素,然后依次对指针p自增从而遍历整个数组。你可能会怀疑
p < &a的用法,其实这样做是完全正确的。即使元素
a不存在,但是对它使用取地址运算符也是合法的。
第二个栗子:二维数组的求和
#define R 9 #define C 8 int a[R][C]; int *p, sum = 0; ... for (p = &a[0][0]; P <= &a[R-1][C-1]; p++) sum += *p;
如果我们要对一个二维数组进行求和,通常我们会用两个嵌套的
for循环,但是如果我们有了指针的话,我们只用一个循环就可以搞定,只不过可读性变差了。
第三个栗子:二维数组的第i行求和
... int a[R][C], *p, i; ... for (p = &a[i][0]; p < &a[i][C]; p++) sum += *p;
上面的代码很容易理解,但是我们可以进一步简化。
&a[i][0]指向第i行的第一个元素,而对于二维数组,
a[i]即为指向第i行的第一个元素的指针,因此我们完全可以用
a[i]代替
&a[i][0],同理可以用
a[i]+C代替
&a[i][C]。
int a[R][C], *p, i; ... for (p = a[i]; p < a[i] + C; p++) sum += *p;
同样,第二个栗子的代码也可以简化成这样:
... int a[R][C]; int *p, sum = 0; ... for (p = a[0]; P < a[R]; p++) sum += *p;
因为a[0]指向数组第i行的第一个元素,同样也是数组的第一个元素。
第四个栗子:二维数组的第i列求和
int a[R][C], (*p)[C], i, sum = 0; ... for (p = &a[0]; p < &a[R]; p++) sum += (*p)[i];
上面的代码有些晦涩。在声明中,我们把
p指向长度为
C的整型数组的指针,在
(*p)[C]中,
*p是需要使用括号的;如果没有括号,编译器将认为
p是指针数组,而不是指向数组的指针。表达式
p++把
p移动到下一行的开始位置。在表达式
(*p)[i]中
*p表示
a的一整行,因此
(*p)[i]选中了该行第i列的那个元素。如果你还是不懂的话,你可以联想一下一维数组的声明方法
int a[C],再看看这里
p的声明
(*p)[C],是不是可以对应上呢?
(*p)可以对应数组a的名字
a,而
p对应
&a。
(*p)[i]中的括号是必要的,因为编译器会将
*p[i]解释为
*(p[i])。
其实,上面的代码还可以进一步简化:
int a[R][C], (*p)[C], i, sum = 0; ... for (p = a; p < a+R; p++) sum += (*p)[i];
理解上面这个代码,必须首先要理解
a(记住此时数组为二维数组)的含义。a不是指向
a[0][0]的指针,而是指向
a[0]的指针。因此
&a[0]就可以简化为
a。
参考资料
C语言程序设计现代方法, K.N.King, 人民邮电出版社本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
相关文章推荐
- C++学习(2)--基础知识(2)--指针复习
- C语言程序设计基础讲座之指针的慨念
- 梁文轩 指针基础 1
- C/C++基础知识:函数指针和指针函数的基本概念
- C陷阱和指针基础(三)
- C语言基础之指针取地址问题
- 【转载】指针基础
- 指针基础总结
- C++基础:指针,函数指针
- C语言程序设计基础讲座之指针的慨念
- 野指针,以及c++中的野指针[基础讲座]
- c语言 指针基础
- 函数指针。。。超级无敌的基础了
- C++基础:指针和const限定符
- 野指针,以及c++中的野指针[基础讲座]
- 指针的基础理解,以及引用的理解
- C 基础 (数组与指针)
- 汇编语言基础之七- 框架指针的省略(FPO)
- C++基础之:引用与指针的区别
- 指针的基础知识