歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> Linux C第三課

Linux C第三課

日期:2017/3/3 11:31:21   编辑:Linux技術

一、為什麼嵌入式開發中選擇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

或者在源碼裡定義宏

define STDC_VERSION 199901L

不同的編譯器支持不同的標准 四、數據類型

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.聲明與定義的區別

①聲明可以有多次,但定義只能有一次

②先聲明,後定義,是語言的規范要求

③聲明不占用內存空間,而定義占用內存空間

Copyright © Linux教程網 All Rights Reserved