首先看下如下代碼,猜猜看會輸出什麼?數組
#include <stdio.h> int main() { char s[] = "How big is it?"; char *t = s; printf("%lu\n", sizeof(s)); printf("%lu\n", sizeof(t)); printf("%p\n", s); printf("%p\n", t); printf("%p\n", &s); printf("%p\n", &t); return 0; }
output:指針
15 8 0x7fff5ab94af5 0x7fff5ab94af5 0x7fff5ab94af5 0x7fff5ab94ae8
這個時候咱們看到 printf("%p\n", s)
和 printf("%p\n", t)
返回了一樣的值,也就是數組變量s[]的第一個元素的指針地址。記住數組變量能夠被看成指針使用,它指向數組在存儲器中的起始地址。code
既然這樣有些小夥伴可能會驚呆了,那爲何 printf("%lu\n", sizeof(s))
會返回15即字符串的真實長度而不是數組起始地址的指針長度?這裏有個特性是 sizeof()運算符
針對這種狀況會自動開竅,若是你傳給它一個數組變量則會返回字符串的實際長度。若是你使用 sizeof(&s)
那返回的就是指針的長度了,在64位OSX下返回的數值則是8。至於 printf("%lu\n", sizeof(t))
上面已經進行了 char *t = s
的賦值操做,其實 t
如今骨子裏已經存放了數組變量 s
首位元素的指針地址。sizeof
對此就只會輸出實際的指針地址長度,因此是8。字符串
printf("%p\n", &s)
和 printf("%p\n", &t)
則有所不一樣,&s
依然會返回 s
數組變量首位元素的指針地址,因此 &s == s
。而 &t
雖然存放了至關於 &s
的指針地址可是別忘了計算機是會爲指針變量 t
也分配存儲空間的,因此 t
有它本身的指針地址,結果固然 &t != t
。編譯器
別覺得就這樣GG了,它們之間還有一個很重要的區別。it
數組變量不能指向其餘地方,建立指針變量的時候計算機會爲它分配存儲空間。那數組變量呢?io
實際上計算機只會爲數組分配存儲空間,但不會爲數組變量分配任何存儲空間,編譯器會在數組變量出現的地方將它替換成數組的起始地址。編譯
Over.變量