數組指針總結

int a[10] 定義一個整型數組 裏面有10個元素
a      數組名,同時也爲首元素地址  +1 +4字節
&a      數組地址                      +1 +40字節
&a[0] 數組首元素的地址            +1 +4字節

int a[4][3]
a            數組名,同時也爲首行地址    +1 +12
&a            數組地址                    +1 +48
a[0]        首行首元素地址                +1 +4
&a[0]        首行地址                    +1 +12
&a[0][0]    首元素地址                    +1 +4

--------------------------------------------------------------

指針
不管什麼類型的指針
sizeof(int *)        四字節
sizeof(char *)        四字節
sizeof(long *)        四字節
sizeof(float *)        四字節

int a = 1;
int *p = &a; 或 p = &a;
p+1 +4字節

指針 + 數組
int a[10] = {1,2,3,4,5,6,7,8,9,10}  數組名a爲常指針
int *p = a;
a[i] *(a+1)    *(p+1) 三個是等價的
-----------------------------------------------------------------------
指針數組的定義
指針數組:指針數組可以說成是”指針的數組”
首先這個變量是一個數組,其次,”指針”修飾這個數組,
意思是說這個數組的所有元素都是指針類型,在32位系統中,指針佔四個字節。

char *arr[4] = {"hello", "world", "shannxi", "xian"};
這就相當與定義char *p1 = “hello”,char *p1 = “world”,char *p3 = “shannxi”, char *p4 = “xian”,這是四個指針,每個指針存放一個字符串首地址,然後用arr[4]這個數組分別存放這四個指針,就形成了指針數組。

arr爲指針數組的首地址 也是hello的地址
*arr        %s輸出的是 hello
*arr + 1     %s輸出的是 ello
*(arr + 1)    %s輸出的是 world
arr[0]        %s輸出的是 hello
arr[1]        %s輸出的是 world
所以對於數組指針而言  *(arr + 1)  arr[1] 也是等價的

-------------------------------------------------------
數組指針:數組指針可以說成是”數組的指針”,
首先這個變量是一個指針,其次,”數組”修飾這個指針,
意思是說這個指針存放着一個數組的首地址,或者說這個指針指向一個數組的首地址。 
int (*pa)[4]; 此時pa的步長爲4*4=16個字節 

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4] = a;  //定義一個數組指針 步長爲16
a[i][j] ;*(*(p+i)+j);(*(p+i))[j]  //這三個是等價的

-------------------------------------------------------------------------
指針的指針 
如果不通過函數的參數傳遞的話
    char *ptr = (char *)malloc(sizeof(char) * 64);
就可以了,但是用了的話:
void A(char **str)
{
    *str = (char *)malloc(sizeof(char) * 64);
}
int main()
{
    char *ptr = NULL;
    A(&ptr);
    strcpy(ptr,"hello");
}


那麼爲什麼要用到指針的指針呢?
printf("%s ",ptr)  -->(null)
printf("%s ",*ptr) -->segment fault
printf("%p ",&ptr) -->0xbfd26f00
printf("%p ",ptr)  -->0x8c3b008c
如果A(ptr); 把null傳遞給了形參 沒意義
如果A(&ptr);把地址傳給了形參,這時候的地址是指針的地址,而本來指針就是存放內存地址的,所以這時候就是指針的指針,形參要用**p接!!!
----------------------------------------------------------------

int main()
{
    char *str[] = {"hello","world","ni","hao"};
    char **p;
    int i;
    for(i = 0; i < 4; i++)
    {
        p = str + i;      //p是指針的指針,存放的是指針的地址,
                          //str爲指針數組存放的就是指針的地址,所以可以賦值
        printf("%s \n",*p);
    }
    return 0;
}

---------------------------------------------------------------
函數指針的定義
void (*p)(); 

int add(int x,int y);
int (*q)(int,int);
q = add;
q(1,2);


總結一下,指針和數組最重要的就是對地址的操作,就是通過指針或者是數組的地址賦值來操作內存中存放的數據!
要分清楚什麼時候調用的是地址,什麼時候是取值!
‘*’在定義時:表示後面的變量是一個指針
‘*’在使用時:表示取值,即取地址的值


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章