user-0 提问: 数组与指针sizeof 

回复:
user: user-1
content: 引用 13 楼 fdsafwagdagadg6576 的回复:int a[5]={1,2,3,4,5}; printf("%x, %x,%x,%x\n", a, &a,a+1,&a+1); ffbee248, ffbee248,ffbee24c,ffbee25c a和&a 地址相同。 根据12楼的解释 &a + 1 在数值上等于 ((char *)&a) + sizeof(a); 为什么a+1不能这样算呢。 这是编译器的设计吗 原理上指针加1，就是指向下一个object a + 1: 这里的数组a退化成一个指针 pointer to ingeter, 所以 a + 1 在数值上等于 ((char *)a) + sizeof(a[0]);

user: user-0
content: int a[5]={1,2,3,4,5}; printf("%x, %x,%x,%x\n", a, &a,a+1,&a+1); ffbee248, ffbee248,ffbee24c,ffbee25c a和&a 地址相同。 根据12楼的解释 &a + 1 在数值上等于 ((char *)&a) + sizeof(a); 为什么a+1不能这样算呢。 这是编译器的设计吗

user: user-2
content: sizeof(数组名) -> 数组的大小 sizeof(指针) -> 指针的大小，在32位系统下是4个字节

user: user-3
content: sizeof(数组名) 求的是 数组的大小 数组名 不是指针 但神似指针 所以sizeof（数组名） =  sizeof(sizeof(数组类型)) * 数组大小

user: user-4
content: &a 数据类型是 int(*)[5] a 数据类型是 int[5] //ps是数组类型 pps 数组是一种数据类型 &a+1 数据类型是 int(*)[5] a+1 数据类型是 int*  你可以直接  sizeof(int[5]) sizeof(int*) 看到这些数据类型的大小

user: user-5
content: sizeof(a) = 4 * 5 = 20 其他的都是指针, 长度 4

user: user-1
content: 刚才的格式有问题  int a[5]; &a 的类型是 pointer to an array of five integers &a + 1 是指向下一个 five integers, 在数值上要加上 sizeof(a) = 4 * 5 = 20; 也就是说 &a + 1 在数值上等于 ((char *)&a) + sizeof(a); a--------------------&a+1--------------- ----------------------------------------- || 1 | 2 | 3 |4 | 5 || 1 | 2 | 3 |4 |5 || -----------------------------------------

user: user-1
content: 引用 5 楼 fdsafwagdagadg6576 的回复:int a[5]={1,2,3,4,5}; adl1=sizeof(&a+1); 结果是4  int *ptr11=(int*)(&a+1); printf ("%x",ptr11[-1]) 结果是5  为什么呢 int a[5]={1,2,3,4,5}; adl1=sizeof(&a+1); 结果是4 &a是个指针，指针 + 1还是指针 sizeof(指针) = sizeof( void *);   int *ptr11=(int*)(&a+1); printf ("%x",ptr11[-1])  int a[5]; &a 的类型是 pointer to an array of five integers &a + 1 是指向下一个 five integers, 在数值上要加上 sizeof(a) = 4 * 5 = 20; 也就是说 &a + 1 在数值上等于 ((char *)&a) + sizeof(a); a____________________&a+1________________ ----------------------------------------- || 1 | 2 | 3 |4 | 5 || 1 | 2 | 3 |4 |5 || -----------------------------------------                          这个在C89标准里有明确的说明  3.3.6 Additive operators  Syntax            additive-expression:                   multiplicative-expression                   additive-expression +  multiplicative-expression                   additive-expression -  multiplicative-expression  Constraints     For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integral type.  (Incrementing is equivalent to adding 1.)     For subtraction, one of the following shall hold:    * both operands have arithmetic type;    * both operands are pointers to qualified or unqualified versions of    compatible object types; or   * the left operand is a pointer to an object type and the right    operand has integral type.  (Decrementing is equivalent to subtracting 1.)  Semantics     If both operands have arithmetic type, the usual arithmetic conversions are performed on them.     The result of the binary + operator is the sum of the operands.     The result of the binary - operator is the difference resulting from the subtraction of the second operand from the first.     When an expression that has integral type is added to or subtracted from a pointer, the integral value is first multiplied by the size of the object pointed to.  The result has the type of the pointer operand.  If the pointer operand points to a member of an array object, and the array object is large enough, the result points to a member of the same array object, appropriately offset from the original member.  Thus if P points to a member of an array object, the expression P+1 points to the next member of the array object.  Unless both the pointer operand and the result point to a member of the same array object, or one past the last member of the array object, the behavior is undefined.  Unless both the pointer operand and the result point to a member of the same array object, or the pointer operand points one past the last member of an array object and the result points to a member of the same array object, the behavior is undefined if the result is used as the operand of a unary * operator.     When two pointers to members of the same array object are subtracted, the difference is divided by the size of a member.  The result represents the difference of the subscripts of the two array members.  The size of the result is implementation-defined, and its type (a signed integral type) is ptrdiff_t defined in the <stddef.h> header.  As with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined.  If two pointers that do not point to members of the same array object are subtracted, the behavior is undefined.  However, if P points either to a member of an array object or one past the last member of an array object, and Q points to the last member of the same array object, the expression (Q+1) - P has the same value as (Q-P) + 1 , even though Q+1 does not point to a member of the array object.

user: user-6
content: 嗯，指针一般都占四个字节，一楼回答一针见血 另外，提醒一下楼主，代码中的标识符最好不要用L（大小写都不要用），容易让人误会

user: user-7
content: 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

user: user-0
content: printf ("%x",ptr11[-1]) 结果是5  为什么呢   自己顶

user: user-8
content: &a是求存储数组a[5]的首地址的地址，而地址是long型的，是4个字节，所以adl为4； sizeof（数组首地址）相当于求整个数组所占的字节数，所以al=5*sizeof（a[0]）=5*4=20,其中5为数组个数； adl1其实相当于求一个long型数据的字节数，即为4，千万不要被a所迷惑了，只要一对a取地址，所得即为指向数组首地址的地址； al1相当于sizeof(a[1]),所以即为4.

user: user-0
content: int a[5]={1,2,3,4,5}; adl1=sizeof(&a+1); 结果是4  int *ptr11=(int*)(&a+1); printf ("%x",ptr11[-1]) 结果是5  为什么呢