Static、const、extern區別

1、Static、const、extern區別函數

 

-------------------------------STATIC--------------------------------this

 

static 全局的,能夠改的,若是在一個類中聲明static,類中其餘地方用到的時候,也是使用的改變量。但不能用類名直接訪問。spa

static 全局變量只能在一個文件中使用,也便是說不可能用extern 使它支持外部引用,而全局變量則能夠經過extern 在外部文件中引用,.net

在真正的開發中,通常要使用的是static 全局變量,爲了防此全局變量名相同時而被別的開發小組用extern引用!設計

.h中3d

 

OC中的全局變量,(生命週期)從定義變量的那一行直到文件結束指針

方法1:使用靜態變量 (不推薦)對象

方法2: 使用單例模式(static A *a = nil;)生命週期

方法3:把全局變量設置到AppDelegate中(實際也是單例)內存

 

對於一個完整的程序,內存中的分佈狀況:
      ==========
      |      代碼區    |

      ------------------

      | 全局數據區  |(靜態存儲區)

      ------------------
      |       堆區       |
      -----------------
      |        棧區      |

      ==========

    通常程序的由alloc產生的動態數據存放在堆區,函數內部的自動變量存放在棧區,全局變量和static變量放在全局數據區

 

static的做用主要有如下3個:
    一、擴展生存期;
    二、限制做用域;

    三、惟一性

 

OC

 局部變量

      做用域: 從定義的那一行開始,直到大括號結束或者遇到break return爲止

      存儲位置: 棧

      

     全局變量:

      做用域:從定義變量的那一行直到文件結束

      存儲位置:靜態區

      

     成員變量:
     做用域:建立對象時候有效,對象銷燬(釋放)結束

      存儲位置:存儲在對象所在的堆內存中

 

例如:

A類.h

// 獲取局部靜態變量staticStr
+ (NSString *)sharedLocalStaticStr;
// 獲取全局靜態變量staticStr2
+ (NSString *)sharedGlobalStaticStr;
// 改變全局靜態變量staticStr2

+ (NSString *)changeStaticStr;

A類.m

#import 「A.h"

static NSString *staticStr2 = @"static的使用:全局字符串staticStr2";

@interface ViewController ()

@end

@implementation ViewController
// 獲取局部靜態變量staticStr
+ (NSString *)sharedLocalStaticStr
{
    // 局部靜態變量,做用域只限制在此函數,出了這個函數就無法修改staticStr
    static NSString *staticStr = nil;
    if (staticStr == nil) {
        staticStr = @"static的使用:全局字符串staticStr";
    }
    return staticStr;
}
// 獲取全局靜態變量staticStr2
+ (NSString *)sharedGlobalStaticStr
{
    return staticStr2;
}
// 改變全局靜態變量staticStr2
+ (NSString *)changeStaticStr

{

    // staticStr無法修改由於它是局部靜態變量;staticStr2k能夠修改由於它是全局靜態變量

    staticStr2 = @"static的使用:全局字符串staticStr2被修改";
    return staticStr2;
}
- (void)viewDidLoad {

    [super viewDidLoad];

}

B類.m引用

// 打印局部靜態變量

NSLog(@"staticStr = %@",[ViewController sharedLocalStaticStr]); staticStr = static的使用:全局字符串staticStr

NSString *staticStr = [ViewController sharedLocalStaticStr];

staticStr = @"static的使用:全局字符串staticStr被修改";

NSLog(@"staticStr = %@",[ViewController sharedLocalStaticStr]); staticStr = static的使用:全局字符串staticStr

NSLog(@"staticStr = %@",staticStr); staticStr = static的使用:全局字符串staticStr被修改

   

// 打印全局靜態變量

NSLog(@"staticStr2 = %@",[ViewController sharedGlobalStaticStr]); staticStr2 = static的使用:全局字符串staticStr2

NSString *staticStr2 = [ViewController sharedGlobalStaticStr];

staticStr2 = @"static的使用:全局字符串staticStr2被修改";

NSLog(@"staticStr2 = %@",[ViewController sharedGlobalStaticStr]); staticStr2 = static的使用:全局字符串staticStr2

NSLog(@"staticStr2 = %@",staticStr2); staticStr2 = static的使用:全局字符串staticStr2被修改

NSLog(@"staticStr2 = %@",[ViewController changeStaticStr]); staticStr2 = static的使用:全局字符串staticStr2被修改

 

STATIC:

1、面向過程設計中的static
    一、[靜態全局變量] //在全局變量前,加上關鍵字static,該變量就被定義成爲一個靜態全局變量。

 

     靜態全局變量有如下特色: 
        1)該變量在全局數據區分配內存; 

        2)未經初始化的靜態全局變量會被程序自動初始化爲0(自動變量的值是隨機的,除非它被顯式初始化); 

        3)靜態全局變量在聲明它的整個文件都是可見的,而在文件以外(extern)是不可見的;修改只能經過本身類中得函數修改(+ (NSString *)changeStaticStr

)  

  定義全局變量就能夠實現變量在文件中的共享,但定義靜態全局變量還有如下好處: 
       1)靜態全局變量不能被其它文件所用; 
       2)其它文件中能夠定義相同名字的變量,不會發生衝突; 

    二、[靜態局部變量] 在局部變量前,加上關鍵字static,該變量就被定義成爲一個靜態局部變量。

    一般,在函數體內定義了一個變量,每當程序運行到該語句時都會給該局部變量分配棧內存。但隨着程序退出函數體,系統就會收回棧內存,局部變量也相應失效。但有時候咱們須要在兩次調用之間對變量的值進行保存。一般的想法是定義一個全局變量來實現。但這樣一來,變量已經再也不屬於函數自己了,再也不僅受函數的控制,給程序的維護帶來不便。
靜態局部變量正好能夠解決這個問題。靜態局部變量保存在全局數據區,而不是保存在棧中,每次的值保持到下一次調用,直到下次賦新值。
    靜態局部變量有如下特色:
      1)該變量在全局數據區分配內存; 
      2)靜態局部變量在程序執行到該對象的聲明處時被首次初始化,即之後的函數調用再也不進行初始化; 
      3)靜態局部變量通常在聲明處初始化,若是沒有顯式初始化,會被程序自動初始化爲0; 
      4)它始終駐留在全局數據區,直到程序運行結束。但其做用域爲局部做用域,當定義它的函數或語句塊結束時,其做      用域隨之結束;

    三、靜態函數
    在函數的返回類型前加上static關鍵字,函數即被定義爲靜態函數。靜態函數與普通函數不一樣,它只能在聲明它的文件當中可見,不能被其它文件使用。
   定義靜態函數的好處: 
      1)靜態函數不能被其它文件所用; 
      2)其它文件中能夠定義相同名字的函數,不會發生衝突;

2、面向對象的static關鍵字(類中的static關鍵字)
一、靜態數據成員
    在類內數據成員的聲明前加上關鍵字static,該數據成員就是類內的靜態數據成員。
   靜態數據成員有如下特色:
      1)而靜態數據成員被看成是類的成員。不管這個類的對象被定義了多少個,靜態數 據成員在程序中也只有一份拷貝,由該類型的全部對象共享訪問。
      2)靜態數據成員存儲在全局數據區,屬於本類的全部對象共享,因此,它不屬於特定的類對象,在沒有產生類對象時其做用域就可見,即在沒有產生類的實例時,咱們就能夠操做它; 
 同全局變量相比,使用靜態數據成員有兩個優點: 
     1)靜態數據成員沒有進入程序的全局名字空間,所以不存在與程序中其它全局名字衝突的可能性;
     2)能夠實現[信息隱藏]。靜態數據成員能夠是private成員,而全局變量不能; 

二、靜態成員函數
    它爲類的所有服務而不是爲某一個類的具體對象服務。與普通函數相比,靜態成員函數因爲不是與任何的 對象相聯繫,所以它不具備this指針。從這個意義上講,它沒法訪問屬於類對象的非靜態數據成員,也沒法訪問非靜態成員函數,它只能調用其他的靜態成員函數。
  關於靜態成員函數,能夠總結爲如下幾點: 
    1)出如今類體外的函數定義不能指定關鍵字static; 
    2)靜態成員之間能夠相互訪問,包括靜態成員函數訪問靜態數據成員和訪問靜態成員函數; 
    3)非靜態成員函數能夠任意地訪問靜態成員函數和靜態數據成員; 
    4)靜態成員函數不能訪問非靜態成員函數和非靜態數據成員

 

--------------------------CONST---------------------------------------
const應用:
1、對於基本聲明

    const int r=100;//標準const變量聲明加初始化,編譯器通過類型檢查後直接用100在編譯時替換。 

#import "ViewController1.h"

const int constNum = 2;

@interface ViewController1 ()

@end

@implementation ViewController1

- (void)viewDidLoad {

    [super viewDidLoad];

    // 整數常量

    NSLog(@"constNum = %d",constNum); constNum = 2

    constNum = 3;(報錯,不讓修改)

}

2、對於指針
    1. int x=10; const int *r=&x; //指針指向的內容是常量,r指向的內容不可以經過r改變,但若是是非const,內容能夠經過本身改變,並且r指針能夠改變,能夠指向其它的整形. 

 

    //*r=*r+1;NO //x++;YES //r=&y;YES

    2. int const *r=&x; 與1徹底相同

 

 

    3. int * const r=&x; //指針指向是常量,不能修改去指向其它內容,但指向的內容能夠修改

     //r=&y;NO //*r=*r+1;YES //x++;YES

    4.const int * const r=&x; //綜合一、3用法,r是一個指向常量的常量型指針,指針指向不能改變,指針內容不能改變,內容能夠自身改變            //r=&y;NO //*r=*r+1;NO //x++;YES

 

extern

假如A類中已經聲明瞭meString,你在另一個B類中想使用這個變量,能夠extern NSString* meString;會獲得a類中一樣的值,且可從新賦值。

// 在A.h中聲明兩個字符串

extern NSString *externStr1; // 定義一個普通的字符串(能夠修改),前面加上extern修飾表示該變量能夠被其餘類導入使用

extern NSString *const externStr2; // 定義一個不可變字符串(不能夠修改)

// 在A.m中初始化兩個字符串
NSString *externStr1 = @"extern的使用:普通字符串externStr1";
NSString *const externStr2 = @"extern的使用:不可變字符串externStr2";

 

// B類中調用

(1)#import 「A.h"

 NSLog(@"externStr1 = %@",externStr1); externStr1 = extern的使用:普通字符串externStr1

 NSLog(@"externStr2 = %@",externStr2); externStr2 = extern的使用:不可變字符串externStr2

(2)不導入#import 「A.h"

extern NSString *externStr1;

extern NSString *const externStr2;

NSLog(@"externStr1 = %@",externStr1); externStr1 = extern的使用:普通字符串externStr1

NSLog(@"externStr2 = %@",externStr2); externStr2 = extern的使用:不可變字符串externStr2

注意:

externStr1 = @"extern的使用:普通字符串externStr1被修改";

NSLog(@"externStr1 = %@",externStr1);externStr1 = extern的使用:普通字符串externStr1被修改

externStr2 = @"extern的使用:不可變字符串externStr2被修改」;(報錯,常量不能修改)

 

 

// 實際開發中

extern NSString * const AFNetworkingReachabilityDidChangeNotification;// 設置成常量能夠被外部調用,可是外部不容許修改

 

 

Code:

相關文章
相關標籤/搜索