91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

在keil編譯器中,extern的關鍵字是什么?

lhl545545 ? 來源:玩轉單片機 ? 作者:玩轉單片機 ? 2020-06-18 16:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

引言我們在一個項目小組做一個相對較復雜的工程時,意味著你不再獨自單干。而是和小組成員分工合作,這就要求小組成員各自負責一部分工程。比如你可能只是負責通訊或者顯示這一塊。這個時候,你就應該將自己的這一塊程序寫成一個模塊,單獨調(diào)試,留出接口供其它模塊調(diào)用。最后,小組成員都將自己負責的模塊寫完并調(diào)試無誤后,由項目組長進行組合調(diào)試。像這些場合就要求程序必須模塊化。模塊化的好處是很多的,不僅僅是便于分工,它還有助于程序的調(diào)試,有利于程序結構的劃分,還能增加程序的可讀性和可移植性。

要說的話初學者往往搞不懂如何模塊化編程,其實它是簡單易學,而且又是組織良好程序結構行之有效的方法之一。本文將先大概講一下模塊化的方法和注意事項,最后將以初學者使用最廣的keil c編譯器為例,給出模塊化編程的詳細步驟。

模塊化程序設計應該理解以下概述:

模塊即是一個.c 文件和一個.h 文件的結合,頭文件(.h)中是對于該模塊接口的聲明;這一條概括了模塊化的實現(xiàn)方法和實質(zhì):將一個功能模塊的代碼單獨編寫成一個.c文件,然后把該模塊的接口函數(shù)放在.h文件中。舉例:假如你用到液晶顯示,那么你可能會寫一個液晶驅動模塊,以實現(xiàn)字符、漢字和圖像的現(xiàn)實,命名為: led_device.c,該模塊的.c文件大體可以寫成:

#include …

//定義變量

unsigned char value;//全局變量

//定義函數(shù)

//這是本模塊第一個函數(shù),起到延時作用,只供本模塊的函數(shù)調(diào)用,所以用到static關鍵字修飾

/********************延時子程序************************/

static void delay (uint us) //delay time

{}

//這是本模塊的第二個函數(shù),要在其他模塊中調(diào)用

/*********************寫字符程序**************************

** 功能:向LCD寫入字符

** 參數(shù):dat_comm 為1寫入的是數(shù)據(jù),為0寫入的是指令

content 為寫入的數(shù)字或指令

******************************************************/

void wr_lcd (uchar dat_comm,uchar content)

{}

/***************************** END Files***********************************/

注: 此處只寫出這兩個函數(shù),第一個延時函數(shù)的作用范圍是模塊內(nèi),第二個,它是其它模塊需要的。為了簡化,此處并沒有寫出函數(shù)體。

.h文件中給出模塊的接口。在上面的例子中, 向LCD寫入字符函數(shù):wr_lcd (uchar dat_comm,uchar content)就是一個接口函數(shù),因為其它模塊會調(diào)用它,那么.h文件中就必須將這個函數(shù)聲明為外部函數(shù)(使用extrun關鍵字修飾),另一個延時函數(shù):void delay (uint us)只是在本模塊中使用(本地函數(shù),用static關鍵字修飾),因此它是不需要放到.h文件中的。

.h文件格式如下:

//聲明全局變量

extern unsigned char value;

//聲明接口函數(shù)

extern void wr_lcd (uchar dat_comm,uchar content); //向LCD寫入字符

/***************************** END Files***********************************/

這里注意三點:

在keil 編譯器中,extern這個關鍵字即使不聲明,編譯器也不會報錯,且程序運行良好,但不保證使用其它編譯器也如此。強烈建議加上,養(yǎng)成良好的編程規(guī)范。

.c文件中的函數(shù)只有其它模塊使用時才會出現(xiàn)在.h文件中,像本地延時函數(shù)static void delay (uint us)即使出現(xiàn)在.h文件中也是在做無用功,因為其它模塊根本不去調(diào)用它,實際上也調(diào)用不了它(static關鍵字的限制作用)。

注意本句最后一定要加分號”;”,相信有不少同學遇到過這個奇怪的編譯器報錯: error C132: ‘xxxx’: not in formal parameter list,這個錯誤其實是.h的函數(shù)聲明的最后少了分號的緣故。

模塊的應用: 假如需要在LCD菜單模塊lcd_menu.c中使用液晶驅動模塊lcd_device.c中的函數(shù)void wr_lcd (uchar dat_comm,uchar content),只需在LCD菜單模塊的lcd_menu.c文件中加入液晶驅動模塊的頭文件lcd_device.h即可。

#include“l(fā)cd_device.h //包含液晶驅動程序頭文件,之后就可以在該.c文件中調(diào)用//lcd_device.h中的全局函數(shù),使用液晶驅動程序里的全局//變量(如果有的話)。

//調(diào)用向LCD寫入字符函數(shù)

wr_lcd (0x01,0x30);

//對全局變量賦值

value=0xff;

某模塊提供給其它模塊調(diào)用的外部函數(shù)及數(shù)據(jù)需在.h 中文件中冠以extern 關鍵字聲明;這句話在上面的例子中已經(jīng)有體現(xiàn),即某模塊提供給其它模塊調(diào)用的外部函數(shù)和全局變量需在.h 中文件中冠以extern 關鍵字聲明,下面重點說一下全局變量的使用。使用模塊化編程的一個難點(相對于新手)就是全局變量的設定,初學者往往很難想通模塊與模塊公用的變量是如何實現(xiàn)的,常規(guī)的做法就是本句提到的,在.h文件中外部數(shù)據(jù)冠以extern關鍵字聲明。比如上例的變量value就是一個全局變量,若是某個模塊也使用這個變量,則和使用外部函數(shù)一樣,只需在使用的模塊.c文件中包含#include“l(fā)cd_device.h”即可。

另一種處理模塊間全局變量的方法來自于嵌入式操作系統(tǒng)uCOS-II,這個操作系統(tǒng)處理全局變量的方法比較特殊,也比較難以理解,但學會之后妙用無窮,這個方法只需用在頭文件中定義一次。方法為:

在定義所有全局變量(uCOS-II將所有全局變量定義在一個.h文件內(nèi))的.h頭文件中:

#ifdef xxx_GLOBALS

#define xxx_EXT

#else

#define xxx_EXT extern

#endif

.H 文件中每個全局變量都加上了xxx_EXT的前綴。xxx 代表模塊的名字。

該模塊的.C文件中有以下定義:

#define xxx_GLOBALS

#include “includes.h”

當編譯器處理.C文件時,它強制xxx_EXT(在相應.H文件中可以找到)為空,(因為xxx_GLOBALS已經(jīng)定義)。所以編譯器給每個全局變量分配內(nèi)存空間,而當編譯器處理其他.C 文件時,xxx_GLOBAL沒有定義,xxx_EXT 被定義為extern,這樣用戶就可以調(diào)用外部全局變量。為了說明這個概念,可以參見uC/OS_II.H,其中包括以下定義:

#ifdef OS_GLOBALS

#define OS_EXT

#else

#define OS_EXT extern

#endif

OS_EXT INT32U OSIdleCtr;

OS_EXT INT32U OSIdleCtrRun;

OS_EXT INT32U OSIdleCtrMax;

同時,uCOS_II.H 中有以下定義:

#define OS_GLOBALS

#include “includes.h”

當編譯器處理uCOS_II.C 時,它使得頭文件變成如下所示,因為OS_EXT 被設置為空。

INT32U OSIdleCtr;

INT32U OSIdleCtrRun;

INT32U OSIdleCtrMax;

這樣編譯器就會將這些全局變量分配在內(nèi)存中。當編譯器處理其他.C 文件時,頭文件變成了如下的樣子,因為OS_GLOBAL沒有定義,所以OS_EXT 被定義為extern。

extern INT32U OSIdleCtr;

extern INT32U OSIdleCtrRun;

extern INT32U OSIdleCtrMax;

在這種情況下,不產(chǎn)生內(nèi)存分配,而任何 .C文件都可以使用這些變量。這樣的就只需在 .H文件中定義一次就可以了。

模塊內(nèi)的函數(shù)和全局變量需在.c 文件開頭冠以static 關鍵字聲明;這句話主要講述了關鍵字static的作用。Static是一個相當重要的關鍵字,他能對函數(shù)和變量做一些約束,而且可以傳遞一些信息。比如上例在LCD驅動模塊.c文件中定義的延時函數(shù)static void delay (uint us),這個函數(shù)冠以static修飾,一方面是限定了函數(shù)的作用范圍只是在本模塊中起作用,另一方面也給人傳達這樣的信息:該函數(shù)不會被其他模塊調(diào)用。下面詳細說一下這個關鍵字的作用,在C 語言中,關鍵字static 有三個明顯的作用:

在函數(shù)體,一個被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。

在模塊內(nèi)(但在函數(shù)體外),一個被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問。它是一個本地的全局變量。

在模塊內(nèi),一個被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。

前兩個都比較容易理解,最后一個作用就是剛剛舉例中提到的延時函數(shù)(static void delay (uint us)),本地化函數(shù)是有相當好的作用的。

永遠不要在.h 文件中定義變量!比較一下代碼:

代碼一:

/*module1.h*/

int a = 5; /* 在模塊1 的.h 文件中定義int a */

/*module1 .c*/

#include “module1.h” /* 在模塊1 中包含模塊1 的.h 文件 */

/*module2 .c*/

#include “module1.h” /* 在模塊2 中包含模塊1 的.h 文件 */

/*module3 .c*/

#include “module1.h” /* 在模塊3 中包含模塊1 的.h 文件 */

以上程序的結果是在模塊1、2、3 中都定義了整型變量a,a 在不同的模塊中對應不同的地址元,這個世界上從來不需要這樣的程序。正確的做法是:

代碼二:

/*module1.h*/

extern int a; /* 在模塊1 的.h 文件中聲明int a */

/*module1 .c*/

#include “module1.h” /* 在模塊1 中包含模塊1 的.h 文件 */

int a = 5; /* 在模塊1 的.c 文件中定義int a */

/*module2 .c*/

#include “module1.h” /* 在模塊2 中包含模塊1 的.h 文件 */

/*module3 .c*/

#include “module1.h” /* 在模塊3 中包含模塊1 的.h 文件 */

這樣如果模塊1、2、3 操作a 的話,對應的是同一片內(nèi)存單元。

注:

一個嵌入式系統(tǒng)通常包括兩類(注意是兩類,不是兩個)模塊:

硬件驅動模塊,一種特定硬件對應一個模塊;

軟件功能模塊,其模塊的劃分應滿足低偶合、高內(nèi)聚的要求
責任編輯:pj

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 液晶驅動
    +關注

    關注

    1

    文章

    51

    瀏覽量

    11089
  • 編譯器
    +關注

    關注

    1

    文章

    1672

    瀏覽量

    51781
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    關鍵字volatile的含意

    關鍵字volatile有什么含意? 一個定義為volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優(yōu)化在用到這個變量時必須每次都小心
    發(fā)表于 12-23 06:33

    interrupt關鍵字使用

    中斷是嵌入式系統(tǒng)重要的組成部分,這導致了很多編譯開發(fā)商提供一種擴展—讓標準C支持中斷。具代表事實是,產(chǎn)生了一個新的關鍵字__interrupt。下面的代碼就使用了__interrupt關鍵字
    發(fā)表于 12-22 09:36

    Temu跨境電商按關鍵字搜索Temu商品API的應用及接口請求示例

    限于以下幾個方面: 用戶搜索商品:當用戶Temu平臺上輸入關鍵字搜索商品時,API會根據(jù)輸入的關鍵字返回與之相關的商品列表,幫助用戶快速找到感興趣的商品。 數(shù)據(jù)分析與市場調(diào)研:商家可以利用該API進行
    的頭像 發(fā)表于 11-29 15:08 ?547次閱讀

    哪些場合會用到volatile關鍵字?

    ,使用volatile關鍵字也許能減少代碼bug率。 2.寄存單片機開發(fā),寄存添加volatile關鍵字應該是必須的,如果你平時有仔細觀察,正規(guī)一點的【庫】都會添加volatile
    發(fā)表于 11-25 08:19

    天眼查平臺關鍵字搜索企業(yè)數(shù)據(jù)API接口技術指南

    ? 一、接口概述 天眼查提供的企業(yè)搜索API接口,支持通過關鍵字查詢企業(yè)工商信息、經(jīng)營狀態(tài)等核心數(shù)據(jù)。該接口采用RESTful架構,返回JSON格式數(shù)據(jù)。 二、接口認證 調(diào)用需使用API密鑰認證
    的頭像 發(fā)表于 11-21 11:48 ?802次閱讀
    天眼查平臺<b class='flag-5'>關鍵字</b>搜索企業(yè)數(shù)據(jù)API接口技術指南

    亞馬遜平臺根據(jù)關鍵字搜索商品API接口

    ? ?電商開發(fā),集成亞馬遜平臺的商品搜索功能是常見需求。通過亞馬遜的Product Advertising API(PAAPI),開發(fā)者可以根據(jù)關鍵字高效檢索商品信息。本技術帖將逐步介紹如何調(diào)用
    的頭像 發(fā)表于 11-05 15:00 ?441次閱讀
    亞馬遜平臺根據(jù)<b class='flag-5'>關鍵字</b>搜索商品API接口

    簡單的內(nèi)聯(lián)匯編介紹

    ”。 __volatile__或 volatile 是可選的。如果添加了該關鍵字,則要求編譯器對后續(xù)括號內(nèi)添加的匯編程序不進行任何優(yōu)化以保持其原狀;如果沒有添加此關鍵字,則編譯器可能會
    發(fā)表于 10-30 08:04

    【上海晶珩睿莓1開發(fā)板試用體驗】將TensorFlow-Lite物體歸類(classify)的輸出圖片移植到LVGL9.3界面

    的方式很簡單,就是用一個extern C關鍵字即可。 一些C語言中編譯能通過但在C++編譯
    發(fā)表于 09-21 00:39

    請問如何在keil μVision 5上進行ARM編譯器的代碼優(yōu)化?

    如何在keil μVision 5上進行ARM編譯器的代碼優(yōu)化?
    發(fā)表于 08-20 07:37

    如何在Keil中將NuMicro BSP從Arm編譯器5遷移到編譯器6?

    Keil中將NuMicro BSP從Arm編譯器5遷移到編譯器6!
    發(fā)表于 08-20 06:29

    micro 關鍵字搜索全覆蓋商品,并通過 API 接口提供實時數(shù)據(jù)

    micro 關鍵字搜索全覆蓋商品”并通過 API 接口提供實時數(shù)據(jù)
    的頭像 發(fā)表于 07-13 10:13 ?934次閱讀

    邊緣設備AI部署:編譯器如何實現(xiàn)輕量化與高性能?

    、ASIC等)上高效執(zhí)行的機器代碼。AI編譯器AI模型的部署和優(yōu)化扮演著關鍵角色,能夠顯著提升模型的運行效率和性能。 ? AI編譯器的主
    的頭像 發(fā)表于 07-06 05:49 ?6785次閱讀

    編譯器功能安全驗證的關鍵要素

    汽車、工業(yè)、醫(yī)療等安全關鍵型應用,確保功能安全合規(guī)性需要嚴格的工具鏈驗證。開發(fā)安全關鍵型軟件的企業(yè)必須遵守ISO 26262、IEC 61508、ISO 62304等國際標準對
    的頭像 發(fā)表于 07-05 13:37 ?1631次閱讀

    單片機編程關鍵字之volatile

    它的存在。也有很多人知道它的存在,根本沒用過,我對它有種“楊家有女初長成, 養(yǎng)深閨無人識”的感覺volatile 關鍵字到底是什么意思呢,怎么用呢1、volat
    發(fā)表于 04-02 13:47 ?2次下載

    帶你單片機編程熟練使用const(可下載)

    為常量、常數(shù)等我們一看到 const 關鍵字馬上就想到了常量。這是不精確的,精確來說應該是只讀變量其 值在編譯時不能被使用,因為編譯器編譯時不知道其存儲的內(nèi)容那么
    發(fā)表于 04-01 14:18 ?3次下載