the difference between pointer and array (and variable)

the difference between pointer  and array (and variable)
/********************************test,c*********************** song 8.13 *************************************************************/ #include<stdio.h> int i=6; int cc[9]={1,2,3,4,5,6,7,8,9}; int * const pa=cc;//注意const的位置:不是const int * pa, int * ppa=cc; int bb[2][3]={{0x50,0x51,0x52},{0x53,0x54,0x55}}; int main() { i=3; i=3; *(cc+1)=6; *(pa+1)=8; *(ppa+1)=9; *(*(bb+1)+1)=0x99; i=2; i=2; printf("%x\n",i); printf("%x\n",*(cc+1)); printf("%x\n",*(pa+1)); printf("%x\n",*(ppa+1)); printf("%x\n",*(*(bb+1)+1)); printf("%x\n",cc); printf("%x\n",pa); printf("%x\n",ppa); printf("%x\n",bb); printf("%x\n",&i); printf("%x\n",&cc); printf("%x\n",&pa); printf("%x\n",&ppa); printf("%x\n",&bb); }
[root@localhost mmap]# ./test 2 9 9 9 99 8049800 8049800 8049800 8049828 80497e0 8049800 8048634 8049824 8049828 
//print sections [root@localhost mmap]# readelf -S test [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [15] .rodata PROGBITS 08048628 000628 000014 00 A 0 0 4 [24] .data PROGBITS 080497c0 0007c0 000080 00 WA 0 0 32 
//print symblols [root@localhost mmap]# readelf -s test Num: Value Size Type Bind Vis Ndx Name 46: 08048634 4 OBJECT GLOBAL DEFAULT 15 pa 53: 08049800 36 OBJECT GLOBAL DEFAULT 24 cc 57: 080497e0 4 OBJECT GLOBAL DEFAULT 24 i 62: 08049828 24 OBJECT GLOBAL DEFAULT 24 bb 65: 08049824 4 OBJECT GLOBAL DEFAULT 24 ppa 
[root@localhost mmap]# objdump -s test Contents of section .rodata: 8048628 03000000 01000200 00000000 00980408 ................ /* the address of pa is starting from 8048634 ,length 4 bytes,it's content is "00980408" displaying as little endian actually it is 08049800---the address of cc */ Contents of section .data: 80497c0 00000000 00000000 00000000 00000000 ................ 80497d0 00000000 00000000 00000000 00000000 ................ 80497e0 06000000 00000000 00000000 00000000 ................ 80497f0 00000000 00000000 00000000 00000000 ................ 8049800 01000000 02000000 03000000 04000000 ................ 8049810 05000000 06000000 07000000 08000000 ................ 8049820 09000000 00980408 50000000 51000000 ........P...Q... 8049830 52000000 53000000 54000000 55000000 R...S...T...U... /* the address of cc is starting from 08049800 ,4*9=36 bytes length ,we can see it's content is 1 2 3 4 5 6 7 8 9 from data section the address of bb is starting from 08049828 , 4*2*3=24 bytes length cotent is 50 51 52 53 54 55 the address of i is starting from 080497e0 , 4 bytes length,cotent is 6 the address of ppa is starting from 08049824 , the length and cotent are the same as pa located in rodata section */ 

可用下图表示变量,指针,数组的内存分分配

www.zeeklog.com - the difference between pointer and array (and variable)


[root@localhost mmap]# objdump -S test 080483c4 <main>: 80483c4: 8d 4c 24 04 lea 0x4(%esp),%ecx 80483c8: 83 e4 f0 and $0xfffffff0,%esp 80483cb: ff 71 fc pushl -0x4(%ecx) 80483ce: 55 push %ebp 80483cf: 89 e5 mov %esp,%ebp 80483d1: 51 push %ecx 80483d2: 83 ec 14 sub $0x14,%esp 80483d5: c7 05 e0 97 04 08 03 movl $0x3,0x80497e0//i=3; 80483dc: 00 00 00 80483df: c7 05 e0 97 04 08 03 movl $0x3,0x80497e0//i=3; 80483e6: 00 00 00 /*$表示一个立即数,%表示一个寄存器,( )表示寄存器间接寻址 编译器将i用其地址0x80497e0替换掉 翻译为将立即数3移到内存单元0x80497e0*/ 80483e9: b8 04 98 04 08 mov $0x8049804,%eax//*(cc+1)=6; 80483ee: c7 00 06 00 00 00 movl $0x6,(%eax) /* 编译器将cc+1用cc+1所表示的地址值替换掉 cc+1-->8049800+4=8049804 编译器将*(cc+1)翻译为将计算出来的地址塞进累加器eax, 利用寄存器间接寻址将立即数6塞进内存单元8049804 */ 80483f4: a1 34 86 04 08 mov 0x8048634,%eax//*(pa+1)=8; 80483f9: 83 c0 04 add $0x4,%eax 80483fc: c7 00 08 00 00 00 movl $0x8,(%eax) /* 编译器将pa用pa之地址替换下来 编译器将*(pa+1)翻译为将pa地址8048634塞进eax 执行+1操作,即eax=8048634+4=8048638 将立即数塞进8048638内存单元 */ 8048402: a1 24 98 04 08 mov 0x8049824,%eax//*(ppa+1)=9; 8048407: 83 c0 04 add $0x4,%eax 804840a: c7 00 09 00 00 00 movl $0x9,(%eax) /* 同*(pa+1)=8; 可以看出,指针常量和指针都被编译器翻译成一样的代码, 数组名cc+1,cc[1]等都是编译器编译时执行的的运算 pa+1是程序运行时执行的运算 所以,数组名只是一个c语言的规定,用于编译器计算数组元素的地址值, c语言在数组范畴规定了这么多的东西,要求我们按照他说的规范去写,然后他在编译的时候,直接套用 规范计算出实际地址,而不是在程序运行的时候去计算 指针常量和指针都是有一个32b的内存单元来装其值得 数组名没有 数组名在内存中更像是普通变量(的集合) 但是在c语言中,大部分场合,要将数组名"假想"作一个指针去用, 这是c语言规范,因为 编译时,是将数组名当做指针对待 比如将cc[1]先在内部译成*(cc+1) 这也就解释了指针也可以写成数组的形式,因为即使你写成了数组的形式(不管实际是数组还是指针) ,编译器还是会将其换成指针 一下来自 thq c程序设计 int *p; int a[10]; p=&a[0](或p=a); 则 p+i,a+i都是a[i]的地址.a[i]也可写作p[i] *(p+i),*(a+i)都是p+i或a+i指向的数组元素即a[i]的值 比如p+2,代表a[2]的地址,或说p[2]的地址 */ 8048410: b8 28 98 04 08 mov $0x8049828,%eax//*(*(bb+1)+1)=0x99; 8048415: 83 c0 10 add $0x10,%eax 8048418: c7 00 99 00 00 00 movl $0x99,(%eax) /* 8049828+12+4 */ 804841e:    c7 05 e0 97 04 08 02     movl   $0x2,0x80497e0//i=2;  8048425:    00 00 00  8048428:    c7 05 e0 97 04 08 02     movl   $0x2,0x80497e0//i=2;  804842f:    00 00 00  8048432:    a1 e0 97 04 08           mov    0x80497e0,%eax  8048437:    89 44 24 04              mov    %eax,0x4(%esp)  804843b:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  8048442:    e8 ad fe ff ff           call   80482f4 <printf@plt>  8048447:    b8 04 98 04 08           mov    $0x8049804,%eax  804844c:    8b 00                    mov    (%eax),%eax  804844e:    89 44 24 04              mov    %eax,0x4(%esp)  8048452:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  8048459:    e8 96 fe ff ff           call   80482f4 <printf@plt>  804845e:    a1 34 86 04 08           mov    0x8048634,%eax  8048463:    83 c0 04                 add    $0x4,%eax  8048466:    8b 00                    mov    (%eax),%eax  8048468:    89 44 24 04              mov    %eax,0x4(%esp)  804846c:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  8048473:    e8 7c fe ff ff           call   80482f4 <printf@plt>  8048478:    a1 24 98 04 08           mov    0x8049824,%eax  804847d:    83 c0 04                 add    $0x4,%eax  8048480:    8b 00                    mov    (%eax),%eax  8048482:    89 44 24 04              mov    %eax,0x4(%esp)  8048486:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  804848d:    e8 62 fe ff ff           call   80482f4 <printf@plt>  8048492:    b8 28 98 04 08           mov    $0x8049828,%eax  8048497:    83 c0 10                 add    $0x10,%eax  804849a:    8b 00                    mov    (%eax),%eax  804849c:    89 44 24 04              mov    %eax,0x4(%esp)  80484a0:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  80484a7:    e8 48 fe ff ff           call   80482f4 <printf@plt>  80484ac:    c7 44 24 04 00 98 04     movl   $0x8049800,0x4(%esp)  80484b3:    08  80484b4:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  80484bb:    e8 34 fe ff ff           call   80482f4 <printf@plt>  80484c0:    a1 34 86 04 08           mov    0x8048634,%eax  80484c5:    89 44 24 04              mov    %eax,0x4(%esp)  80484c9:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  80484d0:    e8 1f fe ff ff           call   80482f4 <printf@plt>  80484d5:    a1 24 98 04 08           mov    0x8049824,%eax  80484da:    89 44 24 04              mov    %eax,0x4(%esp)  80484de:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  80484e5:    e8 0a fe ff ff           call   80482f4 <printf@plt>  80484ea:    c7 44 24 04 28 98 04     movl   $0x8049828,0x4(%esp)  80484f1:    08  80484f2:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  80484f9:    e8 f6 fd ff ff           call   80482f4 <printf@plt>  80484fe:    c7 44 24 04 e0 97 04     movl   $0x80497e0,0x4(%esp)  8048505:    08  8048506:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  804850d:    e8 e2 fd ff ff           call   80482f4 <printf@plt>  8048512:    c7 44 24 04 00 98 04     movl   $0x8049800,0x4(%esp)  8048519:    08  804851a:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  8048521:    e8 ce fd ff ff           call   80482f4 <printf@plt>  8048526:    c7 44 24 04 34 86 04     movl   $0x8048634,0x4(%esp)  804852d:    08  804852e:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  8048535:    e8 ba fd ff ff           call   80482f4 <printf@plt>  804853a:    c7 44 24 04 24 98 04     movl   $0x8049824,0x4(%esp)  8048541:    08  8048542:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  8048549:    e8 a6 fd ff ff           call   80482f4 <printf@plt>  804854e:    c7 44 24 04 28 98 04     movl   $0x8049828,0x4(%esp)  8048555:    08  8048556:    c7 04 24 38 86 04 08     movl   $0x8048638,(%esp)  804855d:    e8 92 fd ff ff           call   80482f4 <printf@plt>  8048562:    83 c4 14                 add    $0x14,%esp  8048565:    59                       pop    %ecx  8048566:    5d                       pop    %ebp  8048567:    8d 61 fc                 lea    -0x4(%ecx),%esp  804856a:    c3                       ret      804856b:    90                       nop      804856c:    90                       nop      804856d:    90                       nop      804856e:    90                       nop      804856f:    90                       nop    



Could not load content