一、為什麼嵌入式開發中選擇C語言作為開發語言
1.C語言的特點
①C語言具有出色的可移植性,能夠在不同體系結構軟/硬件平台上運行,所謂移植性好,就是當程序應用於不同的平台時,需要修改的源碼少
②C語言具有簡練緊湊,使用靈活的語法機制,並且能直接訪問硬件
③C語言具有很高的運行效率
2.C語言與匯編語言的選擇
①C語言是高級語言,能實現一些復雜的功能,主要用於對硬件實施復雜操作
②匯編是低級語言,主要用於對簡單硬件的初始化
3.C語言和解釋性語言的選擇
解釋性語言例如Java,它們都需要通過中間軟件實現解釋,運行效率低,但解釋性語言能適用於多種平台
二、面向過程處理機制(C)和面向對象處理機制(C++)
1.從處理對象來看:面向過程的處理機制解決的是具體事物,注重的是解決問題的過程;而面向對象的處理機制處理的是宏觀事物,注重的是解決問題的結果
2.從特性來看:面向過程的處理機制可以直接訪問硬件,可移植性號,執行效率高;而面向對象的處理機制代碼具有很好的復用性,維護性,擴展性
三、C語言的標准
1.C語言之父,也是Unix之父:丹尼斯·裡奇
2.C語言的標准
①K&R C
1978年,丹尼斯•裡奇(Dennis Ritchie)和布萊恩•柯林漢(Brian Kernighan)合作出版了《C程序設計語言》的第一版。書中介紹的C語言標准也被C語言程式設計師稱作“K&R C”K&R C主要介紹了以下特色:
結構(struct)類型
長整數(long int)類型
無符號整數(unsigned int)類型
把運算符=+和=-改為+=和-=。因為=+和=-會使得編譯器不知道使用者要處理i = -10還是i =- 10,使得處理上產生混淆。
②ANSI C和ISO C
C 的第一個標准是由ANSI發布的。ANSI C現在被幾乎所有廣泛使用的編譯器支持。現在多數C代碼是在ANSI C基礎上寫的。
③C89和C90
1983年,美國國家標准協會組成了一個委員會,X3J11,為了創立 C 的一套標准。經過漫長而艱苦的過程,該標准於1989年完成,並在作為ANSI X3.159-1989 “Programming Language C”正式生效。這個版本的語言經常被稱作”ANSI C”,或有時稱為”C89”(為了區別C99)。 在1990年,ANSI C標准(帶有一些小改動)被美國國家標准協會采納為ISO/IEC 9899:1990。這個版本有時候稱為C90或者ISO C。因此,C89和C90通常指同一種語言。 傳統C語言到ANSI/ISO標准C語言的改進包括:
增加了真正的標准庫
新的預處理命令與特性
函數原型允許在函數申明中指定參數類型
一些新的關鍵字,包括 const、volatile 與 signed 寬字符、寬字符串與字節多字符
對約定規則、聲明和類型檢查的許多小改動與澄清
④C99
2000年3月,ANSI 采納了 ISO/IEC 9899:1999 標准。這個標准通常指C99。 C99新增了一些特性,如:
支持不定長的數組,即數組長度可以在運行時決定。
變量聲明不必放在語句塊的開頭,for 語句提倡寫成 for(int i=0;i<100;++i) 的形式,即i 只在 for 語句塊內部有效。
初始化結構的時候允許對特定的元素賦值。
允許編譯器化簡非常數的表達式。
取消了函數返回類型默認為 int 的規定。
但是各個公司對C99的支持所表現出來的興趣不同。當GCC和其它一些商業編譯器支持C99的大部分特性的時候,微軟和Borland卻似乎對此不感興趣,他們把更多的精力放在了C++上。
⑤C11
在2011年12月,ANSI 采納了 ISO/IEC 9899:2011 標准。這個標准通常即C11,它是C程序語言的最新標准
3.gcc支持的C語言標准
gcc默認是不支持c99及以上版本的
如果想支持,需要在編譯時加參數:-std=c99 gcc -std=c99 -o xx xx.c
或者在源碼裡定義宏
1.什麼是數據類型?
數據是集合的劃分,不同數據類型對CPU的意義不一樣
2.左右法則:先找到變量字母,再看右邊,後看左邊,反復
int a;//整型變量
int *a; //整型指針變量
int **a; //整型指針的指針變量
int a[10]; //整型數組
int *a[10];//整型指針數組
int (*a)[10];//整型數組指針變量
int (*a)(int);//形參為int,返回值為int的函數指針變量
int (*a[10])(int);//函數指針數組,數組的元素指向形參為int,返回值為int的函數
int * ( * ( * fp1 ) ( int ) ) [10];
解釋:fp1是一個函數指針變量,該函數指針指向一個形參為int,返回值為指針數組的函數,數組的元素指向整型指針數組
int * ( ( arr[5] ) ( ) ) ( );
解釋:arr是一個函數指針數組,該數組的元素指向一個形參為空,返回值為函數指針的函數,該函數指針指向一個形參為空,返回值為整型指針的函數
float ( * ( * b ( ) ) [ ] ) ( );
解釋:b是一個函數,形參為空,返回值為函數數組指針,該數組指針指向函數指針數組,該數組元素指向一個形參為空,返回值為float型的函數
void * ( * c) ( char , int ( * ) ( ) );
解釋:c是一個函數指針變量,該函數指針指向一個形參1為char,形參2為形參為空,返回值為int的函數指針,返回值為void* 型的函數
void * * ( * d) ( int a,char * * ( * b) ( char , char *) );
解釋:d是函數指針變量,該函數指針指向形參1為int型,形參2 為函數指針變量(該函數指針指向形參1為char * ,形參2為char * * ,返回值為char * * 型的函數),返回值為void**型
float ( * ( * e[10] (int * ) ) [5];
解釋:e是函數指針數組,該數組元素指向一個形參為整型指針,返回值為float型數組指針的函數
3.強制類型轉化
char →int→float→double
沿箭頭方向的轉化是隱式類型轉化,由編譯器本身自動進行
4.字節長度
bit
字節 = 8 bit ☆
半字 = 2 個字節 = 16 bit
字 = 4 個字節 = 32 bit
通常我們所說的所占空間的大小都以字節來衡量
5.sizeof 不是函數,是運算符
書寫格式 sizeof (num) = sizeof num //測變量名有兩種寫法
sizeof (int) //測數據類型只能加括號
注意:使用的時候sizeof 與括號之間應該加空格
數據類型 字節長度
char 1
short 2
long 4
int 4
float 4
double 8
long long 8
注:任何類型的指針的長度都是4,因為指針用來保存地址,操作系統中地址長度固定,32為操作系統的地址長度為4,而64為操作系統的地址長度為8
6.有符號與無符號(signed & unsigned)
* 計算機中的數據都是以補碼表示的
正數: 原碼 = 補碼
負數:取絕對值的原碼取反加一(已知負數的補碼,有數值部分取反加一,得到原碼)
*計算機中常量都是有符號的
例:
輸出~2的十進制表示,即對2按位取反,輸出十進制的值
2 的原碼 0000 0010
~2的補碼1111 1101
符號位為1是負數,以補碼保存
數值位111 1101 取反加一 000 0011(十進制3)
所以~2的十進制表示為-3
7.越界
*char類型的數據 能表示的范圍,有符號 -128 ~127 ,無符號 0 ~255
*typedef 用來解決有符號數據和無符號數據的可移植問題
*有符號數和無符號數進行比較的時候,有符號數變成無符號數進行比較
*越界問題
例1
signed char ch = -128;
ch = ch - 1;
printf(“ch = %d\n”,ch);
輸出結果是ch = 127
過程:
-128 補碼:1000 0000
-1補碼:1111 1111
所以結果是0111 1111 即十進制的127
如果是unsigned char ch = 0 ;輸出結果就是ch = 255 計算方法是一樣的
例2
signed char ch = -128;
printf(“ch = %d\n”,ch - 1);
輸出結果為 ch = -129
注:例1是執行了賦值操作,所以存在越界的問題,而例2僅僅是計算表達式的值,存在迷惑性
7.sizeof & strlen
首先,這兩個從本質上來講,sizeof是運算符,而strlen 是函數;其次在計算值時sizeof是計算空間的大小,不需要考慮裡面的值時多少,而strlen在計算字符串的長度時,遇到\0就截止,且不計算\0
例:
char *ptr = “hello world”;
sizeof (ptr) 4 //測的是指針的長度
strlen(ptr) 11 //測量字符串的長度,遇到\0截止
char ptr[100] = “hello world”;
sizeof(ptr) 100 //測量字符數組的空間長度
strlen(ptr) 11 //測量字符串的程度,遇到\0截止
char ptr[ ] = “hello world”;
sizeof(ptr) 12 //系統自動根據字符串的大小分配空間,且包含\0在內
strlen(ptr) 11 //測量字符串的長度,遇到\0停止
8.變量的三大特點
①變量的數據類型:說明變量占用空間大小
②變量的作用域:變量的有效范圍,即變量的使用范圍
③變量的存儲區域:變量的存儲方式
9.進程:當系統在執行一個程序是被稱為一個進程
進程的虛擬地址空間:進程的活動范圍,操作系統為每個進程抽象出4g的虛擬空間
MMU內存管理單元:作用是將虛擬內存空間映射到物理內存
printf打印一個空間地址時,打印的是虛擬內存的地址
虛擬內存解決了系統內存空間資源稀缺的問題
☆4g虛擬內存的劃分示意圖
10.局部變量和全局變量的區別
①從變量的存儲區域來看:局部變量存在虛擬內存的棧空間,而全局變量存在虛擬內存的堆空間
②從初始化來看:局部變量不初始化時默認為任意值,而全局變量不初始化時默認為0
③從變量的作用域來看:局部變量在所在函數使用完後立即釋放,而全局變量在所有程序執行完最後釋放
11.聲明與定義的區別
①聲明可以有多次,但定義只能有一次
②先聲明,後定義,是語言的規范要求
③聲明不占用內存空間,而定義占用內存空間