数组与指针寻址访问元素区别

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int nArray[] = { 1,2,3,4 };
    int* pt = NULL;

    pt = nArray;

    printf("%d\n", nArray[1]);

    printf("%d\n", *(pt+1));

    return 0;
}
    int nArray[] = { 1,2,3,4 };
00FD1832  mov         dword ptr [nArray],1  ;初始化数组,nArray作为数组首地址
00FD1839  mov         dword ptr [ebp-14h],2  
00FD1840  mov         dword ptr [ebp-10h],3  
00FD1847  mov         dword ptr [ebp-0Ch],4  
    int* pt = NULL;
00FD184E  mov         dword ptr [pt],0;初始化指针  

    pt = nArray;
00FD1855  lea         eax,[nArray]  ;取数组首元素地址作为指针的值
00FD1858  mov         dword ptr [pt],eax  

    printf("%d\n", nArray[1]);
00FD185B  mov         eax,4  ;数组第2个元素的相对于数组首地址的偏移地址
00FD1860  shl         eax,0  
00FD1863  mov         ecx,dword ptr nArray[eax]  ;取值
00FD1867  push        ecx  
00FD1868  push        offset string "%d\n" (0FD7B30h)  
00FD186D  call        _printf (0FD1046h)  
00FD1872  add         esp,8  

    printf("%d\n", *(pt+1));
00FD1875  mov         eax,dword ptr [pt]  ;取指针存放的地址
00FD1878  mov         ecx,dword ptr [eax+4]  ;从指针存放的地址获取元素
00FD187B  push        ecx  
00FD187C  push        offset string "%d\n" (0FD7B30h)  
00FD1881  call        _printf (0FD1046h)  
00FD1886  add         esp,8  

 

因此,数组和指针的寻址,指针比数组多出一步解引用指针。

数组直接根据相对于数组首地址的偏移地址获取元素,而指针需要先解引用指针,再根据指针中的地址获取元素。

 

最后再介绍一个越界访问。

#include <stdio.h>
#include <stdlib.h>


int main(void)
{
    int nArray[] = { 1,2,3,4 };
    int test_val = 5;
    int* pt = NULL;

    pt = nArray;

    printf("%d\n", nArray[-1]);

    printf("%d\n", *(pt-1));

    return 0;
}
7:        int nArray[] = { 1,2,3,4 };
00401028   mov         dword ptr [ebp-10h],1
0040102F   mov         dword ptr [ebp-0Ch],2
00401036   mov         dword ptr [ebp-8],3
0040103D   mov         dword ptr [ebp-4],4
8:        int test_val = 5;
00401044   mov         dword ptr [ebp-14h],5
9:        int* pt = NULL;
0040104B   mov         dword ptr [ebp-18h],0
10:
11:       pt = nArray;
00401052   lea         eax,[ebp-10h]
00401055   mov         dword ptr [ebp-18h],eax
12:
13:       printf("%d\n", nArray[-1]);
00401058   lea         ecx,[ebp-10h];取数组首地址
0040105B   mov         edx,dword ptr [ecx-4];取地址ebp-14中的元素,即test_val=5
0040105E   push        edx
0040105F   push        offset string "%d\n" (0042201c)
00401064   call        printf (004010c0)
00401069   add         esp,8
14:
15:       printf("%d\n", *(pt-1));
0040106C   mov         eax,dword ptr [ebp-18h];取指针中存放的指针首地址
0040106F   mov         ecx,dword ptr [eax-4]
00401072   push        ecx
00401073   push        offset string "%d\n" (0042201c)
00401078   call        printf (004010c0)
0040107D   add         esp,8

 

 

上面反C代码的汇编代码,编译器不同,结果可能也不同。

posted @ 2019-10-27 14:56  Hk_Mayfly  阅读(517)  评论(2)    收藏  举报