1. 程式人生 > >static關鍵字以及字串常量的理解

static關鍵字以及字串常量的理解

       【注意】存在靜態區的變數主要是全域性變數以及被static關鍵字轉換的自動變數,值得注意的是,常量也是存放在靜態區。我們可以特意分析下程式碼塊內的自動變數被static修飾的情況:經過static修飾的自動變數,只是儲存型別發生了變化,並不影響它的作用域,只能在程式碼內部訪問。另外它在整個程式的執行過程中一直存在,並不會重新初始化

void count_test()
{
   static int count = 0;

   count++;

   printf("count is %d\n", count);
}

如上面這段程式碼,內建一個靜態變數,可以統計函式被呼叫的次數。

      【擴充套件】被static修飾的自動變數的賦值問題:

        根據C99標準:All theexpressions in an initializer for an object that has static storage durationshall be constant expressions or string literals. 因此,對給利用static關鍵字改變儲存屬性的變數賦值時,一定只能是常量表達式或者字串常量。否則會出現“initializer element is not constant”的編譯錯誤。

     ii 暫存器變數          

      關鍵字register可以用於自動變數的宣告,提示這個變數是儲存在暫存器中,而不是記憶體中,對比記憶體,暫存器的變數訪問效果更優。一般來講,可以將使用頻率最高的變數存在於暫存器中。

二、字串常量:

         針對字串常量,主要在於理解,如儲存位置,以及一些高階用法。根據前面的儲存型別可知,字串常量的實質是一個指標常量,也應該是儲存在靜態區的。

char *TEST_pointer_constant()
{
    //stack
    char detailFaultStr[10] = {0}; //locao array is tmp and stored in stack.
  
    sprintf(detailFaultStr, "%s", "asd");
  
    //static data area
    char *detailFaultStr = "abc"; 


    return detailFaultStr;
}

int main(int argc, char **argv)
{
    char *tmp = TEST_pointer_constant();    
    printf("%s.\n", tmp);    
    return 0;
}

       上面這個例子從側面反映了指標所指向的記憶體所儲存的位置不同,而出現不同的結果,第一種情況返回的是一個數組名,其所指向的記憶體時存在棧中,其作用域只存在與整個函式中,而第二種情況則是指向的是靜態區(字串常量),它的作用域是整個程式執行期。另外通過這個例子,可以看出我們通常所理解的不能將函式內的區域性變數作為返回值返回,也不是所有情況下都必須遵守。

         下面這個例子展示了常量表達式作為指標常量的靈活用法:

void TEST_pointer_constant()
{
    printf("%s.\n", "xyz"); //xyz
    printf("%s.\n", "xyz"+1); //yz
    printf("%c.\n", *"xyz"); //x
    printf("%c.\n", "xyz"[1]); //y
    printf("%c.\n", *("xyz"+2)); //z
    putchar("0123456789ABCDEF"[11%16]); //can use to convert hexadecimal  //B
}