关于C语言中,指针变量与char int double等变量分配内存的问题??

如:
char a[3],*p;p=a;
编译器给char 型分配1个字节,而给指针都分配4个字节,当执行:
for(i=0;i<3;i++)
printf("%x %x",&a[i],p++);显示内存地址都相同。请问这里输出的内存地址是不是编译器分配给char型变量和其指针变量的首地址,只占1个字节?
如果是这样,那占4个字节的完整地址该如何知道,而且显然另3个字节地址与输出的地址数值上并不连续啊?如果不是这样,那二者分配的内存又是什么?
换做double double *(double 占8个字节而指针所指向它的地址却只占4个字节),这岂不矛盾么??
真的想不通啊,也不知道是否问清楚,请大家帮我解答一下,先谢谢了。
可能是我没问清楚,1,2l的回答不太理解,3L的解释还明白一些。想再请问一下,指针指向的最小单元是不是一个字节,double a;dounle *p;p=&a中,p是不是指向存储a的内存中第一个字节?? 我会加分谢谢!!

LZ的理解基本是正确的。不过有些概念上的欠缺,补充一下:
地址是表示存储器中存储单元位置的非负整数。所有可用的地址的集合称为地址空间。现代的编译器中,对象指针的值是同一地址空间的元素。在32位编译器中,这个值的上限是2^32-1。
对象是运行期内存中的数据存储区域,这片区域是连续的。指针指向对象,则它的值等于对象的首个字节的地址。对象的大小可以在编译期根据类型确定,因此在确定的时刻,指针(包含被指对象的类型)可以唯一地确定对象的存储。
指针:一类类型的统称。指针类型的实例是表达式,可能是一个对象。有时候把指针对象简称为指针,注意不要混淆。
左值和右值:表达式中的左值具有对象语义,而右值没有。通俗点说左值可以出现在赋值操作符=的左边,而右值不可以(C语言中右值可以简单地理解成值)。&操作符作用于一个左值,获得一个右值指针。
对象地址作为按字节编址的内存单元的编号,最小单位是1(对应于一个字节),且必定是地址空间内的元素。指针的值用来表示地址。所以,指针不能指向小于一个字节的存储区域(位段),使用&操作符试图获得指向它的指针是非法的。
char a[3],*p;声明了两个对象:类型为char[3]的a、类型为char*的p。p=a;使p的值等于a——由于p和a的类型不同,所以显然发生了静态类型转换才能保证表达式的合法性。表达式a在这里并不作为左值而是隐式地转换成一个char*类型的指针(不是对象,而是临时对象,或者精确地说,一个不在运行期占据存储空间的右值),等于&a[0]的值,即a[0]的地址。注意数组元素的地址是编译期就能确定的常量,所以并不需被分配空间,不用存储在对象中。数组a的地址&a(由于数组的存储方式,这个值等于&a[0]的值)作为常量直接被编译到目标代码中,而不是在运行期再计算出来。这里需要计算的是&a[i],因为i的值是不能在编译期唯一被确定的。&a[i]相当于a+i,a在这里同样隐式转换为指针右值。根据指针的加法规则,a+i等于(char*)((int)a+sizeof(char)*((int)i))(这里用显式类型转换指出表达式的类型,下同)。同时,p是和a对应类型的指针,它每次被++后,效果相当于p=(char*)((int)p+sizeof(char)*1)。由于i每次增加1,因此可见增加的部分的数值是同步的;而p=a导致它们的初值是相等的。因此循环体中每次输出的值相等。
====
[原创回答团]

参考资料:原创

温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-11-26
因为现在大部分电脑都是32位的系统,也就是有2的32次方个内存地址,所以每个字节的内存地址就需要用32位整数来表示,也就是一个32位的地址要用4字节保存。所以指针变量都是占4字节。
第2个回答  2010-11-26
一个字节有8个二进制位,4个字节就是32位,32位机的最大内存寻址范围就是32位,所以一个指针占4个字节完全够存一个指向任何内存的地址,至于这个地址存多少字节和指针无关,指针与内存关系就好比一个地址与仓库一样,仓库存多少东西,和地址没有任何关系。
上面"&a[i]取的是地址,4个字节,p++,p也是完整地址,不是一个字节,4个字节指针是个整体,不能被拆分。
第3个回答  2010-11-26
百度一下就有
相似回答