(1)指針數組是一個數組,裏面包含若干指針,指針數組名是指向指針的地址,可賦值給指向指針的指針。
如 int* a[]={"hello" ,"world","nihao"}; int**p=a;
(2)數組指針是一個指針,指向整個數組。
如 int v[2][3]={{1,2,3},{4,5,6}} ;
int b[3]={7,8,9};
int (*p1)[3]=v; p1==v-->v[0]-->v[0][0]==1;
int (*p2)[3]=&b; p2==&b-->b-->b[0]==7;
(3)數組名的兩層含義:既是數組符號名(猶如 “int a=3;"中a是一個4字節內存的符號名一樣),又是指向該數組中第一個元素的地址。比如 int a[3]={1,2,3}; 在*a中,a表示a[0]的地址;而在sizeof(a)中,a表示整個數組的符號名,代表着12字節的空間。
(4)在計算機中,訪問內存中的任意單元內容皆是通過地址的!在彙編語言中,訪問內存中的任何單元都是直接用地址(通常藉助%ebp,%esp等指針)的,而在c語言中,爲了方便引入了符號名,一個符號代表着一塊區域,但要注意符號名本身是不佔內存空間的,只是在c語言的層次供程序員使用。比如int a=3;告訴編譯器爲我分配了4字節,以後我使用這塊空間時用a就行了,而事實上,經編譯編譯成彙編代碼後,彙編裏對該塊區域的訪問皆是通過地址訪問的,彙編語言代碼中沒有相應的符號a。又如,int a[3]={1,2,3}; 對應着12字節的空間,和4個符號(a[0],a[1],a[2],a),但這4個符號都是不佔用內存空間的,彙編代碼裏也沒有這4個符號。
如:
#include<stdio.h>
int main()
{
int a[3]={1,2,3};
int b=a[0]+a[1]+a[2];
return b;
}
彙編代碼如下:
.file "test_a.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp ;分配16字節
movl $1, -16(%ebp) ;對應着a[0]
movl $2, -12(%ebp) ;對應着a[1]
movl $3, -8(%ebp) ;對應着a[2]
movl -16(%ebp), %edx
movl -12(%ebp), %eax
addl %eax, %edx
movl -8(%ebp), %eax
leal (%edx,%eax), %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax ;對應着b
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
(5) int v[2][3]={{1,2,3},{4,5,6}} ;
對應着24字節的空間和訪問該24空間的10(=6+3+1)個符號名。它們分別是:
6個整型變量名: v[0][0]; v[0][1]; v[0][2]; v[1][0]; v[1][1]; v[1][2]; v[2][0]; v[2][1]; v[2][2];
3個一維數組名: v[0],v[1],v[2]
1個數組地址名: v
在c語言中,當我們定義了int v[2][3]後,我們就可以在後面的代碼中使用這個10個符號以不同的方式訪問這塊內存空間。
(6)抓住根本:分配的實際空間+訪問接口(符號名或地址)