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