C++與C#對比學習:函數(二)傳回值,預設實參.this指標

來源:互聯網
上載者:User
文章目錄
  • C#中沒有預設實參
函數傳回值

我們定義函數時會指定一個傳回值類型,那在函數體中必須返回一個匹配的類型,或者隱式轉換後能匹配的類型.不過有時存在這樣的情況,如果函數體中存在一些分支語句,有些情況是可以返回一個值,但有時不會傳回值.還是舉個例子吧.

有如下C++函數

int FunArwen(int a , int b)

{

if(a < b)

     return 888;

}

很顯然,上面的函數有時會返回一個值,但有時又不會.

int result = FunArwen(4,5);      //這時結果是888;

 

int res     = FunArwen(5,4);      

//這時函數不會有傳回值,不過我在VS中運行得到res為5,貌似返回了第一個參數的值.不知道為啥是這個值,沒太搞懂.

//不過反正這肯定是個錯誤的結果.

 

在C++中上面的函數編譯時間會有一個警告資訊"not all control paths return a value", 而在C#中上面的函數不能通過編譯的,會報錯,"not all code paths return a value".

你必須寫成 if (a < b) return 888 ;

                   else return 44;

或者if(a < b) return 888;      return 444;

這樣才能編譯通過

 

C#針對C++中的很多地方都做了一些改進,多做了一些檢查.使你寫出來的代碼更不容易出錯.其實一個程式設計語言的發展很多時候關注的一是,簡化一些複雜的文法,使你能用更少的代碼實現更多的功能.另一個是多做一些檢查,要編譯期間就給你檢查出一些錯誤來.當然準確的講有些錯誤也不是真正的錯誤,只要有潛在的犯錯可能就當作錯誤處理了.

我們平時不是常講軟體測試嘛,其實編譯器做的工作也算是測試的一種,給你把代碼中的語法錯誤找出來.如果任何錯誤都能在編譯期間都找出來自然是最完美的,不過編譯器可沒這麼聰明.很多執行階段錯誤它是沒法檢測出來的.

 

C++返回局部函數體中局部變數指標或引用的問題

另外值得注意的是在C++中如果返回結果是函數體中的局部指標或參考型別.則會出錯,因為函數體中的局部變數一超過範圍就會被釋放了.所以指標就變成野指標了.不知道指到哪去了.舉個例子

int*  GetResult( )

{

  int num = 110;

  int* ip = &num;

 return ip;

}

int* p = GetResult();    //這樣做是錯誤的,不過有時錯誤的操作也會得到正確的結果.

//你運行時可能出現執行階段錯誤,可能運行正確得到個錯誤的結果,有時還可能得到正確的結果.反正我在VS中試的時候是得到個正確的結果的.

因為num超出範圍之後就告訴系統那塊記憶體它不要了,系統可以把那記憶體配置給別人用了.不過如果那記憶體暫時還沒被分給誰,那裡面的值還仍然在,所以你通過指標去訪問那個值時可能還能得到個正確的值

 

預設實參

 

假如某個函數的參數有很多個,我們調用時要傳那麼多個參數進去非常麻煩,而且有些參數不那麼重要,我們整個啥預設值就行.你首先想到的可能是來個函數重載,整很多個函數出來,但參數個數都不一樣.顯然這確實是一個辦法.但實現的不夠優美.在C++中有個預設實參的做法能更好的解決這問題.舉例

void Register(string userName = "打醬油的"

,string pwd = "123"

, int age = 18

)

{

//do something

}

這樣我們調用函數時可以像下面那樣

Register();

Register("arwen");

Register("arwen","911");

Register("weiwen","110",24);

上面那樣調用都正確,不過你這樣調用就不行

Register("wei", 24);     //會出錯.因為系統是從左至右去匹配.你傳兩個參數它只會去匹配userName和pwd

 

C#中沒有預設實參

不過有點遺憾的是C# 2.0, 3.0中都沒有提供這個功能.據說c# 4.0有提借這功能.不過我還從沒用過4.0.微軟的東西更新太快,要老想去跟著趕時髦會很累的啊.還是老實的把基礎打好再說

 

 

This 指標

舉個例子,有C++類Arwen

class  Arwen

{

private:

     int age;

     int height;

public:

      void  SetAge(int age)

       {

            this ->age = height;

         }

       void SetHeight(int hgt)

         {

             height = hgt;

}  

}

 

Arwen wen;

int hgt = 111;

wen.SetHeight(hgt);   //我們知道每個類的函數跟static變數一樣是不屬於某個執行個體的,所以的執行個體對象都使用共一個函數.函數是儲存在代碼區.那我們這樣調用函數時,怎麼能找到函數呢?實際上你像上面這樣調用一個函數時編譯器會預設把它 轉換成

Arwen::SetHeight(&wen  , hgt);

然後給height賦值就是這樣 wen.height =  hgt;     //預設情況都是給自成員變數前加個執行個體對象做首碼.&wen也就是this指標了.

但如果成員變數和傳的參數同名了就必須顯式加this指標.

像SetAge中 this->age = age;

 

const函數

我們可以在函數後面加個const,例如void SetAge(int age) const { this->age = age;}

Arwen wen;

int age = 222;

wen.SetAge(age); //此時出錯了.

因為編譯器把上面的調用中的this指標轉化成指向const類型的指標了,所以不用this->age = age;這樣去修飾指標指向的值了.

 

 

C#中的this的用法和原理跟C++差不多.雖然C#中沒有指標的概念,但我猜實際上後台很多實現最終都是通過指標實現的.估計C#的編譯器也是用C++和C開發的吧.連微軟的操作操作都是C++和C開發的.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.