C語言學習之 數組,指針,字符串. (一)

此文由來: 是看到野鬼發表的關於C語言知識內容後,一激動,手一癢.回了一篇.惋惜誤操做讓回覆沒能保存.
 以後再寫就是下面的內容. 野鬼發表的內容 http://www.oschina.net/question/249672_77341

計算機是按照指令進行操做的. C語言與彙編比算高級語言, 但它仍然很"低級".
計算機操做的都是數字, 差異只是 直接操做與間接操做. C仍然能夠用這些概念來了解 數組與指針的關係.
好比: int i; i=0; i++; 這3條語句就是屬於直接操做, 操做數是 i, 操做的目標也是i;
 另一種 int *p; *p=0; (*p)++; 這3條語句屬於間接操做,操做數是p,操做目的(*p);
記住一點,計算機操做的都是數字,也就是 i, 和 p 都是數字, 他們均可以用 printf("%d %d",i,p);來看看具體是什麼數字. 這裏的差異只是i是一個具體的被操做數,而p只是一個指針,例子中改變的不是p這個數,而是p對應的內容. p所對應的內容是一個int 類型. 因此聲明 用的是int *p;
另外,(*p)++; 這個括號不能夠少, 不然會變成 p這個指針自增,而後取內容.p自增後指向那裏.不肯定,固然是野指針,會出問題的.後話,之後會討論, 裏面有戲法,這個是C的優勢.善加利用會有好處. 數組

竟然有人頂個人回帖,這給我增長了信心. 好吧,我會繼續完善個人跟帖,幫助與我同一塊兒跑線的朋友一塊兒學習C語言. 這裏聲明一點,我也是學習C語言的新手. 跟帖內容是個人理解, 並不是是正確的解釋. 具體正確解釋仍是請你們聽取野鬼的指導文章. 也歡迎給位朋友指出我表述中存在的問題,好幫助我更準確的學習這門語言. 願我與你們共同進步.
函數

以前表述內容是瞭解 計算機在處理信息方面採用的方式, 重點仍是"一切都是數字". 
接下來講說全部變量都有存儲位置. 固然,這個是相對來說的.程序編譯以及優化過程當中這些概念不必定合適, 可是,對與學習這門語言來講.仍是認爲這句話是對的比較好.(雖然這句話自己就是錯的).
 繼續給例子, int i; 這個語句聲明瞭一個變量i(我也不知道如何說明這個i, 姑且認爲他是一個變量的存儲空間).  i就表示一個存儲空間, 他的大小 足夠放的下一個 int 內容. int 是什麼? 是一種類型.這些概念以前有講過, 能夠看以前內容加深理解.  這裏能夠大致上理解爲 "寬度" 若是以8位表示一個字節的話, char 類型就是佔用一個字節, int 類型佔用 sizeof(int) 個字節, sizeof(int) 是什麼?  sizeof 是操做符. 用來返回 目標 佔用的存儲空間大小, 以字節爲單位表示. sizeof(char) 返回確定是1. 這個就叫標準. sizeof(int) 會返回什麼? 標準中沒規定具體數值. 根據編譯器以及對編譯目標平臺來決定. sizeof用來幹什麼? 備用. 
以後說說 數組.  char a[9];  這個語句就是定義一個數組. 數組名是a,  數組大小是9個char 大小. 佔用空間 計算方式爲 9*(sizeof(char)). sizeof(char) =1 (這個是規定). 因此 9*sizeof(char) =9; 因此 char a[9]  會佔用9個字節的存儲空間. char a[8] 會佔用8個字節的存儲空間. 因此 char a[9] 是用來聲明 a 地址內會有 9 個字節的空間能夠用以程序使用.  short a[9] 會有 18個字節的空間, 此時a 的大小有 9*sizeof(short) = 18.  sizeof(short) = 2 也是規定.   在這裏記住一點, a 也是有數值的. 全部操做都是用來操做數字的. a能夠理解爲一個 存儲空間的首地址. 一切皆爲數字. 學習

再來講一下指針與數組的關係. 
 看例子. char a[9]; char *pa; pa=a; 這3條語句比較好理解. 首先 聲明瞭一個 大小爲 9*sizeof(char) 的存儲空間, 入口地址是 a , 以後聲明瞭一個 存儲空間, 存放pa, 它是一個指針.大小是指針的存儲空間--> sizeof(void *);  類型不一樣啊. 管他呢.  指針大小在同一平臺下是 不變的.   最後 pa=a ; 意思是將第二條 申請的空間內容 存儲成 a 的值. a 是什麼?  a其實就是一個數字, 是 數組存儲位置的首地址.  下面要說的就是神奇的地方. 指針運算. 優化

變戲法, 指針運算
依然看上面的例子.  a 表示一個長度爲9的存儲空間, a也是個數字, a也能夠表示爲9個存儲空間的首地址. 由此能夠理解爲, 數組,是一段連續空間的表示形式. 數組名是空間首地址.
在這裏須要引入一個概念, 數組指針, 數組指針是區別與指針數組的. 數組指針其實是一個指針, 聲明的時候會分配一個存儲空間給它,分配給他的存儲空間長度爲 指針的長度, 內容是一段指向連續空間的存儲空間首地址.
先來講一下指針,數組之間的魔法. 例子中 pa 是一個指針, 類型是 char . a 是一個數組, 類型是 char 的數組,  pa=a; 後,會發生什麼呢, pa 是一個char 類型的指針, 指向的內容類型也就是一個 char, 因此 *pa 就是一個char 類型. 來看下:
char a[9]="9742"; /*聲明並賦值*/ 
char *pa;
pa=a;/*這段能夠簡單寫成 char *pa=a; 聲明並賦值*/
printf("%c\n", *pa);/* 這段會輸出 字符 9 並換行. */
pa++; /* 指針運算,自增 */
printf("%c\n", *pa);  /* 這段會輸出字符 7, 並換行*/ .net

其實,上面這段是一個小魔術, 不過這個魔術會在C語言中隨處可見. 緣由很簡單. C代碼當中,處處都是指針. 爲了代碼的優美, 指針遍及各個角落, 這樣的魔術也遍及個個角落. 相對於數組, 指針能夠經過修改一個數字來操做改變後的內容,相對於數組只能經過下標的不一樣來修改要方便的.
爲加深印象. 查看下面的代碼.
 short a[9]; /*聲明數組*/
a[0] = 9;
a[1] = 1;
a[2] = 7;
a[3] = 4;
a[4] = 8;
short *pa; pa=a; 
printf("%d\n", *pa);
pa++;
printf("%d\n", *pa);
printf("%d\n", *(pa+1)); 
printf("%d\n", *(pa+2));  
固然,在這裏, 也能夠用printf("%d\n", *(a+1)); 來實現第二個輸出語句所實現的目的. 可是卻沒辦法執行 a++; 這樣的操做.  或許會有疑問, 既然能夠*(a+1) 爲何還要 *(pa+1);
這就引出更多的內容. tyepdef 指針

我不是萬惡之源,我只是一粒沙.我是 typedef
爲何要這麼說. 由於我不是讓代碼變得 凌亂的 罪魁禍首, 我只是一個讓一切變得好起來的幫手.我是typedef. 請好好待我. get

仍是例子:
typedef char ta[5];/* 一個5字節的連續空間 */
int fa() { 
ta a;
return 0;
}
定義了一個函數 fa, 返回類型是 int ,  裏面聲明瞭一個變量 a;
a 其實就是一個 數組,  和 char b[5]; 效果是同樣的. 這沒什麼好稀奇的.
使用的時候能夠 a[0],a[1],a[2]; 相似的, char b[5]在使用的時候也能夠是 b[0],b[1],b[2],b[3] 編譯器

ta a[3];  a[3] 的效果和 char b[3][5]; 是同樣的. 二維數組. 沒錯.就是他, 能夠更簡單一些.
使用的時候, 能夠 a[0][0]... a[2][4]; 是這樣. 那有什麼優點呢?  魔術,魔法. 指針是很神奇的東西. io

相關文章
相關標籤/搜索