關(guān)鍵字污淋、數(shù)據(jù)類型、自定義數(shù)據(jù)類型與類型修飾符(C語言)

硬件中最小的單位:高低電平余掖;也就是軟件中的位寸爆。

一、關(guān)鍵字

關(guān)鍵字:編譯器預(yù)先定義的具有一定意義的字符串盐欺。
它就是字符串赁豆,只不過被賦予了特定的意義。

C語言有32個(gè)關(guān)鍵字冗美。

如:sizeof是關(guān)鍵字魔种,而不是函數(shù)。
我們沒有實(shí)現(xiàn)sizeof粉洼,而是編譯器規(guī)定好的供我們查看內(nèi)存空間容量的一個(gè)工具节预。

printf是標(biāo)準(zhǔn)庫里面的一個(gè)函數(shù),借助于操作系統(tǒng)属韧。如果嵌入式開發(fā)中沒有OS安拟,直接進(jìn)行裸板操作,就不能調(diào)用該函數(shù)挫剑。但是仍然可以使用sizeof()查看內(nèi)存空間容量大小去扣。


二、數(shù)據(jù)類型

計(jì)算機(jī):CPU與很多資源樊破,中間通過數(shù)據(jù)總線和地址總線相連愉棱。

C語言的操作對(duì)象/目標(biāo):資源/內(nèi)存(硬件資源(顯存)、LCD緩存哲戚、LED燈奔滑、其他的串口和I2C設(shè)備等)。

C語言如何描述這些資源的屬性顺少?

通過資源屬性的大小——即數(shù)據(jù)類型關(guān)鍵字:它是限制內(nèi)存(土地)大小的關(guān)鍵字朋其。
因此王浴,要記住每個(gè)數(shù)據(jù)類型的大小。

涉及到數(shù)據(jù)類型大小梅猿,一般情況下都不是定值氓辣,與編譯器有關(guān),由編譯器決定袱蚓。

1钞啸、char

硬件芯片操作的最小單位。bit:1和0喇潘;高低電平体斩;位。
char buf[x];能更好地處理硬件所發(fā)送或接收的數(shù)據(jù)颖低。

如果軟件操作的最小單位和硬件一樣絮吵,那開發(fā)量會(huì)非常龐大。因此軟件采用了集合方式忱屑,把一組bit當(dāng)作軟件操作的單位:8bit == 1Byte (1B),字節(jié)
ASCII碼表:在整個(gè)計(jì)算機(jī)的鍵盤中蹬敲,用8bit不同的狀態(tài)可以描述所有的鍵值。

2想幻、int

其大小就是編譯器最優(yōu)的處理大小粱栖,即系統(tǒng)一個(gè)周期所能接收的最大處理單位。

比如:

  • 32位系統(tǒng)脏毯,一個(gè)周期能處理的數(shù)據(jù)是32bit闹究。則:32b(4B)就是int的大小,此時(shí)編譯器最優(yōu)食店。
  • 16bit的單片機(jī)系統(tǒng)渣淤,則int大小就是2B(16bit),此時(shí)編譯器最優(yōu)吉嫩。

如果是數(shù)字的處理(循環(huán)价认、計(jì)數(shù)器等),用int比用char好自娩。

3用踩、short

如果沒有特殊要求,用int而不用short忙迁;除非對(duì)空間有非常強(qiáng)烈的限制脐彩,比如在32位電腦中,必須要求空間是16bit處理姊扔,則使用short惠奸。

4、long恰梢、long long

它們是C語言可擴(kuò)展的類型佛南,要看編譯器是否支持梗掰。


三、自定義數(shù)據(jù)類型

C編譯器默認(rèn)定義的內(nèi)存分配不符合實(shí)際資源的形式嗅回。

自定義=基本元素的集合

1及穗、struct:元素之間的合集

struct myabc
{
    unsigned int a;
    unsigned int b;
    unsigned int c;
    unsigned int d;
};  
// 這是聲明,只是告知編譯器妈拌,具有內(nèi)存空間定義的能力拥坛,但是還沒有進(jìn)行定義蓬蝶。

struct myabc mybuf;   // 這是定義

注意:結(jié)構(gòu)體中順序是有要求的尘分。

2、union:共用起始地址的一段內(nèi)存

在一些技巧型的代碼中會(huì)用到丸氛。

union myabc{
    char a;
    int b;
};    // 聲明
union myabc abc;    // 定義

3培愁、enum:枚舉(整型常數(shù)的集合)

定義常數(shù):

#define MON 0
#define TUE 1
#define WED 2

enum與define是一致的,只不過enum可以更好地描述一個(gè)對(duì)象集合缓窜。

enum 枚舉名稱{常量列表};

enum abc {MOD, TUE, WED};    //不管定義多少個(gè)定续,一次只取一個(gè),存在32bit的空間中禾锤。

用處:比如私股,一個(gè)芯片中有一些數(shù)字1、2恩掷、3倡鲸,另一個(gè)芯片中也有一些數(shù)字1、2黄娘、3峭状,但是代表不同的芯片不同的含義,因此兩個(gè)芯片分別定義一個(gè)enum逼争,就可以用一些獨(dú)有的名字來代表1优床、2、3誓焦,讓人一看就明白胆敞。

程序員讀數(shù)字看不懂什么意思,但是通過看名字就能看得懂了

enum就是一個(gè)讓程序員與程序員交流上更加便利的一種打包的常量集合的概念杂伟。

例子:

/*001.c*/
#include <stdio.h>
enum abc {MOD=100, TUE, WED};
int main()
{
    enum abc a1=MOD;
    printf("the a1 is %u:%d\n",sizeof(a1),a1);
    printf("the %d\n",MOD);
    return 0;
}
/*002.c*/
#include <stdio.h>
enum abc {MOD=100, TUE, WED};
int main()
{
    enum abc a1 = 800;
    printf("the a1 is %u:%d\n",sizeof(a1),a1);
    printf("the %d\n",MOD);
    return 0;
}

4移层、typedef

見:《typedef(C語言)


四示罗、類型修飾符

對(duì)內(nèi)存資源在內(nèi)存中的存放位置的限定桨昙。

對(duì)于嵌入式開發(fā)工程師而言艘虎,內(nèi)存分配的具體位置實(shí)際上與某些代碼和流程非常有關(guān)系雕沉。

在內(nèi)核和驅(qū)動(dòng)編程中脑奠,類型修飾符會(huì)被大量地使用摄欲。

要對(duì)類型修飾符有比較深入的總結(jié)才行摸吠。

1侮叮、auto

是一種默認(rèn)情況,分配的區(qū)域是在可讀可寫的內(nèi)存上帽驯。

auto int a;
auto long b;

區(qū)域如果在{ }中龟再,則是棧空間尼变。

2利凑、register

分配的區(qū)域是在寄存器上。
因此嫌术,register可以定義一些快速訪問的變量哀澈。即,如果某個(gè)變量訪問的頻率很高度气,就使用register修飾割按,可以盡量放在寄存器中。

寄存器:CPU緩存器
內(nèi)存:內(nèi)部存儲(chǔ)器

register int a;
// 編譯器不是一定會(huì)把a(bǔ)放在寄存器中
// 編譯器會(huì)盡量地安排CPU的寄存器去存放a磷籍。但如果寄存器空間不足時(shí)适荣,a還是會(huì)被存放在存儲(chǔ)器中

register只是告訴編譯器盡量去安排,但是如果確實(shí)寄存器空間不足時(shí)院领,它是沒有任何辦法的弛矛,所以它沒辦法一定能確定存儲(chǔ)的位置,因此比然,&取地址符號(hào)對(duì)register不起作用丈氓。

中看不中用!

// 003.c
#include <stdio.h>
int main()
{
    register int a;
    a = 0x10;
    printf("a is %d\n", a);
    return 0;
}
// 004.c
#include <stdio.h>
int main()
{
    register int a;
    a = 0x10;
    printf("a is %d\n", &a);
    return 0;
}

register雖然功能不是很強(qiáng)大谈秫,它無法確定一定會(huì)存儲(chǔ)在寄存器上扒寄;但是當(dāng)程序員看到register修飾的變量后,就能夠知道一點(diǎn):該變量的訪問一定很頻繁拟烫!

3该编、static

在多文件工程編程中,在內(nèi)核中硕淑,會(huì)大量地看到static在用课竣。

在嵌入式C中的3種應(yīng)用場(chǎng)景(修飾3種數(shù)據(jù)):

(1)修飾函數(shù)內(nèi)部的變量:局部變量

int fun()
{ 
    int a; ===> static int a;
}

(2)修飾函數(shù)外部的變量:全局變量

int a;     ===>  static int a;
int fun()
{

}

(3)修飾函數(shù)

int fun();  ===> static int fun();

函數(shù)也可以理解成是一種變量。

// 005.c
#include <stdio.h>
int main()
{
    printf("main is %d\n", main);
    return 0;
}
函數(shù)名也是一個(gè)值

4置媳、extern

外部聲明于樟。主要在全局變量和函數(shù)中使用。

5拇囊、const

本意:用于定義常量(經(jīng)const修飾就不能改變了)
實(shí)際:只讀的變量(這個(gè)變量還是可以通過某些方法來改變的)迂曲。

const是C語言的軟肋!中看不中用A认路捧!

const int a  = 100;

// 編譯器不允許進(jìn)行顯式地修改
a = 200;

// 但是還是有辦法來對(duì)a進(jìn)行修改的
  • 內(nèi)存泄漏

    char *p;
    
    // 這2個(gè)等價(jià)
    const char *p;    // 建議用它     
    char const *p;  
    // 建議p指向的內(nèi)存空間关霸,內(nèi)容是只讀的。
    // p是1字節(jié)1字節(jié)(char)去讀的杰扫。p可以指向任意空間队寇,但是只要指向了,就建議它的內(nèi)容是只讀的章姓。  
    // ——可理解為:字符串佳遣。
    
    // 這2個(gè)等價(jià)
    char * const p;    // 建議用它    
    char *p const; 
    // 建議p永遠(yuǎn)指向第一次指向的地址。它指向固定地址凡伊,但是地址里面的內(nèi)容是可以變的零渐。
    // 一般這種定義,都是硬件資源的定義窗声。比如相恃,緩存地址是焊好的,或者芯片做的時(shí)候就做死了笨觅,但是里面的內(nèi)容是可以變的。
    
    const char * const p;     // 限制更加嚴(yán)格耕腾。它指向的地址不能變见剩,里面的內(nèi)容也不能變。
    // 工程中使用得不多扫俺,硬件中描述比較多苍苞。比如,描述ROM設(shè)備
    

例1:

// 001.c
#include <stdio.h>
int main()
{
    char *p = "hello world\n";    // 雙引號(hào)表示整型常量狼纬,里面的內(nèi)容是不可變的
    printf(" the first world is %x\n", *p);
    *p = 'a';
    printf("p is %s\n", p);
}
段錯(cuò)誤:指針指向的內(nèi)容被非法訪問/修改了

例2:

// 002.c
#include <stdio.h>
int main()
{
    char buf[] = {"hello world\n"};
    char *p = buf;
    printf("the first world is %x\n", *p);
    *p = 'a';
    printf("p is %s\n", p);
}
數(shù)組內(nèi)容是可以改變的

例3:

// 003.c
#include <stdio.h>
int main()
{
    const char *p = "hello world\n";    // 直接用const修飾只讀內(nèi)容
    printf(" the first world is %x\n", *p);
    *p = 'a';
    printf("p is %s\n", p);
}
使用const后羹呵,非法訪問/修改指針指向內(nèi)容時(shí),會(huì)直接報(bào)錯(cuò)

例4:

// 004.c
#include <stdio.h>
int main()
{
    const int a = 0x12345678;
    int b = 0x11223344;
    int *p = &b;
    *(p+1) = 0x100;    // p+1:a的地址
    printf("a is %x\n", a);
}
雖然a用const修飾疗琉,無法直接修改值冈欢;但通過越界,將a的值修改了

const只是建議盈简,不是強(qiáng)制凑耻。只是編譯時(shí)不會(huì)變,運(yùn)行時(shí)如果通過越界訪問柠贤,也可以改變香浩。

6、volatile

它不是限定內(nèi)存存放位置的修飾符臼勉,而是告知編譯器編譯方法的修飾符邻吭。

告知編譯器:不優(yōu)化編譯。

volatile的使用與地址關(guān)系比較大宴霸;在嵌入式和驅(qū)動(dòng)開發(fā)中囱晴,與硬件打交道比較多岸裙。在上層開發(fā)中,幾乎看不到這個(gè)關(guān)鍵字速缆。

volatile修飾變量的值的修改降允,不僅僅可以通過軟件,也可以通過其他方式(硬件外部的用戶)艺糜。

例子:鍵盤按下剧董,值改變,LCD亮破停。

volatile char *p;
*p == 0x10;    // 會(huì)一直從里面讀翅楼,而不會(huì)優(yōu)化掉。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末真慢,一起剝皮案震驚了整個(gè)濱河市毅臊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黑界,老刑警劉巖管嬉,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異朗鸠,居然都是意外死亡蚯撩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門烛占,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胎挎,“玉大人,你說我怎么就攤上這事忆家∮坦剑” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵芽卿,是天一觀的道長(zhǎng)揭芍。 經(jīng)常有香客問我,道長(zhǎng)蹬竖,這世上最難降的妖魔是什么沼沈? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮币厕,結(jié)果婚禮上列另,老公的妹妹穿的比我還像新娘。我一直安慰自己旦装,他們只是感情好页衙,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般店乐。 火紅的嫁衣襯著肌膚如雪艰躺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天眨八,我揣著相機(jī)與錄音腺兴,去河邊找鬼。 笑死廉侧,一個(gè)胖子當(dāng)著我的面吹牛页响,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播段誊,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼闰蚕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了连舍?” 一聲冷哼從身側(cè)響起没陡,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎索赏,沒想到半個(gè)月后盼玄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡参滴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年强岸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砾赔。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖青灼,靈堂內(nèi)的尸體忽然破棺而出暴心,到底是詐尸還是另有隱情,我是刑警寧澤杂拨,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布专普,位于F島的核電站,受9級(jí)特大地震影響弹沽,放射性物質(zhì)發(fā)生泄漏檀夹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一策橘、第九天 我趴在偏房一處隱蔽的房頂上張望炸渡。 院中可真熱鬧,春花似錦丽已、人聲如沸蚌堵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吼畏。三九已至督赤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泻蚊,已是汗流浹背躲舌。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留性雄,地道東北人没卸。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像毅贮,于是被迫代替她去往敵國和親办悟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容