嵌入式linux-C學習之基礎

1、數據類型的轉換:

轉換有兩種:(1)自動轉化:遵循一定的規則,有編譯系統自動完成,自動轉換規則:由低到高:char,short——>int——>unsigned——>long——>double<——float

                         (2)強制類型轉換:把表達式的運算結果強制轉換成所需要的數據類型,例如:(int)(a+b);把a+b的結果轉化爲整型


3、bool變量與“零值”進行比較

if( !b_test_flag )或者if(b_test_flag);


4、float變量與“零值”進行比較

if((f_test_val >= -0.00000001) && (f_test_val <= 0.00000001)

float和double類型的數據都是有精度限制的,這樣直接拿來與0.0比,必須像上面語句那樣


5、指針變量和“零值”進行比較

if(NULL == p);  if( NULL != p);


6、case語句後面不要忘記加上break;

記住:case後面只能是整型變量、字符型、常量或者常量表達式

const修飾的數據不能用在case後面


7、循環語句的注意點:

(1)在多重循環中,如果有可能,應當將最長的循環放到最裏面,最短的放到最外面,以減少CPU跨切循環層的次數。相對來說循環效率高


8、goto語句我主張的應該想內核一樣使用:

在實現功能上儘量不要用,

例如:

int  fun(void)

{

int i=0;

if(i == 0)

goto error;

else

{

......

}

error :

return -1;

}


9、const關鍵字也許該被替換爲readolny

const是congstant的縮寫,是恆定不點的意思,也翻譯成常量、常數等。

基於這一點很多人都認爲被const修飾的值是常量,這是不精確地,精確地說應該是隻讀的變量。其值在編譯的時不能被使用,因爲編譯器在編譯時不知道其裏面存儲的什麼內容。

const修飾的只讀變量必須在定義的同時初始化,同時它存放在靜態去,也就是全局變量去,

編譯器通常不爲普通const只讀變量分配存儲空間,而是將它們保存在符號表中,這樣使得它成爲一個編譯期間的值,沒有了存儲與讀內存的操作,使得效率也很高。


這裏看看和define的區別:例如下面:

#define M 3     //宏常量

const int N=5;  //此時併爲將N放入內存中


int  i=N;    //此時爲N分配內存,以後不再分配

int  i = M;  //預編譯期間進行宏替換,分配內存

int  j = N;    //沒有內存分配

int  j = M;     //再進行宏替換,又一次分配內存,

 

修飾指針:

const int *p;        //p可變,p指向的對象不可變

int const  *p;       //p可變,p指向的對象不可變

int *const p;        //p不可變,p指向的對象可變

const int * const p;    //指針p和o指向的對象都不可變

這裏給出一個記憶方法:

先忽略類型名(編譯器解析的時候也是忽略類型嗎,我們看到離cost離那個就近,離誰近就修飾誰




10、volatite 是一邊的、不穩定的意思,   也很少用。


11、union 關鍵字

union維護足夠的空間來置放多個數據成員中的”一種“,而不是爲每一個數據成員配置空間,在union中所有的數據成員公用一個空間,同一時間只能存儲其中一個數據,所有的數據成員具有相同的起始地址,例如:

union machine

{

char character;

int num;

char *str;

double exp;

};

一個union只配置一個足夠大的空間以來容納最大長度的數據成員,以上慄二樣,最大的是double類型,所以machine的空間大小爲double 數據類型的大小。


大、小端模式對union的影響:

union

{

int i;

char a[2];

}*p,u;

p=&u;

p->a[0]=0x38;

p->a[1]=0x30;

p.i的值應該爲多少呢?

這裏需要考慮存儲模式:大端模式和小端模式。

union類型數據所佔的空間等於其最大成員所佔的空間,對union類型的成員的存儲都是相對該聯合體基地址的偏移量爲0處開始,也就是聯合體的訪問不論對那個變量的存取都是從union的首地址位置開始,


12、enum關鍵字

很多初學者對枚舉感到迷惑,或者認爲沒有什麼用,其實枚舉(enum)是個很有用的數據類型。

(1)使用方法:一般定義如下:

enum enmu_type_name

{

ENUM_CONST_1,

ENUM_CONST_2,

.....

}enum_variable_name;

注意: enum_type_name是自定義的一種數據數據類型名,而enum_variable_name爲enum_type_name類型的一個變量,也就是我們平時常說的枚舉變量,實際上enum_type_name類型是對一個變量取值範圍的限定,而花括號內是他的取值範圍,即 enum_type_name類型的變量enum_variable_name 只能取值爲花括號內的任何一個值,如果賦給該類型變量的值不在列表中,則會報錯或者警告。ENUM_CONST_1 、ENUM_CONST_2 、... 、
ENUM_CONST_n ,這些成員都是常量,也就是我們平時所說的枚舉常量(常量一般用大寫)。enum 變量類型還可以給其中的常量符號賦值,如果不賦值則會從被賦初值的那個常量開始依次加1 ,如果都沒有賦值,它們的值從 0 開始依次遞增1。

例如分別用一個常數表示不同的顏色:

enum Color

{

GREEN= 1,

RED,

BLUE,

GREEN_RED=10,

GREEN_BLUE

}ColorVal

其中個常量名代表的數值分別爲:

GREEN=1

RED=2

BULE=3

GREEN_RED=10

GREEN_BULE=11

枚舉與#define宏的區別

下面看看枚舉與#define宏區別:

(1)#define 宏常量是在預編譯階段進行簡單的低緩,枚舉常量是在編譯的時候確定的

(2)一般在編譯器裏,可以調試枚舉常量,但是不能吊事宏常量

(3)枚舉可以一次定義大量相關的常量,而#define宏一次只能定義一個,


13、typedef

typedef的真正意思是給一個已經存在的數據類型(注意:是類型,不是變量)取一個別名,而非定義一個新的數據類型,在實際項目中,爲了方便,可能很多數據類型(尤其是結構體之類的自定義數據類型)需要我們重新取一個適用實際情況的別名。這時候typedef就可以幫忙了:如下例:

typedef struct student 

{

//code

}Stu_st,*Stu_pst;

對struct student *stu2;  和  Stu_pst stu2;  和Stu_st *stu2     // 沒有區別


在如下面的:

(1)#define INT32  int

unsigned INT32 i=20;

(2)typedef int int32;

unsigned int32 j=20;

其中(2)編譯出錯,爲什麼,因爲#define編譯的時開始宏替換,替換爲int 所以(1)正確,那麼(2)typedef取別名不支持這種類型擴展,

下面再看看一個與#define宏有關的例子:

(3)#define pch char*

pch p3,p4;

(4)typedef char* pchar;

pchar p1,p2,

兩組代碼編譯都沒問題,但是,這裏的p4卻不是指針僅僅是一個char類型的字符,這種錯誤很容易被忽略,所以用#define的時候要慎之又慎,


14、關於註釋:

編譯器在編譯的時候會把註釋符號剔除掉,用空格代替原來的註釋符

對於全局變量、常量以及函數必須加註釋。

在C語言裏面 \ 表示斷行,\後面不許有空格,同時\也表示轉義字符

15、左移和右移 <<  、>>

0x01>>2+32;對嗎?

顯然不對,由於整型數長度爲32位,右移32位發生什麼了!溢出,所以左移和右移的位數是有講究的。左移和右移的位數不能大於數據的長度,不能小於0。


16、函數:

(1)如果參數是指針,且僅作爲輸入參數怎應在類型前加const,以防止指針在函數體內被意外修改

例如:void str_copy(char *str_destination,const char *str_source);

(2)如果沒寫函數返回類型,那麼編譯器默認的函數返回類型爲int 型。

(3)return語句不可返回指向“棧內存”的“指針”,

例如:

char * fun(void)

{

char str[20];

.......

return str;

}

(4)儘量避免函數帶有“記憶”功能,在C語言中,函數的static局部變量是函數的“記憶”存儲器,建議儘量少用

static 定義局部變量,除非必需。

(5)函數遞歸

編寫一個測試字符串長度的函數。不使用局部、全局變量也不調用庫函數,

int my_strlen(const char *str_dest)

{

assert(NULL != str_dest);

if('\0' == *str_dest)

{

return 0;

}

else

{

return (1 + my_strlen( ++str_dest ));

}

}








2、變量命名:以字符或者下劃線開頭,由字符、下劃線和數字組成;

sizeof:他是求變量的類型所佔的內存大小,例如:int int_a=100;sizeof(int_a)結果爲:4,因爲int類型佔內存空間4個字節,而不是100。其中數組int b[10]={0};它所佔的空間爲40個字節,

對結構體來說:例如:

strcut student

{

       int a;

       char p;

} type ; 它所佔的字節爲8,不知道其中的道理,那就自己解決吧! ^_^ 。

 

 

                                 

                                      

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章