Chinaunix首页 | 论坛 | 博客
  • 博客访问: 470280
  • 博文数量: 62
  • 博客积分: 1742
  • 博客等级: 中尉
  • 技术积分: 859
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-06 00:13
个人简介

这是一句很长很长而且又很啰嗦并且很无聊的废话...

文章分类

全部博文(62)

文章存档

2013年(1)

2012年(13)

2011年(48)

分类: C/C++

2011-05-12 20:37:30

  1. #include <stdio.h>

  2. int main(char argc,char **argv){

  3.     int a[10];
  4.     printf("%p\n",a);
  5.     printf("%p\n",&a);
  6.     printf("%p\n",&a[0]);

  7.     int b[10][10];
  8.     printf("%p\n",b[0]);
  9.     printf("%p\n",&b[0]);
  10.     printf("%p\n",&b[0][0]);

  11.     printf("%p - %p\n",a,a+1);
  12.     printf("%p - %p\n",&a,&a+1);

  13.     printf("%p - %p\n",b[0],b[0]+1);
  14.     printf("%p - %p\n",&b[0],&b[0]+1);

  15.     return 0;
  16. }
  1. .file "test.c"
  2. .section .rodata
  3. .LC0:
  4. .string "%p\n"
  5. .LC1:
  6. .string "%p - %p\n"
  7. .text
  8. .globl main
  9. .type main, @function
  10. main:
  11. pushl %ebp
  12. movl %esp, %ebp
  13. andl $-16, %esp
  14. subl $480, %esp
  15. movl 8(%ebp), %eax
  16. movb %al, 28(%esp)
  17. movl $.LC0, %eax
  18. leal 440(%esp), %edx
  19. movl %edx, 4(%esp)
  20. movl %eax, (%esp)
  21. call printf
  22. movl $.LC0, %eax
  23. leal 440(%esp), %edx
  24. movl %edx, 4(%esp)
  25. movl %eax, (%esp)
  26. call printf
  27. movl $.LC0, %eax
  28. leal 440(%esp), %edx
  29. movl %edx, 4(%esp)
  30. movl %eax, (%esp)
  31. call printf
  32. leal 40(%esp), %edx
  33. movl $.LC0, %eax
  34. movl %edx, 4(%esp)
  35. movl %eax, (%esp)
  36. call printf
  37. movl $.LC0, %eax
  38. leal 40(%esp), %edx
  39. movl %edx, 4(%esp)
  40. movl %eax, (%esp)
  41. call printf
  42. leal 40(%esp), %edx
  43. movl $.LC0, %eax
  44. movl %edx, 4(%esp)
  45. movl %eax, (%esp)
  46. call printf
  47. movl $.LC1, %eax
  48. leal 440(%esp), %edx
  49. addl $4, %edx
  50. movl %edx, 8(%esp)
  51. leal 440(%esp), %edx
  52. movl %edx, 4(%esp)
  53. movl %eax, (%esp)
  54. call printf
  55. leal 440(%esp), %eax
  56. addl $40, %eax
  57. movl $.LC1, %edx
  58. movl %eax, 8(%esp)
  59. leal 440(%esp), %eax
  60. movl %eax, 4(%esp)
  61. movl %edx, (%esp)
  62. call printf
  63. leal 40(%esp), %eax
  64. leal 4(%eax), %ecx
  65. leal 40(%esp), %edx
  66. movl $.LC1, %eax
  67. movl %ecx, 8(%esp)
  68. movl %edx, 4(%esp)
  69. movl %eax, (%esp)
  70. call printf
  71. movl $.LC1, %eax
  72. leal 40(%esp), %edx
  73. addl $40, %edx
  74. movl %edx, 8(%esp)
  75. leal 40(%esp), %edx
  76. movl %edx, 4(%esp)
  77. movl %eax, (%esp)
  78. call printf
  79. movl $0, %eax
  80. leave
  81. ret
  82. .size main, .-main
  83. .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
  84. .section .note.GNU-stack,"",@progbits

同过上面的C代码和编译成汇编语言对比,可以看出,数组名a和&a,&a[0]的值都是440(%esp)里面的东西,也就是他们的地址是相同的.尽管如此,意义上却是两种东西,通过代码printf("%p - %p\n",a,a+1);printf("%p - %p\n",&a,&a+1);打印出来的值可以看出,他们两者之间的数据长度有差异,也就是指向的数据类型根本不一样!

引用网上的一段话:
比如:
   对数组名取地址在C标准里面是未定义的行为。由于数组名是右值,而&操作符要求操作数具有具体的内存空间,换言之就是一个变量,因此对数组名取地址本来就是非法的,早期的编译器明确规定这是非法的。不过不知道什么原因,现在的编译器多数把&array定义为一个值跟array相同,类型是一个指向数组的地址,注意了,是地址,不是指针。之所以是指向数组的地址,是因为array是一个数组名,它就代表了int array[10]这个数组。而ptr也是定义为一个指向具有10个int数的数组的指针,因此&array能被赋予ptr.也就是说数组名永远都不会是指针.

总结一下:在C里面,数组名只是一个单纯的地标标号(地址),它代表着该数组的首个元素的地址.一般情况下,他可以使用指针的方式访问数组成员.但是,如果对数组名进行取址操作(&),那么(&)表达式将返回一个指针变量,该指针指向一个数组类型对象,如果对该指针进行运算操作,那么他的偏移大小将是一个sizeof(数组对象).

阅读(904) | 评论(2) | 转发(1) |
0

上一篇:数组名

下一篇:一个可变参函数

给主人留下些什么吧!~~

limsco2011-05-13 21:03:35

好!受教了

limsco2011-05-13 21:03:18

好!受教了