为什么要使用指针
- 指针的值是它所指向对象的地址。地址的表示方式依赖于计算机内部的硬件。许多计算机都是按照字节编址的,意思时内存中的每一个字节都按顺序编号,这里,一个较大的地址通常是该对象的第一个字节的地址。
- 因此,使用指针会更加的有效率,能够很好的处理数组,数组表示法其实是在变相的使用指针。
标题
#include "stdio.h"
int main(){
int data[4][2] ={
{
2,4}, {
6,8}, {
1,3}, {
10,11}};
return 520;
}
对于这样一个二维数组,我们来整理一波指针与二维数组的对应关系:
1. data是数组首元素的地址 因此data=&data[0]
2. *data=data[0] **data=data[0][0]
3. data[1][2]=*(*(data+1)+2)
前两条结论很简单,但是第三题结论理解起来可能有点难度,现在我们来剖析一下第三条结论.
data ← 二维数组首元素地址
data+1 ← 二维数组的第二个元素(即一维数组)的地址
*(data+1) ←二维数组的第第二个元素(即一维数组)的首元素
*(data+1)+2 ←二维数组的第二个元素(即一维数组)的第三个元素(一个int类型的值)的地址
*(*(data+1)+2)←二维数组的第二个元素的第三个int类型元素的值
不知道说到这里有没有说清楚呢?
这个图便形象的展示了数组的数组。
指向多维数组的指针
如何声明一个指针变量pz指向一个二维数组呢? 在编写类似data这样的二维数组时会用到这样的指针,把指针声明为指向int的类型还不够。因为指向int只能与data[0]的类型匹配,说明该指针指向一个int类型的值,但是data是他首元素的地址,而该元素是一个内含两个int类型值的一维数组,因此,pz必须指向一个内含两个int类型值的数组,而不是指向一个int类型值。
int (*pz)[2]; //pz指向一个内含两个int类型值的数组
int *pax[2]; //pax是一个内含两个指针元素的数组,每个元素都指向int类型的指针
这两种声明有何细节可言呢?
前者使用圆括号,是因为[]的优先级要高于*,因此*先与pz结合,因此声明的是一个指向数组(内含两个int类型的值)的指针。
对于后者,由于[]优先级高,先于pax结合,所以pax成为一个内含两个元素的数组,然后星号表示pax数组内含有两个指针。最后int表示pax数组中的指针都指向int类型的值。因此,后者声明了两个指向int的指针。
相信讲到这里,大家对指针判别的方式又有了一种参考。
指针的兼容性
数值类型之间的赋值:
int n=5;
double x;
x=n; //隐式类型转换
指针的赋值:
int *pl=&n;
double &pd=&x;
pd=pl; //编译时错误
指针之间的赋值比数值类型之间的赋值要严格
关于C与C++中的const
const在数组中的应用常常是定义在形参中防止数组内容被修改。
#include "stdio.h"
void excute(const int a[]){
/*......... */
/* 接下来的操作可以防止数组被修改 */
}
int main(){
int a[100];
/* ........... */
excute(a);
return 520;
}
C和C++中const的用法很相似,但是并不完全相同。区别之一是,C++允许在声明数组大小时使用const整数,而C却不允许。区别之二是,C++的指针赋值检查更严格:
const int y;
const int *p2=&y;
int *p1;
p1=p2; //C++中不允许这么做,但是C可能只会给出警告
C++不允许把const指针赋给非const 指针。而C则允许这样做,但是如果通过p1更改y,其行为是未定义的。
希望这篇文章给大家带来帮助,有不好的地方也欢迎多多指正。