娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年01月07日(星期二)

正在發生

2020年01月07日 | 淺談鏈表對stm32等芯片程序中的提升作用(C語言)

發布者:碼字狂徒 來源: eefocus關鍵字:鏈表  stm32  C語言 手機看文章 掃描二維碼
隨時隨地手機看文章

程序中經常面臨這樣的一個問題,需要創建一定數量的對象,但事前又不知道對象的具體個數,因此新手通常的做法都會為了能處理足夠的對象信息,創建一個足夠大的空間數組。這里舉個簡單的例子,某個應用要求管理學生信息,因此設置了這樣的一個結構體(類似于面向對象語言里說的成員屬性)


typedef struct 

{

int num;

int age;

char *name;

}studentInfo;

在不引入鏈表的情況下,為了能管理盡可能多的學生信息,可能會這樣創建這個結構體的實體:


studentInfo student[1024*100];

int studentCnt = 0;    //記錄已經管理的學生數量

這樣的處理方法,理論上能實現需求,而且在學生數量還小的時候,這個程序基本也不會出現明顯的問題。但這樣的做法存在很多方面的問題,當一個數組被創建時,其在內存中的大小就已經被固定了,所以,1,當學生數量較小時,這個程序的處理方法浪費了大量的內存空間,特別是在資源緊缺的單片機嵌入式系統中,這樣的做法是不符合要求的。2,當學生數量大于設置的數量時(即例子中的1024*100),即使系統中還剩有內存空間可以繼續添加,而這個程序也無法再添加學生信息。3,當學生數量比較大時,遇到刪除信息的操作,程序的處理效率非常低,處理方法通常是,找個需要刪除的信息的存放位置,然后把后面的信息逐步往前覆蓋,如果刪除的是最后一個,則設置為0,從而達到刪除的目的。


如果引入鏈表,以上的三個問題都能完美解決,但需要配合內存管理才能實現,因此如果是嵌入式系統,還需要實現內存管理方面的功能,關于內存管理,將在下篇文章中提到。使用鏈表的方式,在原有的成員屬性結構體的前提上,還要再封裝多一層鏈表管理。以單向鏈表為例:


typedef struct 

{

int num;

int age;

char *name;

}studentInfo;

 

typedef struct students

{

struct students *nextStudent;    //用于指向下一個學生信息

studentInfo *Info;     //具體的信息

}studentsTypedef; 

 

studentsTypedef *headStudents; //鏈表的頭指針

看到這里,會發現用到的基本上是指針,有些同學可能會比較害怕用指針,其實用多了就會發現,指針也就是那么回事。好了,既然是指針,那么它是沒有用來存放數據的內存空間的,而鏈表的精髓在于,具體的數據信息是通過內存管理申請內存存放,而鏈表結構則負責指向各自負責管理的數據,從而實現關聯。


由于在定義的時候,只定義了一個頭指針,那么它也只是個指向了studentsTypedef也就是鏈表結構體的指針,同樣沒有內存空間,在沒有創建新增鏈表之前,它是一個野指針。


所以,在具體應用之前,需要先執行一個初始化操作,也就是申請空間給鏈表管理結構體,然后頭指針指向這個空間。


//

//初始化

//

bool studentsListInit(void)

{

    //申請鏈表類型大小的空間,并讓頭指針指向它

headStudents = (studentsTypedef*)malloc(sizeof(studentsTypedef));

if(headStudents == NULL) return false;

 

    //同時要標記下一個信息為空

headStudents->nextStudent = NULL;

return true;

}

這里使用了一個malloc函數,作用是申請內存,在PC端編寫測試程序時可以使用這個函數,需要包含的頭文件時malloc.h。如果是在嵌入式系統中,直接使用malloc會導致一些內存碎片的問題,比較多的做法是自己實現一定的內存管理方法,包括申請內存,釋放內存,高端的內存管理方法還會包含碎片整理的功能。如果是使用類似FreeRTOS這樣的操作系統,RTOS中已經為我們提供了幾種內存管理的方法,使用較廣泛的heap4。


需要新增一個學生信息,實現方法可以這樣寫:


bool AddStudentToList(studentInfo *stuInfo)

{

    //在鏈表的最后加入

studentsTypedef *p = headStudents;

while(p->nextStudent!=NULL)

{

p = p->nextStudent;

}

    

    //先申請鏈表結構體的空間,因為后續還要繼續增加

p->nextStudent =  (studentsTypedef*)malloc(sizeof(studentsTypedef));

if(p->nextStudent == NULL) return false;

    

    //指向剛剛申請的空間,并為需要存放的學生信息申請對應的內存

p = p->nextStudent;

p->Info = (studentInfo*)malloc(sizeof(studentInfo));

if(p->Info == NULL) 

    {

        free(p);//由于申請失敗,先前申請的鏈表空間也要釋放

        return false;

    }    

 

    //具體信息賦值

memcpy(p->Info,stuInfo,sizeof(studentInfo));

 

    //標記這個鏈表的尾部

p->nextStudent=NULL;

 

    //添加成功

return true;

}


到這里可以發現,當需要添加一個學生的管理信息時,這里的程序就相應的申請一個學生信息所需要的空間,這樣一來,可以實現內存的利用最大化,不會出現申請了內存但不使用的情況。到這里已經解決了上面說到的2個問題。


下面再來看刪除操作:


bool deleteStudentInfo_AccordingNum(int num)

{

bool res = false;

studentsTypedef *p =  headStudents;

while(p->nextStudent!=NULL)

{

studentsTypedef *temp = p;

p = p->nextStudent;

if(p->Info->num == num)

{

temp->nextStudent = p->nextStudent;

//釋放內存空間 

free(p->Info);

free(p);

p=temp;

res = true;

}

}

return res;

}

可以看到,刪除一個節點,只需要找到該節點的位置,至于怎么找這個節點,可以根據不同的方法,我這里只是隨便舉個例子。找到之后,只需要改變一下原來鏈表結構的指向,并釋放被刪除節點所占用的內存空間,整個刪除操作就完成了,不需要像數組那樣,找到之后,還要把后面的節點逐個往前面移動,效率非常低。當然,鏈表也并不是完全優于數組的,鏈表的訪問只能從頭節點開始,而數組的訪問,可以直接使用下標,結合一定的算法,如二分排序法等,使用數組的方法的查找效率就高于鏈表的方法,具體如何選擇,需要看實際的應用場景。


最后再貼上main函數中,測試的部分。


void printfStudentInfo(void)

{

printf(" list      num age namern");

studentsTypedef *p = headStudents;

int i=0;

while(p->nextStudent!=NULL)

{

p = p->nextStudent;

printf("  %d %d %d %srn",i,p->Info->num,p->Info->age,p->Info->name);

i++;

}

printf("----------------------------end--------------------rn");

 

 

int main(int argc,char *argv[])

{

printf("-------------List test---------------rn"); 

if(!studentsListInit( ))

{

printf("Memory fail..rn");

}

 

studentInfo temp;

for(int i=0;i<5;i++)

{

temp.age = 20+i;

temp.num = i;

temp.name = (char*)"A";

if(!AddStudentToList(&temp))

{

printf("Add student %d info failrn",i);

}

}

printfStudentInfo();

deleteStudentInfo_AccordingNum(4);

printfStudentInfo();

 

temp.age = 18;

temp.num = 1001;

temp.name = (char*)"TEST";

if(!AddStudentToList(&temp))

{

printf("Add student %d info failrn",1001);

}

printfStudentInfo();

}

關鍵字:鏈表  stm32  C語言 引用地址:淺談鏈表對stm32等芯片程序中的提升作用(C語言)

上一篇:對GPIO_Init(GPIOx,&GPIO_InitStructure)的理解
下一篇:stm32創建鏈表相關問題

推薦閱讀

前不久,由清華大學智能網聯汽車與交通研究中心、清新汽車、清研車聯主辦的智輪行第三期沙龍「智能化的新能源汽車如何引領新出行?」在北京清華大學舉行。清華大學汽車工程系主任、教授楊殿閣做了主題演講。?智能汽車的發展不僅僅是汽車產業的革命,也是未來交通出行的一場革命。百姓需要更多的車輛解決交通需求,但交通資源的限制導致城市的嚴重擁堵。智...
臺積電今年實習計劃正式啟動,開放在學學生報名,實習生月薪介于2.2萬至3.5萬元新臺幣(下同)。 聯合報系數據照晶圓代工龍頭臺積電今年實習計劃正式啟動,開放在學學生報名,實習領域包括研究與發展、IC 設計、營運制造、信息工程、人力資源、財務、法務 、企業規劃等。 臺積電也首度公開實習生月薪介于2.2萬至3.5萬元,讓在學學生利用實習機會比別人更...
Qualcomm Incorporated子公司Qualcomm Technologies, Inc.今日在2020年國際消費電子展(CES 2020)上推出全新Qualcomm? Snapdragon Ride?平臺,擴展公司廣泛的汽車產品組合。該平臺是汽車行業最先進且可擴展的開放自動駕駛解決方案之一,包括Snapdragon Ride?安全系統級芯片、Snapdragon Ride?安全加速器和Snapdragon Ride?自動駕駛軟件棧。...
連接與電子解決方案提供商Molex莫仕發布面向汽車行業決策者的全球性調研成果,對將會影響到“未來汽車”戰略與商業決策的主流趨勢與技術進行了展望。調研結果對促成電氣化與互聯化的數據、軟件及網絡所發揮的關鍵作用給予了充分的肯定 – 已經將這兩方面認定為最重要的創新領域。 Molex莫仕負責交通運輸與工業解決方案的高級副總裁 Mike Bloomgren 表示:...

史海拾趣

問答坊 | AI 解惑

用12864LCD做得電子鐘

用12864LCD做得電子鐘…

查看全部問答∨

汽車電器的電路保護: 拋負載、ESD及其它異常

汽車電器的電路保護: 拋負載、ESD及其它異常 主要內容 • 車載電子設備的電路保護 • 線束保護 • 間斷工作馬達保護…

查看全部問答∨

尋找數據采集板硬件開發調試人員

硬件工程師,從事硬件開發的專職人員,熟悉模擬電子線路,數字電子線路,CPLD,有開發工具,特別是數字示波器,信號源等.主要負責示波器前端模擬電路的調試.PCB已經畫好。 您將獲得這次獲得的兩塊PCB(面板和數據采集板)以及主要元器件,還有CPLD下載線 ...…

查看全部問答∨

關于筆記本到FPGA開發板的下載線問題,請教!

請高手幫我解決這個疑問:       由于我的筆記本沒有并口,然而導師給我的下載線只是并口到JTAG的,所以我就去市場買了根從USB口到并口的轉換線,然后連接起來使用,心想就可以下載了。      只是今天我 ...…

查看全部問答∨

工控行業的一點體會

根據多年的工控產品的設計,覺得工業領域產品主要可靠,安全第一。其次追求精度,界面美觀,操作方便等問題…

查看全部問答∨

pcb線路板印刷常見的20種問題

  在電路板絲網印刷過程中可以分為9個部分56個變量,這就要求大家有正確的操作程序或者就會出現以下現象。   網版不管怎樣拉,始終無法拉均勻,或者經常出現爆裂。   網布與網框粘不牢固,干的慢,或者撕不掉。   網版上110網布容易脫落 ...…

查看全部問答∨

在通過串口調試工具向modem com3口寫AT命令ATDT96169后connect 返回CONNECT后一段時間出現 NO CARRIER

在通過串口調試工具向modem com3口寫AT命令ATDT96169后connect 返回CONNECT,接      著下面出現~#}?}#?}!}#}   }=}!}$}\'衹"}&}   }*}   }   }\'}"}(}"}%}&7て拀#}%?}% ...…

查看全部問答∨

內核簡單問題

掃盲了,請問wince內核是什么?像Windows 98、Windows 95、Windows ME是9X內核的,WindowsNT、Windows2000、WindowsXP、Windows Vista是NT內核的,wince是不是也是9X內核的?謝謝各位掃盲!…

查看全部問答∨

如何把eboot燒到arm EP9315 的flash中

請教,如何把eboot程序燒到arm EP9315 的flash中?謝謝大家!…

查看全部問答∨

一個困擾了很久的問題:如何從芯片手冊到編寫驅動

這個問題困擾我很久了,面對一大堆的芯片手冊,卻找不到編寫驅動的步驟. 芯片手冊里,詳細地描述了該芯片支持的特征,端口的描述,工作的信號圖,注意事項,結構方塊圖,物理參數... 卻總沒找到如何開始寫一個驅動的初始化過程,讀過程,寫過程,狀態的獲取 ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 巴青县| 河西区| 嫩江县| 温泉县| 高邮市| 河北区| 绥滨县| 江门市| 秭归县| 孙吴县| 绥中县| 兖州市| 巴南区| 禄丰县| 聂拉木县| 长治市| 武义县| 广德县| 铜鼓县| 太和县| 上犹县| 饶河县| 伊宁市| 韶山市| 郓城县| 苏州市| 万荣县| 特克斯县| 庆城县| 宁明县| 新密市| 永年县| 滦南县| 铜梁县| 宁陵县| 吴江市| 定结县| 邓州市| 托克托县| 固原市| 随州市|