網站首頁 編程語言 正文
前言
在講到extern和static的時候先了解一下定義和聲明的基本概念
定義(define):
A variable is defined when the compiler allocates the storage for the variable,就是我們的變量個其存儲的具體值相關聯
聲明(declared)
編譯器聲明這個變量的存在,宣告其類型但是并不關聯某個存儲的具體值
你可以聲明一個變量多次,但是你只能定義其一次并且給一個范圍,我們定義一個變量也是聲明,但不是所有的聲明都是定義
extern
我們在全局聲明/定義一個變量最好的一個方法是在頭文件中用關鍵字extern
聲明一個變量
在我們工程中,一般用一個頭文件聲明全部所需的全局變量(當然用extern
),然后在所有其他的.c文件中include這個頭文件,假設我們有三個文件分別是file3.h
,file1.c
,file2.c
內容分別如下var.h
extern int global_var;
var.c
#include "var.h" #include "prog1.h" //function declarations,我們示例中沒有將函數原型頭文件寫出來 int global_var = 33; int increment(void) { return global_variable++ }
main.c
#include "var.h" #include "prog1.h" #include <stdio.h> //注意我們沒有include file1.c void use_it(void){ printf("global var : %d\n",global_var++); }
然后我們編譯 (記住不編譯頭文件)
gcc main.c var.c -o out.c
為什么我們的main不include var.c就知道global_var的具體值呢?因為我們說過一個全局變量只能定義一次,但是可以聲明多次,global_var分別在main,c和var.c中聲明了,但是只在var.c中定義,換個角度,global_var的生命周期是全局也就是整個軟件的生命周期,整個軟件的生命周期包含三個文件,且global_var不定義在堆棧中,而是聲明在bss中,定義在initialed data區域中
static
static也是全局但是其作用域不是全局而是本文件中,所以其他的文件include一個含有static的頭文件,且試圖定義他會報錯,因為static變量的作用域只在聲明他的頭文件中
還是上述的程序但是我們把extern改為static了var.h
static int global_var;
var.c
#include "var.h" #include "prog1.h" //function declarations,我們示例中沒有將函數原型頭文件寫出來 int global_var = 33; int increment(void) { return global_variable++ }
main.c
#include "var.h" #include "prog1.h" #include <stdio.h> //注意我們沒有include file1.c void use_it(void){ printf("global var : %d\n",global_var++); }
開始編譯發現錯誤
c++ static members in class
簡而言之就是我們的class里面搞一個static的成員,我們知道static的作用域雖然是全局只存在于本文件,那么將一個static放在一個class中間是什么意思呢?
在Cpp的類中使用static就不再和C一樣局限于定義的文件中了,在Cpp的class中用static修飾成員有以下的特點
- 當這個class建立的時候,此class內的static成員在只有一份,無論創建多少個class對象,且每個對象都是共享這個static成員的,換句話說無論多少個對象創建,class的static成員都是第一無二的,且內存中只有一份
- static成員的初始化發生在此class所有對象創建前
- 他的聲明周期是全程序
我們寫一個程序,寫一個class,在其public中搞一個static member,且在class的構造函數中對這個static member + 1,意味著此static成員作用是統計有多少個class對象成員
static_mamber.h
using namespace std; class Box{ public: static int objcount; Box(double l,double b, double h); double volume(); private: double length; double breadth; double height; };
static_member.cpp
#include "static_member.h" #include <iostream> using namespace std; int Box::objcount = 0; //static成員的初始化在創建所有的class對象之前 //構造函數 Box::Box(double l, double b, double h) :length(l),breadth(b),height(h){ cout << "construct is called," << endl; objcount++; } double Box::volume(){ return length * breadth * height; }
main.cpp
#include "static_member.h" #include <iostream> using namespace std; int main(void){ Box Box1(3.3,1.2,1.5); Box Box2(8.5,6.0,2.0); cout << "total Box object is "<< Box::objcount << endl; return 0; }
編譯
g++ static_member.cpp main.cpp -o static_member.o
得到結果
construct is called,
construct is called,
total Box object is 2
注意class是全局的也就是extern的因為在所有block(
{}
)外部的變量或者class或者函數如果不加static都默認是extern
總結
在C語言中extern修飾后的變量或者函數,可以在其他的文件中進行使用(需要include定義extern變量或者函數的頭文件),但是static則不行,static和extern的作用域都是全局但是,static只允許本文件內對其修飾的變量更改,而extern允許在任何文件中更改
在C++中static修飾的是某個class的一個成員,和C中的static完全不一樣,首先C++中如果在頭文件中聲明某個class的某個成員是static,那么我們在其他文件中可以定義他(前提include對于的頭文件),這是在C中是不行的,且C++ static member in clss意思是為此class創建一個獨一無二的成員,不論你的class實例化多少次,static成員就一個,其他的class對象都是其copy,并且我們可以隨時隨地修改這個static成員
原文鏈接:https://blog.csdn.net/qq_37026934/article/details/125448627
相關推薦
- 2023-02-01 Bat腳本-Call,Start,直接調用,goto?四種方式調用批處理_DOS/BAT
- 2023-03-27 Android?Framework原理Binder驅動源碼解析_Android
- 2022-09-04 詳解Go語言中數組,切片和映射的使用_Golang
- 2023-01-07 Python數據類型轉換實現方法_python
- 2022-10-01 Python+OpenCV實現表面缺陷檢測_python
- 2022-08-07 使用pd.merge表連接出現多余行的問題解決_python
- 2022-12-23 C++類成員函數中的名字查找問題_C 語言
- 2022-05-18 C++中string類的常用方法實例總結_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支