C/C++ 靜態變數解析

gaopengtttt發表於2016-06-13


靜態變數:這種變數的記憶體將儲存到整個程式的結束,他的記憶體是獨立存放到一個叫做靜態記憶體區的。
          所有的靜態的變數如果不賦值,會預設賦值為0,不管是結構體還是其他型別的變數,
          當然靜態變數的初始化也分為靜態初始化和動態初始化,如果有一些不可確定的因素會使用
          動態初始化
          比如:
          int a = 1;靜態初始化。
          double a = sqrt(2);動態初始化因為sqrt是一個不確定的因素。
          有幾個概念
          內部全域性:內部是說不能被其他檔案呼叫,全域性是說有限訪問範圍為本檔案。
          外部全域性:外部是說可以被其他檔案呼叫,全域性是說有限訪問範圍為本檔案。
          內部區域性:內部是說不能被其他檔案呼叫,區域性是說有限訪問範圍為本程式碼塊。
舉例3種模式
1、內部區域性靜態變數,如
int test(void)
{
static i = 1;
.....
}
這個靜態變數是區域性的,有效範圍是本程式碼塊。
2、外部全域性靜態變數
int i = 1;
int test(void)
{
   ....
}
這個靜態變數是全域性的,有效範圍是本檔案。
並且它是外部的,所以其他檔案如果想使用可以使用
extern int i;
3、內部全域性靜態變數
static i = 1;
int test(void)
{
   ....
}
這個靜態變數是全域性的,有效範圍是本檔案。
並且它是內部的,不能被其他檔案呼叫,
如果想extern int i;是不行的。
注意extern int i;不能初始化,因為他只是宣告而已,實際的變數在其他檔案進行了空間初始化,也就是說記憶體
已經分配了這裡
extern int i;不會分配任何記憶體空間。
這裡展開說一下關於左值和右值。
任何一個有限的記憶體空間才能作為左值,

int a=1;
int *p;
p = &a;
*p = 1;
是可以作為左值的,如果沒有有效記憶體一定不行
比如

int a;
int b;
a+b = 5;
這裡的a+b 是一段臨時空間不能作為左值

但是關於如果我們抓住一個細節就是這段靜態記憶體區域在整個程式期間都存在,C/C++是很靈活的,
我們就可以定義一個指標來訪問他。
我寫了一段程式。這段程式包含了其他的一些東西,比如flexible array number 來節約記憶體,

點選(此處)摺疊或開啟

  1. t1.h

  2. #include<iostream>
  3. using namespace std;

  4. #ifndef TEST_H__
  5. #define TEST_H__
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <stdio.h>

  9. typedef struct chain
  10. {
  11.          char address[];
  12. } CM;
  13. typedef struct mc
  14. {
  15.         int id;
  16.         char name[20];
  17.         CM* adr;
  18. } CHC;
  19. #define LEN_S strlen(max_address)+sizeof(CM)+3
  20. #define LEN_MAX strlen(max_address)
  21. CM* finps(CHC* ins);
  22. void fshows(const CHC* ins);
  23. int** stre(void);

  24. #endif


  25. t3.cpp


  26. #include<iostream>
  27. #include "t1.h"
  28. using namespace std;

  29. static int st1 = 1;
  30. static int st2 = 2;

  31. int** stre(void)
  32. {
  33.         static int* p[2];
  34.         p[0] = &st1;
  35.         p[1] = &st2;
  36.         return p;
  37. }

  38. CM* finps(CHC* ins)
  39. {
  40.         char max_address[80];
  41.         static CM* ck;

  42.         cout<< "please input id:" <<endl;
  43.         cin >> ins->id;
  44.         cin.get();
  45.         cout<<"please input name:"<<endl;
  46.         cin.getline(ins->name,19);
  47.         cout<<"please input your address"<<endl;
  48.         cin.getline(max_address,79);
  49.         ck = (CM* )malloc(LEN_S);
  50.         ins->adr = ck;
  51.         strcpy(ck->address,max_address);
  52.         return ck;

  53. }

  54. void fshows(const CHC* ins)
  55. {
  56.         cout<<"your information is:"<<endl;
  57.         cout<< ins->id <<endl;
  58.         cout<< ins->name <<endl;
  59.         cout<< ins->adr->address <<endl;
  60. }

  61. t2.cpp
  62. #include<iostream>
  63. #include "t1.h"
  64. using namespace std;

  65. int main(void)
  66. {
  67.         CHC ins;
  68.         CM* dt;
  69.         int** p;
  70.         dt = finps(&ins);
  71.         fshows(&ins);
  72.         free(dt);
  73.         p = stre();
  74.         cout<<"access static values from pointer:"<<endl;
  75.         cout<<**p<<endl;
  76.         cout<<**(p+1)<<endl;
  77. }


注意這裡的

點選(此處)摺疊或開啟

  1. static int st1 = 1;
  2. static int st2 = 2;
  3. int** stre(void)
  4. {
  5.         static int* p[2];
  6.         p[0] = &st1;
  7.         p[1] = &st2;
  8.         return p;
  9. }


實際上我定義了一個指標陣列來儲存st1和st2的地址,並且返回了指向指標的指標p
那麼我們訪問的時候就可以
<endl;

點選(此處)摺疊或開啟

  1. cout<<**p<<endl;
  2. cout<<**(p+1)<<endl;
<endl;
來進行訪問了,這樣一來雖然定義的內部全域性靜態變數但是任然訪問到了。


編譯執行這段程式:
gaopeng@bogon:~/CPLUSPLUS/part9$ g++  t2.cpp t3.cpp
gaopeng@bogon:~/CPLUSPLUS/part9$ ./a.out 
please input id:
1
please input name:
gaopeng
please input your address
chongqing
your information is:
1
gaopeng
chongqing
access static values from pointer:
1
2
</endl;
</endl;

--end---



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2119670/,如需轉載,請註明出處,否則將追究法律責任。

相關文章