【阅读前】

  本文是妆台秋思个人理解。毕竟操作系统设计人不是我(^_^ ^_^),我认为内存访问规则制定代表是微软。若有纰漏,请指出。

  【相同点】

  数组名本身就是指针,都涉及到系统底层的存储管理。对于进行系统底层或涉及到系统底层的应用程序编程,能应用于数组名的内存定位方法(通俗的说是寻找定位数组元素)也能应用于指针。例如:

  const int a[2]={1,2};
  int *b=a;

  用b[0]也能找到“1”。获取当前b的地址是:&b,获得a的地址是:b或者a。获得元素“2”的地址是a+sizeof(int)

  【不同点】

  主要集中在分配的内存上面。数组名没有自己的内存空间,它的地址也是第一个元素的地址。而指针则有sizeof(指针类型)大小的空间,例如:

  typedef struct aa
  {
    int a;
    int b;
    int *c;
    struct aa a*;
  }bb,*cc;
  bb bbExam;
  cc ccExam;

  此时bbExam得到的存储空间与ccExam是相同的,都是sizeof(int)+sizeof(int)+sizeof(int)+sizeof(bb),sizeof(bb)=(sizeof(int)+sizeof(int)+sizeof(int))*2。但是这个情况:

  bb bbExam[10];
  cc ccExam;

  则是不同的。前者是后者的10倍。

  【指针的一个重要应用】

  经常出现这样的情况:需要用到数组,但是数组的维数或者长度(数组元素个数)需要变动。普通的方法无法变动维数和长度,于是要用到指针,动态申请内存:

  ccExam=(cc)malloc(sizeof(bb))或者:ccExam=(bb*)malloc(sizeof(bb))

  删除数组元素:

  free(ccExam)

  加入数组:

  &bbExam[1]=ccExam

  【内存读或写错误】

  指针用来存储地址,而不是用来存储数据的,例如以下是正确的:

  bb bbExam[2]={0,0,0,0xFFFFFFFF,1,1,1,0xBBBBBBBB};
  cc ccExam=bbExam;//或者:cc ccExam=&bbExam[0];
  bb ddExam[2];
  bbExam=ccExam;

  以下是错误的:

  cc ccExam;
  bb ddExam[2];
  ddExam=ccExam;

  编译时不报错,因为语法确实没有错误。但是一运行就要出错:根据ccExam记录的地址访问数据导致访问当前程序没有权限访问的内存,它被操作系统拦截,并报出内存读错误。当前,只要将ccExam事先赋值为当前程序运行时所包含的内存地址就解决了,不过这样做没有意义。所以指针如果没有特殊用途,最好要初始化。肯定不能这样初始化:

  cc ccExam=0x00000000;

  00000000,这个地址是操作系统在使用的,0x00000000~0x000000FF一般存放中断向量表,操作系统肯定要拦截的。假设操作系统拦截失败,结果就是蓝屏或者整个系统死机了(具体什么结果要看这个程序要做什么事情了)。应该这样初始化:

  int a=0;
  int *p=&a;

  声明变量a时,就获得了一部分有权访问的内存了。如果觉得初始化烦人,那么,int *p=NULL或者只要指针赋值(是当前有权访问的地址)之前不使用它,就不会出错。

  【指针类型】

  指针本身不是一个独立的类型,不能用它来声明变量。需要借助其它实体类型才能声明变量。可以这么理解:指针用来告诉来访者这里存储的是值的地址,而不是值本身。

  【二重指针以及多重指针】

  指针产生原因包括数据处理过程中需要知道数据所在位置(也就是地址),但是同是不能影响数据本身,所以产生了用来记录数据地址的变量。数据类型本身是人为规定的,其约束方法就像HTTP协议约束方法一样。如果有人不服,那么他就不能用现成的,数据类型需要他自己去制定了。如果需要记录地址的数据本身是指针,那么该指针是多重指针。常见的有二重指针。有学者论证三重指针以及更深层次的指针没有应用意义,所以我们也只需要了解一下定义。就我个人而言,写了这么多程序,确实没有用过三重以及更深层次的指针。

  • 标 题:答复
  • 作 者:爱鸟
  • 时 间:2012-03-17 16:49:14

引用:
最初由 风铃草发布 查看帖子
呵呵,至少对于WINDOWS,所有内存都有它的访问权限。我知道你说的是CPU保护模式下对内存访问的管制,但是管制作用的发挥还是由操作系统来实现,不是吗?
数组名和指针本来没什么关系。

数组名 是一块内存地址的【名字】 就像门牌号指明了门的位置,又贴在门上面。
指针   是使用一块内存地址的【工具】 就像一把钥匙 可以开这个门 但是它和门没有任何关系

指针是真实存在计算机内存中的 比如
int a;
int *p =&a;
计算机确实有一个地方存放p (a的地址)

数组名是不存在与计算机内存中的 比如
int b[4]={1,2,3,4};
计算机没有一块地方来保存b这个东西 

这个就是数组和指针在本质上的区别 
而你举得例子 只是说明它们在语法上的通用性
这仅仅是为了方便你用  绝对不是本质 比如
int c[4] ={1,2,3,4};
int * p =c;
这时候你确实可以p[3](甚至你可以3[p]) 它们只是在形式上 = *(p+3) 此外不代表任何含义