FreeRTOS的列表和列表項

列表和列表項

列表

列表是FreeRTOS中的一個數據結構,概念上和鏈表有點類型,是一個循環雙向鏈表,列表被用來跟蹤FreeRTOS中的任務。列表的類型是List_T,具體定義如下:

typedef struct xLIST
{listFIRST_LIST_INTEGRITY_CHECK_VALUE				/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */configLIST_VOLATILE UBaseType_t uxNumberOfItems;ListItem_t * configLIST_VOLATILE pxIndex;			/*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */MiniListItem_t xListEnd;							/*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */listSECOND_LIST_INTEGRITY_CHECK_VALUE				/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
} List_t;
  • listFIRST_LIST_INTEGRITY_CHECK_VALUE和listSECOND_LIST_INTEGRITY_CHECK_VALUE都是用來檢查列表完整性的,需要將宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 設置為1,默認不開啟。
  • uxNumberOfItems:記錄列表項的數量
  • pxIndex:指向當前的列表項,可用來遍歷列表,類型是ListItem_t *
  • xListEnd:作為一個標記,表示列表最后一個列表項,類型是MiniListItem_t 。
列表項

FreeRTOS提供了兩種列表項:列表項(ListItem_t 類型)和迷你列表項(MiniListItem_t 類型)。對于列表項,具體定義為:

struct xLIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */configLIST_VOLATILE TickType_t xItemValue;			/*< The value being listed.  In most cases this is used to sort the list in descending order. */struct xLIST_ITEM * configLIST_VOLATILE pxNext;		/*< Pointer to the next ListItem_t in the list. */struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;	/*< Pointer to the previous ListItem_t in the list. */void * pvOwner;										/*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */void * configLIST_VOLATILE pvContainer;				/*< Pointer to the list in which this list item is placed (if any). */listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
};
typedef struct xLIST_ITEM ListItem_t;					/* For some reason lint wants this as two separate definitions. */
  • listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE檢查列表項完整性
  • xItemValue:列表項的值
  • pxNext:指向下一個列表項
  • pxPrevious:指向前一個列表項
  • pvOwner:記錄此列表項歸誰擁有,通常是任務控制塊
  • pvContainer:記錄該列表項歸哪個列表

迷你列表項:

struct xMINI_LIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */configLIST_VOLATILE TickType_t xItemValue;struct xLIST_ITEM * configLIST_VOLATILE pxNext;struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

可以看出迷你列表項只是比列表項少了幾個成員變量,迷你列表項所有的成員變量列表項都有。
對于列表結構體List_t中的xListEnd是MiniListItem_t類型,表示最后一個列表項,pxIndex是ListItem_t指針類型,指向真正有數據的列表項。

列表和列表項初始化

列表初始化

新創建的或者定義的列表需要對其做初始化處理,列表初始化其實就是初始化列表結構體List_t中的各個成員變量,列表的初始化通過函數vListInitialise()來完成。

void vListInitialise( List_t * const pxList )
{/* The list structure contains a list item which is used to mark theend of the list.  To initialise the list the list end is insertedas the only list entry. */pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );			/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. *//* The list end value is the highest possible value in the list toensure it remains at the end of the list. */pxList->xListEnd.xItemValue = portMAX_DELAY;/* The list end next and previous pointers point to itself so we knowwhen the list is empty. */pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );	/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */pxList->uxNumberOfItems = ( UBaseType_t ) 0U;/* Write known values into the list ifconfigUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

函數的參數是一個列表

  • pxIndex 指向強制類型轉換的xListEnd
  • xItemValue 列表項的值為portMAX_DELAY
    在這里插入圖片描述
  • pxNext :指向自己
  • pxPrevious :指向自己
  • uxNumberOfItems :列表中的列表項數目為0

下圖為初始化后的列表
在這里插入圖片描述

列表項初始化
void vListInitialiseItem( ListItem_t * const pxItem )
{/* Make sure the list item is not recorded as being on a list. */pxItem->pvContainer = NULL;/* Write known values into the list item ifconfigUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

函數的參數是一個列表項指針,只是將列表項的pvContainer初始化為NULL
下圖為列表項初始后的列表項
在這里插入圖片描述

列表項插入

列表項插入相當于和在循環雙向鏈表中按照數值的遞增插入數據原理是一樣的。
列表項的插入式通過函數vListInsert來完成的

void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )

參數:

  • pxList:要插入的列表
  • pxNewListItem :要插入的列表項
    vListInsert是根據pxNewListItem 中的成員變量xItemValue的值來決定插入位置。根據xItemValue的升序方式排序。

具體插入過程如下:

void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t *pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;/* Only effective when configASSERT() is also defined, these tests may catchthe list data structures being overwritten in memory.  They will not catchdata errors caused by incorrect configuration or use of FreeRTOS. */listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );/* Insert the new list item into the list, sorted in xItemValue order.If the list already contains a list item with the same item value then thenew list item should be placed after it.  This ensures that TCB's which arestored in ready lists (all of which have the same xItemValue value) get ashare of the CPU.  However, if the xItemValue is the same as the back markerthe iteration loop below will not end.  Therefore the value is checkedfirst, and the algorithm slightly modified if necessary. */if( xValueOfInsertion == portMAX_DELAY ){pxIterator = pxList->xListEnd.pxPrevious;}else{/* *** NOTE ***********************************************************If you find your application is crashing here then likely causes arelisted below.  In addition see http://www.freertos.org/FAQHelp.html formore tips, and ensure configASSERT() is defined!http://www.freertos.org/a00110.html#configASSERT1) Stack overflow -see http://www.freertos.org/Stacks-and-stack-overflow-checking.html2) Incorrect interrupt priority assignment, especially on Cortex-Mparts where numerically high priority values denote low actualinterrupt priorities, which can seem counter intuitive.  Seehttp://www.freertos.org/RTOS-Cortex-M3-M4.html and the definitionof configMAX_SYSCALL_INTERRUPT_PRIORITY onhttp://www.freertos.org/a00110.html3) Calling an API function from within a critical section or whenthe scheduler is suspended, or calling an API function that doesnot end in "FromISR" from an interrupt.4) Using a queue or semaphore before it has been initialised orbefore the scheduler has been started (are interrupts firingbefore vTaskStartScheduler() has been called?).**********************************************************************/for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */{/* There is nothing to do here, just iterating to the wantedinsertion position. */}}pxNewListItem->pxNext = pxIterator->pxNext;pxNewListItem->pxNext->pxPrevious = pxNewListItem;pxNewListItem->pxPrevious = pxIterator;pxIterator->pxNext = pxNewListItem;/* Remember which list the item is in.  This allows fast removal of theitem later. */pxNewListItem->pvContainer = ( void * ) pxList;( pxList->uxNumberOfItems )++;
}
  1. 獲取pxNewListItem的xItemValue值
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
  1. 檢查列表和列表項的完整性
	listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
  1. 判斷插入的位置,如果等于portMAX_DELAY ,列表項的最大值,插入的位置是列表最末尾
	if( xValueOfInsertion == portMAX_DELAY ){pxIterator = pxList->xListEnd.pxPrevious;}
  1. 不等于portMAX_DELAY ,則for循環找到插入位置,這個查找過程是按照升序的方式查找列表項插入點的,列表的xListEnd 可以想成鏈表的頭,不放數據,方便查詢用的,xListEnd 指向的列表項的xItemValue 值最小
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) 
  1. 將列表項插入到列表中
	pxNewListItem->pxNext = pxIterator->pxNext;pxNewListItem->pxNext->pxPrevious = pxNewListItem;pxNewListItem->pxPrevious = pxIterator;pxIterator->pxNext = pxNewListItem;/* Remember which list the item is in.  This allows fast removal of theitem later. */pxNewListItem->pvContainer = ( void * ) pxList;
  1. 列表的列表項數目加1
	( pxList->uxNumberOfItems )++;
列表項插入過程

一個初始化的空列表如下:
在這里插入圖片描述
插入值為40的列表項后
在這里插入圖片描述

插入值60的列表項
在這里插入圖片描述
插入50后的列表項為
在這里插入圖片描述

列表末尾插入

末尾插入就不根據xItemValue了,直接插入末端。原理和在循環雙向鏈表的末尾插入數據是一樣的

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )

列表項的刪除

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove );
  • pxItemToRemove :要刪除的列表項

列表的遍歷

列表結構體中的pxIndex是用來遍歷鏈表的,在說列表項插入的時候,也用到了列表的遍歷,具體代碼如下:

for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) 

FreeRTOS提供了一個函數來完成列表的遍歷,這個函數是listGET_OWNER_OF_NEXT_ENTRY。每調用一次該函數pxIndex變量就會指向下一個列表項,并且返回這個列表項的pxOwner變量值

#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )										\
{																							\
List_t * const pxConstList = ( pxList );													\/* Increment the index to the next item and return the item, ensuring */				\/* we don't return the marker used at the end of the list.  */							\( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;							\if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )	\{																						\( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;						\}																						\( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;											\
}

pxTCB用來保存pxIndex所指向的列表項pvOwner變量值。pxList是要遍歷的列表
將pxIndex指向下一個列表項

( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;

如果指向的列表項是xListEnd ,表示已經到了列表末尾,然后跳過末尾,再一次重新指向列表的第一個列表項。

	if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )	\{																						\( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;						\}	

將pxIndex所指向的新列表項的pvOwner賦值給pxTCB

	( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;			

列表項的插入和刪除實驗

實驗設計,三個任務:
start_task:創建其他兩個任務
task1_task:應用任務1,控制LED0閃爍,用來提示系統正在運行
task2_task:列表和列表項操作任務,調用列表和列表相關的API,并且通過串口輸出相應的信息來觀察這些API函數的運行過程。

任務設置
#define START_STACK_SIZE 128
#define START_TASK_PIO 1
TaskHandle_t Start_Handler;
void start_task(void * pvParameters);#define TASK1_STACK_SIZE 128
#define TASK1_TASK_PIO 2
TaskHandle_t Task1_Handler;
void task1_task(void * pvParameters);#define TASK2_STACK_SIZE 128
#define TASK2_TASK_PIO 3
TaskHandle_t Task2_Handler;
void task2_task(void * pvParameters);
列表項和列表的定義
//定義一個測試用的列表和是哪個列表項
List_t TestList;
ListItem_t ListItem1;
ListItem_t ListItem2;
ListItem_t ListItem3;
main函數
int main(void)
{HAL_Init();                     //初始化HAL庫   Stm32_Clock_Init(360,25,2,8);   //設置時鐘,180Mhzdelay_init(180);                //初始化延時函數uart_init(115200);              //初始化串口LED_Init();                     //初始化LED KEY_Init();						//初始化按鍵SDRAM_Init();					//初始化SDRAMLCD_Init();						//初始化LCDPOINT_COLOR = RED;LCD_ShowString(30,10,200,16,16,"Apollo STM32F4/F7");	LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 7-1");LCD_ShowString(30,50,200,16,16,"list and listItem");LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,90,200,16,16,"2016/10/9");//創建開始任務xTaskCreate(start_task,"start_task",START_STACK_SIZE,NULL,START_TASK_PIO,&Start_Handler);vTaskStartScheduler();
}
任務函數
//開始任務任務函數
void start_task(void * pvParameters)
{taskENTER_CRITICAL();		//進入臨界區//創建任務xTaskCreate(task1_task,"task1_task",TASK1_STACK_SIZE,NULL,TASK1_TASK_PIO,&Task1_Handler);xTaskCreate(task2_task,"task1_task",TASK2_STACK_SIZE,NULL,TASK2_TASK_PIO,&Task2_Handler);vTaskDelete(Start_Handler);//退出臨界區taskEXIT_CRITICAL();
}//task1任務函數
void task1_task(void * pvParameters)
{while(1){LED0 = !LED0;vTaskDelay(500);}
}
//list任務函數
void task2_task(void * pvParameters)
{//初始化列表和列表項vListInitialise(&TestList);vListInitialiseItem(&ListItem1);vListInitialiseItem(&ListItem2);vListInitialiseItem(&ListItem3);ListItem1.xItemValue=40;ListItem2.xItemValue = 60;ListItem3.xItemValue=50;//第二步:打印列表和其他列表項的地址printf("/*******************列表和列表項地址*******************/\r\n");printf("項目                              地址				    \r\n");printf("TestList                          %#x					\r\n",(int)&TestList);printf("TestList->pxIndex                 %#x					\r\n",(int)TestList.pxIndex);printf("TestList->xListEnd                %#x					\r\n",(int)(&TestList.xListEnd));printf("ListItem1                         %#x					\r\n",(int)&ListItem1);printf("ListItem2                         %#x					\r\n",(int)&ListItem2);printf("ListItem3                         %#x					\r\n",(int)&ListItem3);printf("/************************結束**************************/\r\n");printf("按下KEY_UP鍵繼續!\r\n\r\n\r\n");while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);	//第三步:向列表TestList添加列表項ListItem1,并通過串口打印所有//列表項中成員變量pxNext和pxPrevious的值,通過這兩個值觀察列表//項在列表中的連接情況。vListInsert(&TestList,&ListItem1);		//插入列表項ListItem1printf("/******************添加列表項ListItem1*****************/\r\n");printf("項目                              地址				    \r\n");printf("TestList->xListEnd->pxNext        %#x					\r\n",(int)(TestList.xListEnd.pxNext));printf("ListItem1->pxNext                 %#x					\r\n",(int)(ListItem1.pxNext));printf("/*******************前后向連接分割線********************/\r\n");printf("TestList->xListEnd->pxPrevious    %#x					\r\n",(int)(TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious             %#x					\r\n",(int)(ListItem1.pxPrevious));printf("/************************結束**************************/\r\n");printf("按下KEY_UP鍵繼續!\r\n\r\n\r\n");while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);	//第四步:向列表TestList添加列表項ListItem2,并通過串口打印所有//列表項中成員變量pxNext和pxPrevious的值,通過這兩個值觀察列表//項在列表中的連接情況。vListInsert(&TestList,&ListItem2);	//插入列表項ListItem2printf("/******************添加列表項ListItem2*****************/\r\n");printf("項目                              地址				    \r\n");printf("TestList->xListEnd->pxNext        %#x					\r\n",(int)(TestList.xListEnd.pxNext));printf("ListItem1->pxNext                 %#x					\r\n",(int)(ListItem1.pxNext));printf("ListItem2->pxNext                 %#x					\r\n",(int)(ListItem2.pxNext));printf("/*******************前后向連接分割線********************/\r\n");printf("TestList->xListEnd->pxPrevious    %#x					\r\n",(int)(TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious             %#x					\r\n",(int)(ListItem1.pxPrevious));printf("ListItem2->pxPrevious             %#x					\r\n",(int)(ListItem2.pxPrevious));printf("/************************結束**************************/\r\n");printf("按下KEY_UP鍵繼續!\r\n\r\n\r\n");while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);		//第五步:向列表TestList添加列表項ListItem3,并通過串口打印所有//列表項中成員變量pxNext和pxPrevious的值,通過這兩個值觀察列表//項在列表中的連接情況。vListInsert(&TestList,&ListItem3);	//插入列表項ListItem3printf("/******************添加列表項ListItem3*****************/\r\n");printf("項目                              地址				    \r\n");printf("TestList->xListEnd->pxNext        %#x					\r\n",(int)(TestList.xListEnd.pxNext));printf("ListItem1->pxNext                 %#x					\r\n",(int)(ListItem1.pxNext));printf("ListItem3->pxNext                 %#x					\r\n",(int)(ListItem3.pxNext));printf("ListItem2->pxNext                 %#x					\r\n",(int)(ListItem2.pxNext));printf("/*******************前后向連接分割線********************/\r\n");printf("TestList->xListEnd->pxPrevious    %#x					\r\n",(int)(TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious             %#x					\r\n",(int)(ListItem1.pxPrevious));printf("ListItem3->pxPrevious             %#x					\r\n",(int)(ListItem3.pxPrevious));printf("ListItem2->pxPrevious             %#x					\r\n",(int)(ListItem2.pxPrevious));printf("/************************結束**************************/\r\n");printf("按下KEY_UP鍵繼續!\r\n\r\n\r\n");while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);	//第六步:刪除ListItem2,并通過串口打印所有列表項中成員變量pxNext和//pxPrevious的值,通過這兩個值觀察列表項在列表中的連接情況。uxListRemove(&ListItem2);						//刪除ListItem2printf("/******************刪除列表項ListItem2*****************/\r\n");printf("項目                              地址				    \r\n");printf("TestList->xListEnd->pxNext        %#x					\r\n",(int)(TestList.xListEnd.pxNext));printf("ListItem1->pxNext                 %#x					\r\n",(int)(ListItem1.pxNext));printf("ListItem3->pxNext                 %#x					\r\n",(int)(ListItem3.pxNext));printf("/*******************前后向連接分割線********************/\r\n");printf("TestList->xListEnd->pxPrevious    %#x					\r\n",(int)(TestList.xListEnd.pxPrevious));printf("ListItem1->pxPrevious             %#x					\r\n",(int)(ListItem1.pxPrevious));printf("ListItem3->pxPrevious             %#x					\r\n",(int)(ListItem3.pxPrevious));printf("/************************結束**************************/\r\n");printf("按下KEY_UP鍵繼續!\r\n\r\n\r\n");while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);	//第七步:刪除ListItem2,并通過串口打印所有列表項中成員變量pxNext和//pxPrevious的值,通過這兩個值觀察列表項在列表中的連接情況。TestList.pxIndex=TestList.pxIndex->pxNext;			//pxIndex向后移一項,這樣pxIndex就會指向ListItem1。vListInsertEnd(&TestList,&ListItem2);				//列表末尾添加列表項ListItem2printf("/***************在末尾添加列表項ListItem2***************/\r\n");printf("項目                              地址				    \r\n");printf("TestList->pxIndex                 %#x					\r\n",(int)TestList.pxIndex);printf("TestList->xListEnd->pxNext        %#x					\r\n",(int)(TestList.xListEnd.pxNext));printf("ListItem2->pxNext                 %#x					\r\n",(int)(ListItem2.pxNext));printf("ListItem1->pxNext                 %#x					\r\n",(int)(ListItem1.pxNext));printf("ListItem3->pxNext                 %#x					\r\n",(int)(ListItem3.pxNext));printf("/*******************前后向連接分割線********************/\r\n");printf("TestList->xListEnd->pxPrevious    %#x					\r\n",(int)(TestList.xListEnd.pxPrevious));printf("ListItem2->pxPrevious             %#x					\r\n",(int)(ListItem2.pxPrevious));printf("ListItem1->pxPrevious             %#x					\r\n",(int)(ListItem1.pxPrevious));printf("ListItem3->pxPrevious             %#x					\r\n",(int)(ListItem3.pxPrevious));printf("/************************結束**************************/\r\n\r\n\r\n");while(1){LED1=!LED1;vTaskDelay(1000);                           //延時1s,也就是1000個時鐘節拍	}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379746.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379746.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379746.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

string基本字符系列容器

二、string基本字符系列容器 簡介&#xff1a;C語言只提供了一個char類型來處理字符&#xff0c;而對于字符串&#xff0c;只能通過字符串數組來處理&#xff0c;顯得十分不方便。CSTL提供了string基本字符系列容器來處理字符串&#xff0c;可以把string理解為字符串類&#x…

正則表達式(一)

正則表達式概述 1.1什么是正則表達式&#xff1f; 正則表達式(Regular Expression)起源于人類神經系統的早期研究。神經生理學家Warren McCulloch和Walter Pitts研究出一種使用數學方式描述神經網絡的方法。1956年&#xff0c;數學家Stephen Kleene發表了一篇標題為“神經…

42.有“舍”才有“得”

大干世界&#xff0c;萬種誘惑&#xff0c;什么都想要&#xff0c;會累死你&#xff0c;該放就放&#xff0c;該舍就舍。人必須先有所舍&#xff0c;才能有所得&#xff0c;舍如同種子撒播出去&#xff0c;轉了一圈&#xff0c;又帶了一大群子子孫孫回來。“舍”永遠在“得”的…

Java StringBuilder codePointCount()方法與示例

StringBuilder類codePointCount()方法 (StringBuilder Class codePointCount() method) codePointCount() method is available in java.lang package. codePointCount()方法在java.lang包中可用。 codePointCount() method is used to count the number of Unicode code point…

FreeRTOS時間管理

在使用FreeRTOS的過程中&#xff0c;我們通常會在一個任務函數中使用延時函數對這個任務延時&#xff0c;當執行延時函數的時候就會進行任務切換&#xff0c;并且此任務就會進入阻塞太&#xff0c;直到延時完成&#xff0c;任務重新進入就緒態。延時函數舒屬于FreeRTOS的時間管…

set和multiset集合容器

三、①set集合容器 簡介&#xff1a;set集合的目的就是為了快速檢索。set集合容器實現了紅黑樹的平衡二叉檢索樹的數據結構。set集合里面不允許有重復的元素出現&#xff1b;使用set容器前&#xff0c;需要在程序的頭文件中聲明 #include < set >。 函數方法總結&#…

javascript獲取select的值全解

獲取顯示的漢字 document.getElementById("bigclass").options[window.document.getElementById("bigclass").selectedIndex].text 獲取數據庫中的id window.document.getElementById("bigclass").value 獲取select組分配的索引id window.docume…

Java File類void deleteOnExit()方法(帶示例)

文件類void deleteOnExit() (File Class void deleteOnExit()) This method is available in package java.io.File.deleteOnExit(). 軟件包java.io.File.deleteOnExit()中提供了此方法。 This method is used to delete the file or directory when the virtual machine termi…

FreeRTOS隊列

在實際應用中&#xff0c;我們會遇到一個任務或者中斷服務需要和另一個任務進行消息傳遞&#xff0c;FreeRTOS提供了隊列的機制來完成任務與任務、任務與中斷之間的消息傳遞。 0x01 隊列簡介 隊列是為了任務與任務、任務與中斷之間的通信而準備的&#xff0c;可以在任務與任務…

括號配對問題(C)

描述 現在&#xff0c;有一行括號序列&#xff0c;請你檢查這行括號是否配對。 輸入 第一行輸入一個數N&#xff08;0<N<100&#xff09;,表示有N組測試數據。后面的N行輸入多組輸入數據&#xff0c;每組輸入數據都是一個字符串S(S的長度小于10000&#xff0c;且S不是空串…

劇情介紹:“阿甘正傳”

阿甘是個智商只有75的低能兒。在學校里為了躲避別的孩子的欺侮&#xff0c;聽從一個朋友珍妮的話而開始“跑”。他跑著躲避別人的捉弄。在中學時&#xff0c;他為了躲避別人而跑進了一所學校的橄欖球場&#xff0c;就這樣跑進了大學。阿甘被破格錄取&#xff0c;并成了橄欖球巨…

java 方法 示例_Java集合syncedList()方法與示例

java 方法 示例集合類syncList()方法 (Collections Class synchronizedList() method) synchronizedList() method is available in java.util package. syncList()方法在java.util包中可用。 synchronizedList() method is used to return the synchronized view of the given…

FreeRTOS信號量---二值信號量

信號量可以用來進行資源管理和任務同步&#xff0c;FreeRTOS中信號量又分為二值信號量、計算型信號量、互斥信號量和遞歸互斥信號量。 0x01 二值信號量 二值信號量其實就是一個只有一個隊列項的隊列&#xff0c;這個特殊的隊列要么是滿的&#xff0c;要么是空的&#xff0c;任…

Linux 上 rpm包管理工具的基本使用

查詢是否安裝某個包&#xff1a;rpm -q 包名查詢所有已安裝的包&#xff1a;rpm -q a查詢未安裝包的文件信息&#xff1a;rpm -qilp 未安裝的包安裝包&#xff1a;rpm -i 包測試安裝包&#xff1a;rpm -i test 包刪除包&#xff1a;rpm -e 包名測試刪除包&#xff1a;rpm -e te…

ios 內存使用陷阱

在iphone開發過程中&#xff0c;代碼中的內存泄露我們很容易用內存檢測工具leaks 檢測出來&#xff0c;并一一改之&#xff0c;但有些是因為ios 的缺陷和用法上的錯誤&#xff0c;leaks 檢測工具并不能檢測出來&#xff0c;你只會看到大量的內存被使用&#xff0c;最后收到didR…

FreeRTOS軟件定時器

軟件定時器允許設置一段時間&#xff0c;當設置的時間達到后就執行指定的功能函數&#xff0c;被軟件定時器調用的功能函數叫做定時器的回調函數。軟件定時器的回調函數是在定時器服務任務中執行的&#xff0c;所以一定不能在回調函數中調用任何阻塞任務的API函數&#xff0c;比…

Java類class isAssignableFrom()方法及示例

類class isAssignableFrom()方法 (Class class isAssignableFrom() method) isAssignableFrom() method is available in java.lang package. isAssignableFrom()方法在java.lang包中可用。 isAssignableFrom() method is used to check whether the class or an interface den…

關于 列表實例

wss3.0工具中有個列表實例項目。此項目的作用是在自定義網站或自定義字段時使用默認值。也就是定義其默認的數據。 格式詳見微軟msdn&#xff1a;http://msdn.microsoft.com/zh-cn/library/ms478860.aspx轉載于:https://www.cnblogs.com/heavencloud/archive/2009/03/20/141793…

WP7之Application Bar控件

Microsoft.Phone.Shell命名空間中定義了ApplicationBar及其相關類&#xff08;ApplicationBarIconButton和ApplicationBarMenuItem&#xff09;&#xff0c;這些類派生自Object,并完全獨立于常規Silverlight編程中的DependencyObject,UIElement和FrameworkElement類層次結構。A…

TomCat使用以及端口號被占用的處理方法

一.HTTP協議 什么是HTTP協議 HTTP協議&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是因特網上應用最為廣泛的一種網絡傳輸協議&#xff0c;所有的WWW文件都必須遵守這個標準。 HTTP請求 HTTP響應 2.如何處理端口被占用 方法一&#xff…