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++類的靜態成員變數初始化C++變數
- C++ 靜態變數什麼時候完成初始化C++變數
- TscanCode C/C++靜態分析C++
- C++靜態函式C++函式
- 靜態變數變數
- C語言--靜態區域性變數C語言變數
- c++類的靜態成員C++
- C++ 靜態資料成員C++
- C++:類的靜態成員C++
- c++中的靜態成員C++
- C++ 類方法解析:內外定義、引數、訪問控制與靜態方法詳解C++
- C++ 接受狀態變數的lambda表示式C++變數
- C++ 的靜態成員變數為什麼一定要在類外定義C++變數
- C++除法運算 // 靜態斷言C++
- C++教程-----C++變數型別和變數的定義C++變數型別
- 區域性變數和全域性變數(靜態和非靜態)區別變數
- Java靜態變數在靜態方法內部無法改變值Java變數
- C++的動態繫結和靜態繫結C++
- C++學習筆記(三):類與物件--靜態成員變數與常成員函式C++筆記物件變數函式
- c++中的變數型別_C ++中的變數C++變數型別
- C++從靜態型別到單例模式C++型別單例模式
- c++基礎三(變數)C++變數
- c++可變模板引數C++
- c++向量變數動作.C++變數
- C:static 關鍵字、靜態變數、跨類訪問資料變數
- Spring如何為靜態變數注入值Spring變數
- 對於systemverilog靜態變數和動態變數 ,描述不正確的是()。變數
- c++ web框架實現之靜態反射實現C++Web框架反射
- C++ 變數型別查詢C++變數型別
- c++基本型別和變數C++型別變數
- 變數C++邏輯程式碼變數C++
- C++逆向 可變引數HookC++Hook
- C++中的條件變數C++變數
- c++ 動態規劃(數塔)C++動態規劃
- C++入門教程(20):變數、不變數和常量C++變數
- Java逆向基礎之靜態變數存取Java變數
- Java自學入門之靜態變數Java變數
- C++類中的常成員和靜態成員C++