C/C++ 靜態變數解析
靜態變數:這種變數的記憶體將儲存到整個程式的結束,他的記憶體是獨立存放到一個叫做靜態記憶體區的。
所有的靜態的變數如果不賦值,會預設賦值為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 來節約記憶體,
點選(此處)摺疊或開啟
-
t1.h
-
-
#include<iostream>
-
using namespace std;
-
-
#ifndef TEST_H__
-
#define TEST_H__
-
#include <stdlib.h>
-
#include <string.h>
-
#include <stdio.h>
-
-
typedef struct chain
-
{
-
char address[];
-
} CM;
-
typedef struct mc
-
{
-
int id;
-
char name[20];
-
CM* adr;
-
} CHC;
-
#define LEN_S strlen(max_address)+sizeof(CM)+3
-
#define LEN_MAX strlen(max_address)
-
CM* finps(CHC* ins);
-
void fshows(const CHC* ins);
-
int** stre(void);
-
-
#endif
-
-
-
t3.cpp
-
-
-
#include<iostream>
-
#include "t1.h"
-
using namespace std;
-
-
static int st1 = 1;
-
static int st2 = 2;
-
-
int** stre(void)
-
{
-
static int* p[2];
-
p[0] = &st1;
-
p[1] = &st2;
-
return p;
-
}
-
-
CM* finps(CHC* ins)
-
{
-
char max_address[80];
-
static CM* ck;
-
-
cout<< "please input id:" <<endl;
-
cin >> ins->id;
-
cin.get();
-
cout<<"please input name:"<<endl;
-
cin.getline(ins->name,19);
-
cout<<"please input your address"<<endl;
-
cin.getline(max_address,79);
-
ck = (CM* )malloc(LEN_S);
-
ins->adr = ck;
-
strcpy(ck->address,max_address);
-
return ck;
-
-
}
-
-
void fshows(const CHC* ins)
-
{
-
cout<<"your information is:"<<endl;
-
cout<< ins->id <<endl;
-
cout<< ins->name <<endl;
-
cout<< ins->adr->address <<endl;
-
}
-
-
t2.cpp
-
#include<iostream>
-
#include "t1.h"
-
using namespace std;
-
-
int main(void)
-
{
-
CHC ins;
-
CM* dt;
-
int** p;
-
dt = finps(&ins);
-
fshows(&ins);
-
free(dt);
-
p = stre();
-
cout<<"access static values from pointer:"<<endl;
-
cout<<**p<<endl;
-
cout<<**(p+1)<<endl;
- }
點選(此處)摺疊或開啟
-
static int st1 = 1;
-
static int st2 = 2;
-
int** stre(void)
-
{
-
static int* p[2];
-
p[0] = &st1;
-
p[1] = &st2;
-
return p;
- }
實際上我定義了一個指標陣列來儲存st1和st2的地址,並且返回了指向指標的指標p
那麼我們訪問的時候就可以
<endl;
點選(此處)摺疊或開啟
- cout<<**p<<endl;
- cout<<**(p+1)<<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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【C++】靜態持續變數?如何建立靜態持續變數?C++變數
- C++ static variable(靜態變數) 學習C++變數
- C++類的靜態成員變數初始化C++變數
- 靜態變數和非靜態變數變數
- C++ 靜態變數什麼時候完成初始化C++變數
- JNI/NDK開發指南(7):C/C++訪問Java例項變數和靜態變數C++Java變數
- C語言區域性變數、全域性變數、靜態區域性變數、靜態全域性變數C語言變數
- 靜態變數變數
- 靜態變數與靜態方法變數
- C++ 靜態變數單例模式的誤會(執行緒安全)C++變數單例模式執行緒
- C#靜態建構函式及靜態變數學習C#函式變數
- C++靜態函式C++函式
- C語言--靜態區域性變數C語言變數
- 關於C/C++ const變數 const指標 以及C++ 引用變數的解析C++變數指標
- C++在寫靜態變數時容易犯的一個小錯誤C++變數
- TscanCode C/C++靜態分析C++
- C++類靜態成員C++
- 靜態持續變數變數
- 靜態變數和Session變數Session
- c++類的靜態成員C++
- c++中的靜態成員C++
- C++ 靜態資料成員C++
- C++:類的靜態成員C++
- C++ 類的靜態成員C++
- 區域性變數和全域性變數(靜態和非靜態)區別變數
- C++ 接受狀態變數的lambda表示式C++變數
- C++ 類方法解析:內外定義、引數、訪問控制與靜態方法詳解C++
- static靜態變數的理解變數
- js中的靜態變數JS變數
- 靜態全域性變數和全域性變數變數
- 靜態變數和例項變數區別?變數
- C++ 的靜態成員變數為什麼一定要在類外定義C++變數
- Java靜態變數在靜態方法內部無法改變值Java變數
- C++教程-----C++變數型別和變數的定義C++變數型別
- C++ — 靜態繫結與動態繫結C++
- PHP類的靜態(static)方法和靜態(static)變數PHP變數
- C++除法運算 // 靜態斷言C++
- 全域性變數和靜態變數的區別變數