指针与数组的区别

  以前上课的时候老师说,将数组名作为指针来使用,一直是这样认为。后来在论坛中看到其实是错的,不过不明其理,十一期间在网上发现了关于数组与指针的文章,将其翻译了,与大家共享(对使用的代码做了一点修改)。首次翻译文章,希望大家多多指点,谢谢!!


   本文翻译至:http://www.cplusplus.com/forum/articles/10/


  非常感谢那些有帮助的教程,我觉得有必要发表这篇关于指针和数组文章。不幸的是要从一些错误的观念恢复有点困难。所以正确和精确的理解问题是非常重要的,可以避免进一步的误解。

  一个数组并不等于一个指针。在内存中,它是简单变量的序列。

  当我们写:

  1. int array[3];
  2. array[2]=66;

  C/C++编译器并不将array[0]看作是一个整型数值的地址,可以直接将它作为一个值,与下面的写法完全一样。

    int var;
    var=66;
 

明显的,var不是指针,同样的array[2]也不是指针。

  但是,如果我们使用一个指针代替数组,对于同样的代码,不同的编译器所生成的汇编程序是不同的。例如:

  1. int *ptr = new int[3];
  2. ptr[2] = 66;

  类似的,对于第一种代码,在编译器中没有不同的意思。第一中代码(第二行),编译器将会进行以下的步骤来生成的代码
    1)转到array[0]的下面两个空间,并且使它等于66
  在使用指针的代码中,它是这样的:
    1)取得ptr[0]的值(地址)
    2)给它加上2
    3)将它所指向的值设为66
  事实上,array、&array和&array[0]的值使相等的。但是&array是不同的类型(一个数组的内存地址而不是数组成员)
这里还有另外一个例子,使得你更容易理解这篇文章。我写了这样的程序:获取用户输入的一个值,给它加上4,最后将结果打印出来。我用整型指针和整型变量各写了一次。
使用整型变量:

  1. #include<iostream>
  2. int main(){
  3.     int int_input;
  4.     std::cin >> int_input;
  5.     std::cout<< (int_input + 4) << std::endl;
  6.     return 0;
  7. }

使用指针:

  1. #include<iostream>
  2. int main(){
  3.     int *int_ptr = new int[1];
  4.     std::cin >> *int_ptr;
  5.     std::cout << (*int_ptr + 4) << std::endl;
  6.     delete(int_ptr);
  7.     return 0;
  8. }

  有人认为这些程序是完全相同的吗?
  让我们来看看它们的汇编代码。首先是整型变量的:

  1. 2212: main(){
  2. 00401000   push        ebp
  3. 00401001   mov         ebp,esp
  4. 00401003   sub         esp,44h
  5. 00401006   push        ebx
  6. 00401007   push        esi
  7. 00401008   push        edi
  8. 2213:     int int_input;
  9. 2214:     cin>>int_input;
  10. 00401009   lea         eax,[ebp-4]
  11. 0040100C   push        eax
  12. 0040100D   mov         ecx,offset cin (00414c58)
  13. 00401012   call        istream::operator>> (0040b7c0)
  14. 2215:     cout<<(int_input+4)<<endl;
  15. 00401017   push        offset endl (00401070)
  16. 0040101C   mov         ecx,dword ptr [ebp-4]
  17. 0040101F   add         ecx,4
  18. 00401022   push        ecx
  19. 00401023   mov         ecx,offset cout (00414c18)
  20. 00401028   call        ostream::operator<< (0040b3e0)
  21. 0040102D   mov         ecx,eax
  22. 0040102F   call        ostream::operator<< (00401040)
  23. 2216:     return 0;
  24. 00401034   xor         eax,eax
  25. 2217: }

使用指针汇编代码

  1. 2212: main(){
  2. 00401000   push        ebp
  3. 00401001   mov         ebp,esp
  4. 00401003   sub         esp,4Ch
  5. 00401006   push        ebx
  6. 00401007   push        esi
  7. 00401008   push        edi
  8. 2213:     int *int_ptr = new int[1];
  9. 00401009   push        4
  10. 0040100B   call        operator new (004011b0)
  11. 00401010   add         esp,4
  12. 00401013   mov         dword ptr [ebp-8],eax
  13. 00401016   mov         eax,dword ptr [ebp-8]
  14. 00401019   mov         dword ptr [ebp-4],eax
  15. 2214:     cin>>*int_ptr;
  16. 0040101C   mov         ecx,dword ptr [ebp-4]
  17. 0040101F   push        ecx
  18. 00401020   mov         ecx,offset cin (00414c38)
  19. 00401025   call        istream::operator>> (0040b8a0)
  20. 2215:     cout<< (*int_ptr + 4)<<endl;
  21. 0040102A   push        offset endl (004010a0)
  22. 0040102F   mov         edx,dword ptr [ebp-4]
  23. 00401032   mov         eax,dword ptr [edx]
  24. 00401034   add         eax,4
  25. 00401037   push        eax
  26. 00401038   mov         ecx,offset cout (00414bf8)
  27. 0040103D   call        ostream::operator<< (0040b4c0)
  28. 00401042   mov         ecx,eax
  29. 00401044   call        ostream::operator<< (00401070)
  30. 2216:     delete(int_ptr);
  31. 00401049   mov         ecx,dword ptr [ebp-4]
  32. 0040104C   mov         dword ptr [ebp-0Ch],ecx
  33. 0040104F   mov         edx,dword ptr [ebp-0Ch]
  34. 00401052   push        edx
  35. 00401053   call        operator delete (00401120)
  36. 00401058   add         esp,4
  37. 2217:     return 0;
  38. 0040105B   xor         eax,eax
  39. 2218: }

  第19行对第32行。因此,你可以看出整数不同于“指向整数的指针”。一个整数是保存整数数据在内存空间,而一个整型指针是保存一个地址的内存空间。当要处理一个整数时,编译器知道这是一个内存空间的地址。我不打算解释这些汇编代码,因为这文章是针对初学者写的,我希望保持它的简短。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值