C語言中,static關鍵字作用


static修飾變量

1 在塊中使用static修飾變量

  • 它具有靜態存儲持續時間、塊范圍和無鏈接。
    即作用域只能在塊中,無法被塊外的程序調用;變量在程序加載時創建,在程序終止時結束。
  • 它只在編譯時初始化一次。如果沒有顯式初始化,默認初始化為0.
#include <stdio.h>

void trystat(void);

int main(void)
{
   int count;
   for (count = 1; count <= 3; count++)
   {
       printf("Here comes iteration %d:\n", count);
       trystat();
   }
   
   return 0;
}


void trystat(void)
{
   int fade = 1;
   static int stay = 1;
   
   printf("fade = %d and stay = %d\n", fade++, stay++);
}

程序執行結果
Here comes iteration 1:
fade = 1 and stay = 1
Here comes iteration 2:
fade = 1 and stay = 2
Here comes iteration 3:
fade = 1 and stay = 3

(1) 這里變量stay ,它從程序加載時開始存在,直到程序終止。但是它的范圍僅限於trystat()函數塊。只有當這個函數執行時,程序才能使用stay訪問它指定的對象.
(2) 變量stay記得它的值增加了1,但是變量fade每次都會重新開始。這指出了初始化的不同之處:fadetrystat()每次調用都從新初始化,而stay變量只初始化一次。
(3) 靜態變量在程序加載到內存之后就已經就位了。將語句static int stay = 1;放在trystat()函數中告訴編譯器,只允許trystat()函數查看變量;它不是在運行時執行的語句。

2 在任何函數外部使用static修飾變量

  • 它具有靜態存儲時間、文件范圍和內部鏈接。
    即作用域在當前文件之中(只能被同一文件中的函數使用),無法被其他文件調用
  • 它只在編譯時初始化一次。如果沒有顯式初始化,默認初始化為0。

使用static修飾函數

  • 作用域限制在當前定義的文件中使用,從而避免了多文件函數名稱沖突的可能性。通常文件中不作為接口的函數,建議使用static修飾,這樣避免不同文件使用相同的函數名發生沖突。
static BOOL wavTaskCreated = FALSE;
static QueueHandle_t wav_msg_queue = NULL;
static WAV_PLAY_QUEUE_t wavPlayQueue;

static bool wav_get_version_flag = false;
static char wav_version[32];

static uint8_t *Wav_GetFileName(WAV_TYPE_t wav_type)
{

}


static bool Wav_GetFileInfo(WAV_FILE_INFO_t *pFileInfo, uint8_t *pFileName)
{
  
}


static bool Wav_GetVersion_Internal(WAV_FILE_INFO_t *pFileInfo)
{

}


static bool Wav_ReadFile(uint8_t *pData, uint32_t offset, uint32_t size)
{

}


static bool Wav_SendToDA(uint8_t *pFile, uint32_t size,  uint32_t volume)
{
 
}


static BOOL Wav_Put_Queue(WAV_TYPE_t wav_type, BOOL fromISR)
{
 
}


static BOOL Wav_Get_Queue(WAV_TYPE_t *pWavType)
{

}


static bool Wav_Play_Inernal(WAV_TYPE_t wav_type)
{

}


void Wav_Init(void)
{
    DA_Init(16000);

    if (!wavTaskCreated)
    {
        wavTaskCreated = TRUE;
        xTaskCreate(wav_task, "WAV", STACK_SIZE_TASK_WAV, NULL, PRIORITY_TASK_WAV, NULL);
        wav_msg_queue = xQueueCreate(WAV_MSG_QUEUE_LENGTH, sizeof(WAV_MESSAGE_t));

        wavPlayQueue.pWavTypeTable = malloc(WAV_PALY_QUEUE_MAX * sizeof(WAV_TYPE_t));
    }

    wavPlayQueue.front = 0;
    wavPlayQueue.end = 0;
    wavPlayQueue.sizeNow = 0;
    wavPlayQueue.totalSize = WAV_PALY_QUEUE_MAX;
}


bool Wav_Play(WAV_TYPE_t wav_type, bool force)
{
    if (!wavTaskCreated)
    {
        return false;
    }

    if (force)
    {
        vPortEnterCritical();

        watchdog_feed();
        
        Wav_Play_Inernal(wav_type);
        
        vPortExitCritical();

        return true;
    }
    
    bool rv = Wav_Put_Queue(wav_type, false);

    vTaskDelay(30);

    return rv;
        
}

上述為某平台使用DA播放wav的程序片段,

static uint8_t *Wav_GetFileName(WAV_TYPE_t wav_type);
static bool Wav_GetFileInfo(WAV_FILE_INFO_t *pFileInfo, uint8_t *pFileName);
static bool Wav_GetVersion_Internal(WAV_FILE_INFO_t *pFileInfo);
static bool Wav_ReadFile(uint8_t *pData, uint32_t offset, uint32_t size);
static bool Wav_SendToDA(uint8_t *pFile, uint32_t size,  uint32_t volume);
static BOOL Wav_Put_Queue(WAV_TYPE_t wav_type, BOOL fromISR);
static BOOL Wav_Get_Queue(WAV_TYPE_t *pWavType);
static bool Wav_Play_Inernal(WAV_TYPE_t wav_type);

上述函數為內部函數使用static修飾。

void Wav_Init(void);
bool Wav_Play(WAV_TYPE_t wav_type, bool force);

上述兩個函數為模塊接口(初始化DA和播放wav功能)供外部調用,沒有使用static修飾。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM