int arr[] ={1,2,3,4,5}; int *p=arr;

int arr[] ={1,2,3,4,5};
int *p=arr;
*p++;

printf("%d\n",*p);

我有疑问, 如果printf("%d\n",arr); 的话,那不能compile, arr的本质是个int *, 也就是个pointer,是指向arr【0】的地址。 可是为什么*p就是个int呢? *p=arr啊,而且arr++也不行,因为arr是个int[ ] 但是*p就可以。
c语言为什么在这里不一致呢?
而且,*p++以后 print *p 得到2, 若是p++,那依次得到2,2,3,4,5 请问这个过程发生了什么?谢谢

c/c++语言奇葩之一 是指针的形式逻辑不成立。外貌相同的形式,在语句里的意思不同于在声明里的意思。
必须分清,事情发生在声明里,还是语句里。

int *p; // 这是声明,*p 声明 p 是指针,p 只能用来指向 int 型地址
int *p=arr; // 这是声明加初始化,*p 声明p 是指针,p 只能用来指向 int 型地址,初始化让它指向数组arr 的 首地址,也就是 p=&arr[0];

*p++; // 这是语句,*p 是 p指向的存储单元里的值,现在要 自增1。也就是执行了 arr[0]=arr[0]+1;
p++; // 这是语句,p 是地址, p++ 是 "p 的地址 加 sizeof(int)"

printf("%d\n",arr); // 这是语句,arr 不是指针,而是数组,
你要想打印地址: printf("%u\n", &arr[0]); 或 printf("%p\n", &arr[0]);
你要想打印第一个元素的值: printf("%d\n", arr[0]);

语句里有恒等式: arr[i] = *(arr + i); 指针 与 数组 的 恒等 关系。
你要想打印第i个元素的值: printf("%d\n", arr[i]); 或 printf("%d\n", *(arr + i) );

同样,语句里有恒等式:*(p+i) = p[i]; (这是数值)
加上你初始化声明了 p=arr,所以语句里有 :*(p+i) = p[i] = arr[i] 的数值关系 (是数值)

搞通了这些基本概念,你的问题便可迎刃而解了。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-01-29
指针就是指针,数组就是数组,它们本不是一路货,可以说毫不相干。但类型兼容的指针一旦指向了数组,就可以像操作数组名一样操作指针来访问各元素;而数组名可以作为一个指针常量使用,与一个整型数结合作增量像操作指针一样来访问各元素。这种现象把指针与数组的“距离”拉近了,使人们产生了错觉,以为指针与数组有什么必然联系!至于*p=arr的疑问,显然这里*p=arr写法是错误的,只有int *p=arr才是正确的,int *p=arr是一种“综合”写法,把它分开则是:int *p;p=arr;。你看,p=arr的p前面本就没有*吧。这说明int *p中的*不是p的,而是int的,它是“声明一个int *型指针p“的意思,而"不是"声明一个int型变量*p!我想剩下的你已清楚了,就自己琢磨吧……
第2个回答  2014-01-29
你把int和 int *搞混了。
Q:我有疑问, 如果printf("%d\n",arr); 的话,那不能compile,
A:compile会出错的原因是,%d需要整形,而arr是指针型。
Q:arr的本质是个int *, 也就是个pointer,是指向arr【0】的地址。可是为什么*p就是个int呢?
A:没错,arr是int *。不过,你没有定义*p这个变量,你定义了一个p变量(指针变量),类型是int *。因为p是int *,所以p可以等于arr;(而不是*p=arr)。你可以把p的定义看成(char *) p = arr;
变量名没有*开头的。

Q:*p=arr啊,而且arr++也不行,因为arr是个int[ ] 但是*p就可以。
A:不是*p=arr,而是p=arr。arr不能++,是因为arr的类型相当于const int *,是个只读变量,类似常量,所以不能修改。

Q:若是p++,那依次得到2,2,3,4,5 请问这个过程发生了什么?
A:*p++这个表达式,根据运算符优先级,++的优先级比*高,所以相当于*(p++)(先自增,再取值)。当p=arr的时候,就是p=&arr[0](arr前面有个地址符&)。当p++后,就相当于p=&arr[1]。所以输出对应的结果。
相似回答