1. 程式人生 > >const,mutable,volatile意義與用法

const,mutable,volatile意義與用法

const能夠增加程式的健壯型,減少程式出錯.const用法很多意義也不同。


基本的用法:
const int a =200; a的內容不變,a只能是200 ,也就是宣告一個int型別的常量(#define a 200)
int const s =200; //和上面作用一樣

const指標和引用一般用在函式的引數中
int* m = &a; //出錯,常量只能用常指標
int c= 1;

const int*pc = &c;//常指標可指向常量

const int* pa = &a; //指標指向的內容為常量
int const *a = &b; //指標指向的內容為常量*p=3//error
int* const a = &b; //指標為常量,不能更改指標瞭如 a++但可以改值*p=3;

從這可以看出const放在*左側修飾的是指標的內容,const放在*右側修飾的是指標本身.

const引用的用法和指標一樣
int const & a=b; 和指標一樣
const int& a=b; 和指標一樣
但沒有 int& const a=b 的用法因為引用不能做移位運算,但只是出個warning

const int* const a = &b; //綜合應用,一般用來傳遞多維的陣列
類如:char* init[] = {"Paris","in the","Spring"};
void fun(const int* const a){}
fun(init)//保護引數不被修改

int A(int)const; //是常函式,只能用在類中,呼叫它的物件不能改改變成員值
const int A(); //返回的是常量,所以必須這麼呼叫 cosnt int a=A();
int A(const int); //引數不能改值,可用在任意函式
int A(const int*);
....
int height() const;//常函式只能由常函式呼叫
int max(int,int) const;
int Max = max(height(),height());

const int* pHeap = new int;
delete pHeap;
p = NULL;//出錯
我的解決辦法是強制型別轉換
const int* pHeap = new int(1);
delete (int*)pHeap;
pHeap = NULL;

一、const 和引用聯合使用的時候要注意

const int a = 1;
const int& ref1 = a;
const int& ref2 = 1;

ref1 和 ref2 都是正確的,但是他們引用的內容和一般的引用不同
對 const int& ref1 = a; 而言,其實這個 ref1 已經和 a 沒有任何關係了
ref1 實際上是對一個臨時量的引用。同理 const int& ref2 = 1; 也是對
一個臨時量做的引用。當引用臨時量是 C++ 的隱式型別轉換可以起作用。
臨時量的生存期和引用量的生存期相同。

二、強傳const物件可能導致無定義行為

對於優化做的比較好的編譯器,程式碼 const int i = 1;
當後面用到變數 i 的時候,編譯器會優化掉對 i 的存取,而直接使用立即數 1

const int i = 1;

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;

所以,對 const 物件做 const_cast 可能導致無定義行為

  
int height() const;//常函式只能由常函式呼叫
int max(int,int) const;
int Max = max(height(),height());


1.不能將const修飾的任何物件、引用和指標作為賦值表示式的左值。
const int cx=100;
const int & rcx=cx;
const int * pcx=&cx;
cx=200; //error
rcx=200; //error
*pcx=200; //error

2.const型別的物件不能直接被non-const型別的別名所引用。
(1)不能將const型別的物件傳遞給non-const型別的引用。
const int cx=100;
int & rx=cx; //error
(2)不能將const型別的實參傳遞給形參為non-const型別引用的函式。
void f(int a)
{
}
void g(int & ra)
{
}
const int cx=100;
f(cx); //ok
g(cx); //error
(3)不能將const型別的物件作為non-const型別引用的函式返回值。
int & f(const int & rca)
{
return rca; //error
}
int x=100;
f(x);

3.可以使用const類型別名引用non-const物件。此時通過const引用不能修改物件,但物件可以通過non-const引用被修改。
int x=100;
int & rx=x;
const int & rcx=x; //ok
x=200;
rx=200;
rcx=200; //error

4.指標的屬性有兩個:指標的型別和指標本身的常量性。其中,指向const物件與指向non-const物件,是不同的指標型別。
int x=100;
const int * pcx=&x; //[1]
int * px=&x; //[2]
int y=100;
int * const cpy=&y; //[3]
int * py=&y; //[4]
[1][2]兩個指標的型別不同;[3][4]兩個指標的常量性不同。
物件與指向物件的指標的規則類似於物件與引用。即,const型別的物件不能直接被non-const型別的指標所指示(同2);可以使用const型別的指標指向non-const物件(同3)。

5.可以將相同型別(包括常量性)的const指標值賦給non-const指標。
int x=100;
int * px;
const int * pcx=&x;
px=pcx; //error
int * const cpx=&x;
px=cpx; //ok

6.若函式的返回值為內建型別或是指標,則該返回值自動成為const性質。但自定義型別則為non-const性質。
int f() //相當於返回const int
{
return 100;
}
int * g(int & ra) //相當於返回int * const
{
return &ra;
}
class CTest
{
int n;
public:
CTest(int n){this->n=n;}
};
CTest h() //返回的就是CTest
{
return CTest(200);
}

f()=200; //error

int x=100;
int y=200;
int * px=&x;
g(y)=px; //error
*g(y)=x; //ok,從這點可以看出g()返回的不是const int *

CTest t(100);
h()=t; //ok,但卻是完全錯誤的、危險的做法
//所以h()的正確寫法是返回const CTest

const int b=100; b的內容不變,b只能是100
int const b=100; b必須為int型,不能為其他型別?
這2句話的意思應該是一樣的吧 , THINKING IN C++是這樣說的

 const int a=100; a的內容不變,a只能是100(同樣不能型別轉換)。
int const b=100; b必須為int型,不能為其他型別?(同樣在使用中不能修改)。
所以a和b是一樣的,稱為整型常數,在使用中不能被修改,當然都不能轉為其他型別了。
#include <iostream>

using namespace std;

int main()
{
  const int a = 100;
  int const b = 100;

  a = 100; //這四條語句編譯時都會出現“Cannot modify a const object
b = 100; //in function main()”的錯誤提示,也就是說,任何企圖修改   a = 100.0; //a和b(其實是一樣的)的行為都會出現“災難”,在語法上講就  b = 100.0; //是a和b都不能出現在賦值語句的左邊!

  cout<<'/n'<<a<<'/n'<<b<<endl;

  return 0;
}

常函式的呼叫:常量物件只能呼叫常成員函式,非常量物件即可以調常成員函式,也可以調一般成員函式,但當某個函式有const和非const兩個版本時,const物件調const版本,非const物件調非const版本
例:
class A
{
public:
int & GetData(){return data;}
const int & GetData()const {return data;}
private:
int data;
}
A a;
a.GetData();//呼叫int & GetData(){return data;}
//但如果沒有這個函式,也可以呼叫const int & GetData()const
const A const_a;
const_a.GetData();//呼叫const int & GetData()const {return data;}
常函式只能調常函式,也是由於這個原因

一、const 和引用聯合使用的時候要注意

const int a = 1;
const int& ref1 = a;
const int& ref2 = 1;

ref1 和 ref2 都是正確的,但是他們引用的內容和一般的引用不同
對 const int& ref1 = a; 而言,其實這個 ref1 已經和 a 沒有任何關係了
ref1 實際上是對一個臨時量的引用。同理 const int& ref2 = 1; 也是對
一個臨時量做的引用。當引用臨時量是 C++ 的隱式型別轉換可以起作用。
臨時量的生存期和引用量的生存期相同。

二、強傳const物件可能導致無定義行為

對於優化做的比較好的編譯器,程式碼 const int i = 1;
當後面用到變數 i 的時候,編譯器會優化掉對 i 的存取,而直接使用立即數 1

const int i = 1;

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;

所以,對 const 物件做 const_cast 可能導致無定義行為

#include <iostream.h>
void fun(char b){cout <<"void"<<endl;}
int fun(int const b){cout <<"int"<<endl;}
int main()
{
fun(1.0);//詳細看看過載函式吧
fun(4); //想一想呼叫哪一個

return 0;
}
我試了一下,會出錯? vc說:'fun':ambiguous call to overloaded function


const int i = 1;
*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl;
這個可真有意思,除錯時兩個都是2,可編譯就是2,1了
const的永遠都是const,這樣能更改就不錯了,不然就自相矛盾了
奇怪的是 pi 和 &i地址一樣啊,就像樓上說的這是編譯時的優化
處理
const int i = 1;
int* pi=const_cast<int*>(&i);
*pi=2;
cout << *pi << endl;
cout << i << endl;

那個主要是隱式轉換
你可依次把兩個函式注掉看看呼叫
#include <iostream.h>
//void fun(char b){cout <<"void"<<endl;}
void fun(int b){cout <<"int"<<endl;}
int main()
{
fun('a');
fun(4);
return 0;
}

const
一.一般應用
1.const修飾各種變數的用法.
   a.取代define
     #define D_INT 100
     #define D_LONG 100.29
     ………
     const int D_INT = 100;
     const D_INT = 100;     //如果定義的int型別,可省略int.
     const long D_LONG = 100.29;
     ………
     const int& a = 100;
     const替代define雖然增加分配空間,可它卻保證了型別安全.
     在C標準中,const定義的資料相當於全域性的,而C++中視宣告的位置而定.
   b.修飾指標相關的變數
     以三組簡單的定義示意:
     Group1:  
     int a = 0;   
     const int* b = &a;------------  [1]               
     int const *b = &a;------------  [2]                    
     const int* const b = &a;---- [4]  
         
     Group2: 
     const char *p = "const";--------------[1]
     char const *p = "const";--------------[2]  
     char* const p = "const";--------------[3]  
     const char * const p = "const";----[4]     
    
     Group3:
      int a=0;
     const int &b = a;---------------[1]
     int const &b = a;---------------[2] 
     int & const b = a;--------------[3]  //--->修飾引用時,const被忽略
     const int & const b = a;-----[4]
     總結:
     1.如果const位於星號左側,則const用來修飾指標所指向的變數,
       即指標指向的為不可變的.
     2.如果const位於星號右側,const就是修飾指標本身,即指標本身是
       不可變的.
       因此,[1]和[2]的情況相同,指標所指向內容不可變(const放在變數
       宣告符的位置無關), 這種情況下不允許對內容進行更改,如不能*a = 3 ;
     3.[3]中指標本身是不可變的,而指標所指向的內容是可變的,這種情況
       下不能對指標本身進行更改操作,如a++是錯誤的
     4.[4]中指標本身和指向的內容均為常量.(引用特殊:引用在使用增加
       遇義時,增加它代表的變數.所以qualifiers on reference are ignoredv.
       延伸點:
       注意示例:
       1.const int& reference = 1000;
       2.char* p = "const"
         char*& q ;
  
2.const在函式環境下的各種應用
   常用法示例如下:
   const A&  _Fun(const  A& _in);  //修飾引用型傳入引數
   // A  _Fun(const A& _in);
   //A& _Fun(const A& _in);
   //上面的兩種,在函式內部有特殊的步驟,這裡不詳提了…..
 
   const  A*  _Fun( const  A* _in);   //修飾指標型傳入引數
   void _Fun( ) const;   //修飾class成員函式
   const  A&  _Fun(A& _in );  //修飾返回值
   const A & operator(const A& _in);  //同時修飾傳入引數和返回值

   a.修飾引數
     如void _Fun(const A* _in)或 void _Fun(const A& _in);
     它們被修飾後,在函式執行期間行為特性同於上面的講解,
     注意:這不會改變原來資料的是否是const的屬性.

   b.修飾函式返回值
    const A&  _Fun( )
    const A*   _Fun( );
    注意:由於生命期不同步的問題,不可將區域性的變數的指標或引用返回(static除外).
    另外,傳出來的視情況,代表不同的意思…
    對於A&返回型別,你若將之賦與其它變數,那麼它實際執行的是將返回的變數
    (或引用)代表的資料賦出..而你若將其它值賦予之,那麼被賦予的是變數或引
    用代表的資料. 而const A& 一般是防止之做為左值被賦值.

    這個地方還有很多的細節問題(譬如在連續賦值、返回的臨時物件的處理、
    過載的const和非cosnt運算子等等),讀者自己在實踐中需要多多總結.

二、難點
3. 修飾類成員函式的const.
   形如:void _Fun() const { };
   你需要知道的幾點規則:

   a.const物件只能訪問const成員函式,而非const物件可以訪問任意
     的成員函式,包括const成員函式.
   b.const物件的成員是不可修改的,然而const物件通過指標維護的物件卻
     是可以修改的.
   c.const成員函式不可以修改物件的資料,不管物件是否具有const性質.它在
     編譯時,以是否修改成員資料為依據,進行檢查.
   e.然而加上mutable修飾符的資料成員,對於任何情況下通過任何手段
     都可修改,自然此時的const成員函式是可以修改它的…

4.談談volatile和”完全const物件”
  一個有volatile修飾的類只允許訪問其介面的一個子集,這個子集由類的
  實現者來控制.使用者只有用const_cast才可以訪問這個型別的全部介面.而且,
  象const一樣,類的volatile屬性會傳遞給它的成員.想象const修飾的對
  象,它的成員變數是不可修改的,而它通過指標維護的物件或原生變數是可
  修改.那麼我們想:如果物件維護一個char* ,則它相當於char*
  const chrptr ;而不是const char* cosnt chrptr;對於類中的指標你需要
  這樣修飾以防止它或它維護的資源:cosnt x* xptr;而不是x*const xptr;
  因為cosnt 修飾的物件它預設 的行為是延續變數:x* cosnt xptr;

  更重要的,volatile修飾的資料,編譯器不可對其進行執行期寄存於暫存器的優化.
  這種特性,是為了多執行緒同步的需要.有興趣者看參看Andrei的GP系列文章.

5.談談const_cast轉換運算子
  這個關鍵字最基礎的用法是:去掉資料的const性質.
  值得注意的是:它只對指標、引用和其它的具有指向性質的型別.



 
mutable
mutable只能由於修飾類的非靜態資料成員,對於使用使用mutable修飾的成員變數,const成員函式可以改變其值,比如下面的程式碼:
class X{
public:
  void foo() const
  {
     if (!changed_){
       changed_ = true;
     }
     // do something
  }
private:
  mutable bool changed_;
};
如果缺少mutable,那麼就無法編譯通過啦。
mutable具有欺騙性,使用它,可以使const的成員函式悄悄的改變的類的成員函式,而無須使用const_cast來轉換this指標。
 
mutable和const
    宣告:這裡討論的const是用來修飾函式的const,而不是用來修飾變數的const。雖然是同一個關鍵字,但yayv還是覺得把他們當作2個關鍵字來理解更好一些。
    C++中const關鍵字用來表示一個常量,同時const也用來修飾函式。yayv在這個要明確的概念是:const所修飾的函式只能是類的成員函式,因為const所修飾的函式中,要由編譯器負責保護類的成員變數不被修改。而相對的,mutable則是用來修飾類的成員變數,讓該變數在const所修飾的成員函式中可以被修改。而且const修飾的函式只能是類的成員函式,mutable修飾的變數只能是類的成員變數。簡直就是一對冤家對頭~
這裡出現了3個問題:
第一:為什麼要保護類的成員變數不被修改
第二:為什麼用const保護了成員變數,還要再定義一個mutable關鍵字來突破const的封鎖線?
第三:到底有沒有必要使用const 和 mutable這兩個關鍵字?
    yayv對這三個問題的看法是:
    保護類的成員變數不在成員函式中被修改,是為了保證模型的邏輯正確,通過用const關鍵字來避免在函式中錯誤的修改了類物件的狀態。並且在所有使用該成員函式的地方都可以更準確的預測到使用該成員函式的帶來的影響。
    而mutable則是為了能突破const的封鎖線,讓類的一些次要的或者是輔助性的成員變數隨時可以被更改。
    沒有使用const和mutable關鍵字當然沒有錯,const和mutable關鍵字只是給了建模工具更多的設計約束和設計靈活性,而且程式設計師也可以把更多的邏輯檢查問題交給編譯器和建模工具去做,從而減輕程式設計師的負擔(yayv覺得這只不過是把負擔移交給了設計人員~, :(,並沒有降低任何工作量 )。
   如果開發過程有比較嚴格的迭代過程,使用這兩個關鍵字應該更能體現出他們的作用。

volatile
在Andrei Alexandrescu的文章《volatile - Multithreaded Programmer's Best Friend》[2]開頭有如下簡要描述:
The volatile keyword was devised to prevent compiler optimizations that might render code incorrect in the presence of certain asynchronous events. For example, if you declare a primitive variable as volatile, the compiler is not permitted to cache it in a register -- a common optimization that would be disastrous if that variable were shared among multiple threads. So the general rule is, if you have variables of primitive type that must be shared among multiple threads, declare those variables volatile. But you can actually do a lot more with this keyword: you can use it to catch code that is not thread safe, and you can do so at compile time. This article shows how it is done; the solution involves a simple smart pointer that also makes it easy to serialize critical sections of code.
volatile修飾的變數防止被優化,主要用在多執行緒程式中。避免編譯器優化。編譯器進行優化時,它有時會取一些值的時候,直接從暫存器裡進行存取,而不是從記憶體中獲取,這種優化在單執行緒的程式中沒有問題,但到了多執行緒程式中,由於多個執行緒是併發執行的,就有可能一個執行緒把某個公共的變數已經改變了,這時其餘執行緒中暫存器的值已經過時,但這個執行緒本身還不知道,以為沒有改變,仍從暫存器裡獲取,就導致程式執行會出現未定義的行為。
 

volatile變數之記載 volatile的本意是“易變的” 
由於訪問暫存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化。比如:

static int i=0;

int main(void)
{
...
while (1)
{
if (i) dosomething();
}
}

/* Interrupt service routine. */
void ISR_2(void)
{
i=1;
}

程式的本意是希望ISR_2中斷產生時,在main當中呼叫dosomething函式,但是,由於編譯器判斷在main函式裡面沒有修改過i,因此
可能只執行一次對從i到某暫存器的讀操作,然後每次if判斷都只使用這個暫存器裡面的“i副本”,導致dosomething永遠也不會被
呼叫。如果將將變數加上volatile修飾,則編譯器保證對此變數的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。

一般說來,volatile用在如下的幾個地方:

1、中斷服務程式中修改的供其它程式檢測的變數需要加volatile;

2、多工環境下各任務間共享的標誌應該加volatile;

3、儲存器對映的硬體暫存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;


另外,以上這幾種情況經常還要同時考慮資料的完整性(相互關聯的幾個標誌讀了一半被打斷了重寫),在1中可以通過關中斷來實
現,2中可以禁止任務排程,3中則只能依靠硬體的良好設計了。


補充: volatile應該解釋為“直接存取原始記憶體地址”比較合適,“易變的”這種解釋簡直有點誤導人; 

“易變”是因為外在因素引起的,象多執行緒,中斷等,並不是因為用volatile修飾了的變數就是“易變”了,假如沒有外因,即使用volatile定義,它也不會變化;

而用volatile定義之後,其實這個變數就不會因外因而變化了,可以放心使用了;
volatile關鍵字是一種型別修飾符,用它宣告的型別變量表示可以被某些編譯器未知的因素更改,比如:作業系統、硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的程式碼就不再進行優化,從而可以提供對特殊地址的穩定訪問。

使用該關鍵字的例子如下:

  當要求使用volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。

例如:

  volatile 指出 i是隨時可能發生變化的,每次使用它的時候必須從i的地址中讀取,因而編譯器生成的彙編程式碼會重新從i的地址讀取資料放在b中。而優化做法是,由於編譯器發現兩次從i讀資料的程式碼之間的程式碼沒有對i進行過操作,它會自動把上次讀的資料放在b中。而不是重新從i裡面讀。這樣以來,如果i是一個暫存器變數或者表示一個埠資料就容易出錯,所以說volatile可以保證對特殊地址的穩定訪問。

關鍵字volatile有什麼含意 並給出三個不同的例子。
一個定義為volatile的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。下面是volatile變數的幾個例子:
    1). 並行裝置的硬體暫存器(如:狀態暫存器)
    2). 一箇中斷服務子程式中會訪問到的非自動變數(Non-automatic variables)
    3). 多執行緒應用中被幾個任務共享的變數
    回答不出這個問題的人是不會被僱傭的。我認為這是區分C程式設計師和嵌入式系統程式設計師的最基本的問題。嵌入式系統程式設計師經常同硬體、中斷、RTOS等等打交道,所用這些都要求volatile變數。不懂得volatile內容將會帶來災難。
    假設被面試者正確地回答了這是問題(嗯,懷疑這否會是這樣),我將稍微深究一下,看一下這傢伙是不是直正懂得volatile完全的重要性。
    1). 一個引數既可以是const還可以是volatile嗎?解釋為什麼。
    2). 一個指標可以是volatile 嗎?解釋為什麼。
    3). 下面的函式有什麼錯誤:
         int square(volatile int *ptr)
         {
              return *ptr * *ptr;
         }
    下面是答案:
    1). 是的。一個例子是隻讀的狀態暫存器。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。
    2). 是的。儘管這並不很常見。一個例子是當一箇中服務子程式修該一個指向一個buffer的指標時。
    3). 這段程式碼的有個惡作劇。這段程式碼的目的是用來返指標*ptr指向值的平方,但是,由於*ptr指向一個volatile型引數,編譯器將產生類似下面的程式碼:
    int square(volatile int *ptr)
    {
         int a,b;
         a = *ptr;
         b = *ptr;
         return a * b;
     }
    由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段程式碼可能返不是你所期望的平方值!正確的程式碼如下:
     long square(volatile int *ptr)
     {
            int a;
            a = *ptr;
            return a * a;
     }

相關推薦

constmutablevolatile意義用法

const能夠增加程式的健壯型,減少程式出錯.const用法很多意義也不同。 基本的用法:const int a =200; a的內容不變,a只能是200 ,也就是宣告一個int型別的常量(#define a 200)int const s =200; //和上面作用一樣

duilib各種佈局的作用相對佈局絕對佈局的的意義用法

轉載請說明原出處,謝謝~~       我使用duilib快3個月了,總體感覺duilib的使用還是較為簡單的,只是剛入門時可能有些摸不清頭腦。今天寫一篇關於duilib的入門日誌,大致說一下duilib中的各個佈局的作用,以及很關鍵的相對佈局與絕對佈局的意義與用法。希望可以

Android簽名的意義用法

一:簽名的意義:         開發Android的人這麼多,完全有可能大家都把類名,包名起成了一個同樣的名字,這時候如何區分?簽名這時候就是起區分作用的。        由於開發商可能通過使用相同的Package Name來混淆替換已經安裝的程式,簽名可以保證相當名字,

constvolatilestatictypdef幾個關鍵字辨析和理解

iostream 很好 都是 種類 狀態 優點 ror 識別 出錯 1、const類型修飾符 const它限定一個變量初始化後就不允許被改變的修飾符。使用const在一定程度上可以提高程序的安全性和可靠性。它即有預編譯命令的優點也有預編譯沒有的優點。const修飾的變量被

淺談JS中的!=、== 、!==、===的用法和區別 JS中NullUndefined的區別 讀取XML文件 獲取路徑的方式 C#中CookieSessionApplication的用法區別? c#反射 抽象工廠

main 收集 data- 時間設置 oba ase pdo 簡單工廠模式 1.0 var num = 1; var str = ‘1‘; var test = 1; test == num //true 相同類型 相同值 te

java中異常(Exception)的定義意義用法。舉例

use 詳情 put 視頻下載 ati itl url index ring 1.異常(Exception)的定義,意義和用法 (視頻下載) (全部書籍) 我們先給出一個例子,看看異常有什麽用? 例:1.1-本章源碼 public class Test { publi

conststaticvolatile關鍵字的作用

const關鍵字:   1.欲阻止一個變數被改變,可使用const,在定義該const變數時,需先初始化,以後就沒有機會改變他了;   2.對指標而言,可以指定指標本身為const,也可以指定指標所指的資料為const,或二者同時指定為const;   3.在一個函式宣告中,const可以修飾

C#兩種常量型別readonly(執行時常量)const(編譯時常量)

C#中有兩種常量型別,分別為readonly(執行時常量)與const(編譯時常量),本文將就這兩種型別的不同特性進行比較並說明各自的適用場景。 工作原理 readonly為執行時常量,程式執行時進行賦值,賦值完成後便無法更改,因此也有人稱其為只讀變數

多執行緒中sleep() wait() yield() join(), interrupt(),stop()suspend()setPriority()用法區別

網上卻是有很多的關於這個的答案,但是都長得一樣,為了寫這篇部落格,自己找了幾個例子。 JoinThread: package com.com.aaa.threadJoinDemo; public class JoinThread extends Thread{ publ

做有意義的事情發揮自己的光

1. 發現問題,解決問題 觀察、蒐集、聽取、歸納、總結,對問題形成一個整體性的輪廓,然後對問題進行分析和思考,最終洞悉問題的本質, 對症下藥,要保證行動和訴求具有一致性。 辯證看待問題,具體問題具體分析,在關鍵問題或情況下,多問為什麼。 讓思維像樹枝一樣伸展,像水一樣浸潤,滲透到問題的深處,抓住問題本身。 一

Java中thisstaticfinalconst用法

  static表示“全域性”或者“靜態”的意思,用來修飾成員變數和成員方法,也可以形成靜態static程式碼塊,但是Java語言中沒有全域性變數的概念。      被static修飾的成員變數和成員方法獨立於該類的任何物件。也就是說,它不依賴類特定的例項,被類的所有例項共享。      只要這個類被載入,

關於volatile關鍵字的用法從彙編透視C語法操作

看一個簡單的c程式,p是沒加關鍵字volatile的int型指標,r是加關鍵字volatile的int型指標。 //main.c #include <stdio.h> void main(void) {int n;int *p;volatile int *r;

List介面Set介面及其子類的詳細用法。Collection介面簡介。ArraListLinkedListVector

(一)連結串列的特點:(1)這種節點關係的處理操作,核心需要一個Node類(儲存資料,設定引用)(2)在進行連結串列資料的查詢,刪除的時候需要equals()方法的支援。在實際的開發中對於這些資料的使用都有一些共性的特點:儲存進去而後取。             (二)Jav

C++系列——const引用指標用法小結

1. const 將變數設定為只讀,任何對其進行的寫操作(如賦值),都會導致編譯錯誤。 2. 引用 引用(複合型別)就是物件的另外一個名字。 關於定義引用幾點要求: a. 定義引用的時候,必須初始化(指定引用指向物件的唯一方法)。非法情況:int &ref;

extern 用法全局變量頭文件(重復定義)

.exe 類型 archive 展開 我想 很大的 不用 color 編程思想 轉自 https://www.cnblogs.com/chengmin/archive/2011/09/26/2192008.html 當你要引用一個全局變量的時候,你就要聲明,extern i

jni中arm64-v8aarmeabi-v7a,armeabi文件夾的意義用法

結果 strong The 主流手機 lin div %20 tco 高通 兼容和文件讀取順序 arm64-v8a是可以向下兼容的,其下有armeabi-v7a,armeabi armeabi-v7a向下兼容armeabi 兼容得不夠智能: 對於一個cpu是arm64-v8

R語言函式的含義用法實現過程解讀

R的源起 R是S語言的一種實現。S語言是由 AT&T貝爾實驗室開發的一種用來進行資料探索、統計分析、作圖的解釋型語言。最初S語言的實現版本主要是S-PLUS。S-PLUS是一個商業 軟體,它基於S語言,並由MathSoft公司的統計科學部進一步完善。後來Auckland大學的Robert Gentle

display:inline-blockblockinline的區別用法

margin 觸發 style tle 設置 str utf lin 示例 一、首先要了解什麽是塊級元素與行級元素 塊級元素 會占領頁面的一行,其後多個block元素自動換行、 可以設置width,height,設置了width後同樣也占領一行、同樣也可以設置 marg

C#中CookieSessionApplication的用法區別?

1.Application 儲存在服務端,沒有時間限制,伺服器關閉即銷燬(前提是自己沒寫銷燬方法)  2.Session 儲存在服務端,客戶端(瀏覽器)關閉即銷燬(若長時間不使用 且 瀏覽器未關閉的情況下, 預設自動銷燬時間為20分鐘) 3.Cookie 儲存在客戶端,由使

RPC框架的意義用法什麼是RPC

關於RPC框架,首先我們要了解什麼叫RPC,為什麼要用RPC。 RPC是隻遠端過程呼叫,也就是說兩臺伺服器A,B, 一個應用部署在A伺服器上,另一個應用部署在B伺服器上,A伺服器上的應用想要呼叫B伺服器上的應用提供的方法/函式,由於不在一個記憶體空間,不能直接呼叫,需要通過