編程技巧之嵌入式C語言徹底學習筆記及案例[圖]
一、經典入門:hello world
1.一、概念:
*源文件:源文件即源代碼文件,C語言源文件後綴名是.c。
*頭文件:頭文件後綴名爲.h(head,頭),C語言代碼由源文件和頭文件組成。
*關鍵字:關鍵字是C語言徵用了的一些字,這些字在C語言中表明特殊含義,已經被C語言定義好了,輪不到咱們用了。每一個關鍵字都有本身特定的含義,咱們必須搞懂每一個關鍵字的全部含義和用法,不然就看不懂C語言程序。
*註釋:C語言中註釋以//開頭,或者/* */,註釋是給程序員看的,不是給機器看的。也
就是說,程序員寫註釋給其餘人看,以讓人明白本身爲何要這麼寫。可是編譯器編譯程序的時候是忽略註釋內容的,因此機器根本看不見註釋,也不理註釋。
*符號:C語言程序中包含不少符號,如; : , + () {} *等等,各類符號都有本身的含義,必須
搞明白各類符號的含義,才能看懂C語言程序。
*變量:會變化的量。C語言程序中用變量來進行計算。
*函數:函數是C語言的一個基本組成單位,一個C語言程序其實就是由不少函數組成的,每一個函數用來完成必定的功能,函數能夠調用別的函數來完成功能。函數的標誌是().C語言中有一個特殊的函數叫main,這個函數是整個程序的內定的入口,也就是說整個C語言程序是從main函數開始執行的,其餘的函數都是直接或者間接被main調用。html
1.二、C語言寫代碼步驟:
第一步:編輯源代碼(使用vi或者其餘編輯器)
第二步:編譯。編譯就是用編譯器把源程序轉化成可執行程序的過程,編譯要用到編譯器。咱們在linux中使用編譯器通常是gcc。
譬如:gcc hello.c 把當前目錄下hello.c文件編譯,獲得的可執行文件名字叫a.out
也能夠本身指定編譯後生成的可執行程序的名字,使用gcc hello.c -o hello
第三步:執行編譯生成的可執行程序,執行方式是./hello
第四步:調試。當你執行後發現程序結果不對,不是本身想要的,這時候就是返回來看源代碼哪裏不對。而後修改,再編譯執行,再看結果。如此循環直接結果正確。
C語言關鍵字:
include(包含) 頭文件包含
int(integer,整數) 用來表示一個整數的類型叫整形。
float(浮點型) 用來表示小數的類型
char(character,字符) 字符型數據類型
return(返回) 函數返回
VMWare共享文件夾使用
嵌入式C語言徹底學習筆記進階篇:
一、數據類型
1.一、基本數據類型
數據類型分2類:基本數據類型+複合類型
基本類型:char short int long float double
複合類型:數組 結構體 共用體 類(C語言沒有類,C++有)
1.1.一、內存佔用與sizeof運算符
數據類型就好像一個一個的模子,這個模子實例化出C語言的變量。變量存儲在內存中,須要佔用必定的內存空間。一個變量佔用多少空間是由變量的數據類型決定的。
每種數據類型,在不一樣的機器平臺上佔用內存是不一樣的。咱們通常講的時候都是以32位CPU爲默認硬件平臺來描述:
char 1字節 8位
short 2字節 16位
int 4字節 32位
long 4字節 32位
float 4字節
double 8字節
1.1.二、有符號數和無符號數
對於char short int long等整形類型的數,都分有符號有無符號數。
而對於float和double這種浮點型數來講,只有有符號數,沒有無符號數。
對於C語言來講,數(也就是變量)是存儲在內存中一個一個的格子中的。存儲的時候是以二進制方式存儲的。對於有符號數和無符號數來講,存儲方式不一樣的。譬如對於int來講
unsigned int 無符號數,32位(4字節)所有用來存數的內容 因此表示的數的範圍
是0 ~ 4294967295(2^32 - 1)
signed int 有符號數,32位中最高位用來存符號(0表示正數,1表示負數),剩餘的31位用
來存數據。因此能夠表示的數的範圍是 -2147483648(2^32) ~ 2147483647(2^31 - 1)
結論:從絕對數值來講,無符號數所表示的範圍要大一些。由於有符號數使用1個二進制位來表示正負號。
1.1.三、整形數和浮點型數存儲方式上的不一樣
對於float和double這種浮點類型的數,它在內存中的存儲方式和整形數不同。因此float和
int相比,雖然都是4字節,可是在內存中存儲的方式徹底不一樣。因此同一個4字節的內存,若是存儲時是按照int存放的,取的時候必定要按照int型方式去取。若是存的時候和取的時候理解的方式不一樣,那數據就徹底錯了。
備註:詳細的數制存儲能夠查找資料:計算機原碼、反碼、補碼等知識。
總結:存取方式上主要有兩種,一種是整形一種是浮點型,這兩種存取方式徹底不一樣,沒有任何關聯,因此是絕對不能隨意改變一個變量的存取方式。在整形和浮點型以內,譬如說4種整形char、short、int、long只是範圍大小不一樣而已,存儲方式是如出一轍的。float和double存儲原理是相同的,方式上有差別,致使了能表示的浮點型的範圍和精度不一樣。
1.二、空類型(關鍵字void)
C語言中的void類型,表明任意類型,而不是空的意思。任意類型的意思不是說想變成誰就變成誰,而是說它的類型是未知的,是還沒指定的。
void * 是void類型的指針。void類型的指針的含義是:這是一個指針變量,該指針指向一個
void類型的數。void類型的數就是說這個數有多是int,也有多是float,也有多是個結構體,哪一種類型都有可能,只是我當前不知道。
void型指針的做用就是,程序不知道那個變量的類型,可是程序員本身內心知道。程序員如何知道?當時給這個變量賦值的時候是什麼類型,如今取的時候就仍是什麼類型。這些類型對不對,可否兼容,徹底由程序員本身負責。編譯器看到void就沒辦法幫你作類型檢查了。
在函數的參數列表和返回值中,void表明的含義是:
一個函數形參列表爲void,表示這個函數調用時不須要給它傳參。
返回值類型是void,表示這個函數不會返回一個有意義的返回值。因此調用者也不要想着去使用該返回值。
C語言設計基本理念:
C語言相信程序員永遠是對的,C語言相信程序員都是高手,C語言賦予了程序員最大的權利。因此C語言的程序員必須本身對程序的對錯負責,必須隨時腦殼清楚,知道本身在幹嗎。
1.三、數據類型轉換
C語言中有各類數據類型,寫程序時須要定義各類類型的變量。這些變量須要參與運算。C語言有一個基本要求就是:不一樣類型的變量是不能直接運算的。
也就是說,int和float類型的變量不能直接加減等運算。你要運算,必須先把兩種類型轉成相同的類型才能夠。
1.3.一、隱式轉換
隱式轉換就是自動轉換,是C語言默認會進行的,不用程序員干涉。
C語言的理念:隱式類型轉換默認朝精度更高、範圍更大的方向轉換。
1.3.二、強制類型轉換
C語言默認不會這麼作,可是程序員我想這麼作,因此我強制這麼作了。
1.四、C語言與bool類型
C語言中原生類型沒有bool,C++中有。在C語言中若是須要使用bool類型,能夠用int來代替。
不少代碼體系中,用如下宏定義來定義真和假
#define TRUE 1
#define FALSE 0
二、變量和常量
2.一、變量
變量,指的是在程序運行過程當中,能夠經過代碼使它的值改變的量。
2.1.一、局部變量
定義在函數中的變量,就叫局部變量。
2.1.1.一、普通局部變量(auto)
普通的局部變量定義時直接定義,或者在定義前加auto關鍵字
void func1(void)
{
int i = 1;
i++;
printf("i = %d.\n", i);
}
局部變量i的解析:
在連續三次調用func1中,每次調用時,在進入函數func1後都會創造一個新的變量i,而且給它賦初值1,而後i++時加到2,而後printf輸出時輸出2.而後func1本次調用結束,結束時同時殺死本次創造的這個i。這就是局部變量i的整個生命週期。
下次再調用該函數func1時,又會從新創造一個i,經歷整個程序運算,最終在函數運行完退出時再次被殺死。
2.1.1.二、靜態局部變量(static)
靜態局部變量定義時前面加static關鍵字。
總結:
一、靜態局部變量和普通局部變量不一樣。靜態局部變量也是定義在函數內部的,靜態局部變量定義時前面要加static關鍵字來標識,靜態局部變量所在的函數在多調用屢次時,只有第一次才經歷變量定義和初始化,之後屢次在調用時再也不定義和初始化,而是維持以前上一次調用時執行後這個變量的值。本次接着來使用。
二、靜態局部變量在第一次函數被調用時創造並初始化,但在函數退出時它不死亡,而是保持其值等待函數下一次被調用。下次調用時再也不從新創造和初始化該變量,而是直接用上一次留下的值爲基礎來進行操做。
三、靜態局部變量的這種特性,和全局變量很是相似。它們的相同點是都創造和初始化一次,之後調用時值保持上次的不變。不一樣點在於做用域不一樣
2.1.1.四、register關鍵字
register(寄存器),C語言的一個關鍵字
register int i = 3;
總結:register類型的局部變量表現上和auto是同樣的,這東西基本沒用,知道就能夠了。register被稱爲:C語言中最快的變量。C語言的運行時環境承諾,會盡可能將register類型的變量放到寄存器中去運行(普通的變量是在內存中),因此register類型的變量訪問速度會快不少。可是它是有限制的:首先寄存器數目是有限的,因此register類型的變量不能太多;其次register類型變量在數據類型上有限制,譬如你就不能定義double類型的register變量。通常只在內核或者啓動代碼中,須要反覆使用同一個變量這種狀況下才會使用register類型變量。
2.1.二、全局變量
定義在函數外面的變量,就叫全局變量。
2.1.2.一、普通全局變量
普通全局變量就是平時使用的,定義前不加任何修飾詞。普通全局變量能夠在各個文件中使
用,能夠在項目內別的.c文件中被看到,因此要確保不能重名。
2.1.2.二、靜態全局變量
靜態全局變量就是用來解決重名問題的。靜態全局變量定義時在定義前加static關鍵字,
告訴編譯器這個變量只在當前本文件內使用,在別的文件中絕對不會使用。這樣就不用擔憂重名問題。因此靜態的全局變量就用在我定義這個全局變量並非爲了給別的文件使用,原本就是給我這個文件本身使用的。
2.1.1.三、跨文件引用全局變量(extern)
就是說,你在一個程序的多個.c源文件中,能夠在一個.c文件中定義全局變量g_a,而且能夠在別的另外一個.c文件中引用該變量g_a(引用前要聲明)
函數和全局變量在C語言中能夠跨文件引用,也就是說他們的鏈接範圍是全局的,具備文件鏈接屬性,愛的教育讀書筆記(http://www.simayi.net/dushubiji/6047.html)及心得感悟,總之意思就是全局變量和函數是能夠跨文件看到的(直接影響就是,我在a.c和b.c中各自定義了一個函數func,名字相同可是內容不一樣,編譯報錯。)。
局部變量和全局變量的對比:
一、定義同時沒有初始化,則局部變量的值是隨機的,而全局變量的值是默認爲0.
二、使用範圍上:全局變量具備文件做用域,而局部變量只有代碼塊做用域。
三、生命週期上:全局變量是在程序開始運行以前的初始化階段就誕生,到整個程序結束退出的時候才死亡;而局部變量在進入局部變量所在的代碼塊時誕生,在該代碼塊退出的時候死亡。
四、變量分配位置:全局變量分配在數據段上,而局部變量分配在棧上。
判斷一個變量能不能使用,有沒有定義,必須注意兩點:第一,該變量定義的做用域是否在當前有效,是否包含當前位置;第二,變量必須先定義後使用。因此變量引用必定要在變量定義以前。linux