C#進階系列——WebApi 介面引數不再困惑:傳參詳解
前言:還記得剛使用WebApi那會兒,被它的傳參機制折騰了好久,查閱了半天資料。如今,使用WebApi也有段時間了,今天就記錄下API介面傳參的一些方式方法,算是一個筆記,也希望能幫初學者少走彎路。本篇針對初初使用WebApi的同學們,比較基礎,有興趣的且看看。
WebApi系列文章
本篇打算通過get、post、put、delete四種請求方式分別談談基礎型別(包括int/string/datetime等)、實體、陣列等型別的引數如何傳遞。
一、get請求
對於取資料,我們使用最多的應該就是get請求了吧。下面通過幾個示例看看我們的get請求引數傳遞。
1、基礎型別引數
[HttpGet]public string GetAllChargingData(int id, string name) { return "ChargingData" + id; }
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetAllChargingData", data: { id: 1, name: "Jim", bir: "1988-09-11"}, success: function (data, status) {if (status == "success") { $("#div_test").html(data); } } });
引數截圖效果
這是get請求最基礎的引數傳遞方式,沒什麼特別好說的。
2、實體作為引數
如果我們在get請求時想將實體物件做引數直接傳遞到後臺,是否可行呢?我們來看看。
public class TB_CHARGING { /// <summary> /// 主鍵Id /// </summary>public string ID { get; set; } /// <summary> /// 充電裝置名稱 /// </summary> public string NAME { get; set; } /// <summary> /// 充電裝置描述 /// </summary> public string DES { get; set; } /// <summary> /// 建立時間 /// </summary> public DateTime CREATETIME { get; set; } }
[HttpGet] public string GetByModel(TB_CHARGING oData) { return "ChargingData" + oData.ID; }
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetByModel", contentType: "application/json", data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } });
測試結果
由上圖可知,在get請求時,我們直接將json物件當做實體傳遞後臺,後臺是接收不到的。這是為什麼呢?我們來看看對應的http請求
原來,get請求的時候,預設是將引數全部放到了url裡面直接以string的形式傳遞的,後臺自然接不到了。
原因分析:還記得有面試題問過get和post請求的區別嗎?其中有一個區別就是get請求的資料會附在URL之後(就是把資料放置在HTTP協議頭中),而post請求則是放在http協議包的包體中。
根據園友們的提議,Get請求的時候可以在引數裡面加上[FromUri]即可直接得到物件。還是貼上程式碼:
var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }; $.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetAllChargingData", data: postdata, success: function (data, status) { } });
[HttpGet] public string GetAllChargingData([FromUri]TB_CHARGING obj) { return "ChargingData" + obj.ID; }
得到結果:
如果你不想使用[FromUri]這些在引數裡面加特性的這種“怪異”寫法,也可以採用先序列化,再在後臺反序列的方式。
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetByModel", contentType: "application/json", data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } });
[HttpGet] public string GetByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; }
這樣在後臺得到我們序列化過的物件,再通過反序列化就能得到物件。
在url裡面我們可以看到它自動給物件加了一個編碼:
3、陣列作為引數
一般get請求不建議將陣列作為引數,因為我們知道get請求傳遞引數的大小是有限制的,最大1024位元組,數組裡面內容較多時,將其作為引數傳遞可能會發生引數超限丟失的情況。
4、“怪異”的get請求
為什麼會說get請求“怪異”呢?我們先來看看下面的兩種寫法對比。
(1)WebApi的方法名稱以get開頭
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetByModel", contentType: "application/json", data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } });
[HttpGet] public string GetByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; }
這是標準寫法,後臺加[HttpGet],引數正常得到:
為了對比,我將[HttpGet]去掉,然後再呼叫
//[HttpGet] public string GetByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; }
貌似沒有任何問題!有人就想,那是否所有的get請求都可以省略掉[HttpGet]這個標註呢。我們試試便知。
(2)WebApi的方法名稱不以get開頭
我們把之前的方法名由GetByModel改成FindByModel,這個再正常不過了,很多人查詢就不想用Get開頭,還有直接用Query開頭的。這個有什麼關係嗎?有沒有關係,我們以事實說話。
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/FindByModel", contentType: "application/json", data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } });
[HttpGet] public string FindByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; }
貌似又可行,沒有任何問題啊。根據上面的推論,我們去掉[HttpGet]也是可行的,好,我們註釋掉[HttpGet],執行起來試試。
結果是不進斷點,有些人不信,我們在瀏覽器裡面看看http請求:
呵呵,這就奇怪了,就改了個方法名,至於這樣麼?還真至於!
博主的理解是:方法名以Get開頭,WebApi會自動預設這個請求就是get請求,而如果你以其他名稱開頭而又不標註方法的請求方式,那麼這個時候伺服器雖然找到了這個方法,但是由於請求方式不確定,所以直接返回給你405——方法不被允許的錯誤。
最後結論:所有的WebApi方法最好是加上請求的方式([HttpGet]/[HttpPost]/[HttpPut]/[HttpDelete]),不要偷懶,這樣既能防止類似的錯誤,也有利於方法的維護,別人一看就知道這個方法是什麼請求。
這也就是為什麼很多人在園子裡面問道為什麼方法名不加[HttpGet]就呼叫不到的原因!
二、post請求
在WebApi的RESETful風格里面,API服務的增刪改查,分別對應著http的post/delete/put/get請求。我們下面就來說說post請求引數的傳遞方式。
1、基礎型別引數
post請求的基礎型別的引數和get請求有點不一樣,我們知道get請求的引數是通過url來傳遞的,而post請求則是通過http的請求體中傳過來的,WebApi的post請求也需要從http的請求體裡面去取引數。
(1)錯誤的寫法
$.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", data: { NAME: "Jim" }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } });
[HttpPost] public bool SaveData(string NAME) { return true; }
這是一種看上去非常正確的寫法,可是實際情況是:
(2)正確的用法
$.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", data: { "": "Jim" }, success: function (data, status) {} });
[HttpPost] public bool SaveData([FromBody]string NAME) { return true; }
這是一種另許多人頭痛的寫法,但是沒辦法,這樣確實能得到我們的結果:
我們一般的通過url取引數的機制是鍵值對,即某一個key等於某一個value,而這裡的FromBody和我們一般通過url取引數的機制則不同,它的機制是=value,沒有key的概念,並且如果你寫了key(比如你的ajax引數寫的{NAME:"Jim"}),後臺反而得到的NAME等於null。不信你可以試試。
上面講的都是傳遞一個基礎型別引數的情況,那麼如果我們需要傳遞多個基礎型別呢?按照上面的推論,是否可以([FromBody]string NAME, [FromBody]string DES)這樣寫呢。試試便知。
(1)錯誤寫法
$.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", data: { "": "Jim","":"備註" }, success: function (data, status) {} });
[HttpPost] public bool SaveData([FromBody]string NAME, [FromBody] string DES) { return true; }
得到結果
這說明我們沒辦法通過多個[FromBody]裡面取值,此法失敗。
(2)正確用法
既然上面的辦法行不通,那我們如何傳遞多個基礎型別的資料呢?很多的解決辦法是新建一個類去包含傳遞的引數,博主覺得這樣不夠靈活,因為如果我們前後臺每次傳遞多個引數的post請求都去新建一個類的話,我們系統到時候會有多少個這種引數類?維護起來那是相當的麻煩的一件事!所以博主覺得使用dynamic是一個很不錯的選擇。我們來試試。
$.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", contentType: 'application/json', data: JSON.stringify({ NAME: "Jim",DES:"備註" }), success: function (data, status) {} });
[HttpPost] public object SaveData(dynamic obj) { var strName = Convert.ToString(obj.NAME); return strName; }
通過dynamic動態型別能順利得到多個引數,省掉了[FromBody]這個累贅,並且ajax引數的傳遞不用使用"無厘頭"的{"":"value"}這種寫法,有沒有一種小清新的感覺~~有一點需要注意的是這裡在ajax的請求裡面需要加上引數型別為Json,即 contentType: 'application/json', 這個屬性。
(3)推薦用法
通過上文post請求基礎型別引數的傳遞,我們瞭解到了dynamic的方便之處,為了避免[FromBody]這個累贅和{"":"value"}這種"無厘頭"的寫法。博主推薦所有基礎型別使用dynamic來傳遞,方便解決了基礎型別一個或多個引數的傳遞,示例如上文。如果園友們有更好的辦法,歡迎討論。
2、實體作為引數
(1)單個實體作為引數
上面我們通過dynamic型別解決了post請求基礎型別資料的傳遞問題,那麼當我們需要傳遞一個實體作為引數該怎麼解決呢?我們來看下面的程式碼便知:
$.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }, success: function (data, status) {} });
[HttpPost] public bool SaveData(TB_CHARGING oData) { return true; }
得到結果
原理解釋:使用實體作為引數的時候,前端直接傳遞普通json,後臺直接使用對應的型別去接收即可,不用FromBody。但是這裡需要注意的一點就是,這裡不能指定contentType為appplication/json,否則,引數無法傳遞到後臺。我們來看看它預設的contentType是什麼:
為了弄清楚原因,博主查了下http的Content-Type的型別。看到如下說明:
- application/x-www-form-urlencoded : <form encType=””>中預設的encType,form表單資料被編碼為key/value格式傳送到伺服器(表單預設的提交資料的格式);
- application/json : JSON資料格式
也就是說post請求預設是將表單裡面的資料的key/value形式傳送到服務,而我們的伺服器只需要有對應的key/value屬性值的物件就可以接收到。而如果使用application/json,則表示將前端的資料以序列化過的json傳遞到後端,後端要把它變成實體物件,還需要一個反序列化的過程。按照這個邏輯,那我們如果指定contentType為application/json,然後傳遞序列化過的物件應該也是可以的啊。博主好奇心重,還是打算一試到底,於是就有了下面的程式碼:
var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }; $.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", contentType: 'application/json', data: JSON.stringify(postdata), success: function (data, status) {} });
[HttpPost] public bool SaveData(TB_CHARGING lstCharging) { return true; }
得到結果:
嘗試成功,也就是說,兩種寫法都是可行的。如果你指定了contentType為application/json,則必須要傳遞序列化過的物件;如果使用post請求的預設引數型別,則前端直接傳遞json型別的物件即可。
(2)實體和基礎型別一起作為引數傳遞
有些時候,我們需要將基礎型別和實體一起傳遞到後臺,這個時候,我們神奇的dynamic又派上用場了。
var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }; $.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", contentType: 'application/json', data: JSON.stringify({ NAME:"Lilei", Charging:postdata }), success: function (data, status) {} });
[HttpPost] public object SaveData(dynamic obj) { var strName = Convert.ToString(obj.NAME); var oCharging = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(Convert.ToString(obj.Charging)); return strName; }
得到結果:
原理也不用多說,同上。
3、陣列作為引數
(1)基礎型別陣列
var arr = ["1", "2", "3", "4"]; $.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", contentType: 'application/json', data: JSON.stringify(arr), success: function (data, status) { } });
[HttpPost] public bool SaveData(string[] ids) { return true; }
得到結果:
(2)實體集合
var arr = [ { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }, { ID: "2", NAME: "Lilei", CREATETIME: "1990-12-11" }, { ID: "3", NAME: "Lucy", CREATETIME: "1986-01-10" } ]; $.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", contentType: 'application/json', data: JSON.stringify(arr), success: function (data, status) {} });
[HttpPost] public bool SaveData(List<TB_CHARGING> lstCharging) { return true; }
得到結果:
4、後臺傳送請求引數的傳遞
上面寫了那麼多,都是通過前端的ajax請求去做的,我們知道,如果呼叫方不是web專案,比如Android客戶端,可能需要從後臺傳送http請求來呼叫我們的介面方法,如果我們通過後臺去傳送請求是否也是可行的呢?我們以實體物件作為引數來傳遞寫寫程式碼試一把。
public void TestReques() { //請求路徑 string url = "http://localhost:27221/api/Charging/SaveData"; //定義request並設定request的路徑 WebRequest request = WebRequest.Create(url); request.Method = "post"; //初始化request引數 string postData = "{ ID: \"1\", NAME: \"Jim\", CREATETIME: \"1988-09-11\" }"; //設定引數的編碼格式,解決中文亂碼 byte[] byteArray = Encoding.UTF8.GetBytes(postData); //設定request的MIME型別及內容長度 request.ContentType = "application/json"; request.ContentLength = byteArray.Length; //開啟request字元流 Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); //定義response為前面的request響應 WebResponse response = request.GetResponse(); //獲取相應的狀態程式碼 Console.WriteLine(((HttpWebResponse)response).StatusDescription); //定義response字元流 dataStream = response.GetResponseStream(); StreamReader reader = new StreamReader(dataStream); string responseFromServer = reader.ReadToEnd();//讀取所有 Console.WriteLine(responseFromServer); }
當代碼執行到request.GetResponse()這一句的時候,API裡面進入斷點
嘗試成功。
三、put請求
WebApi裡面put請求一般用於物件的更新。它和用法和post請求基本相同。同樣支援[FromBody],同樣可以使用dynamic。
1、基礎型別引數
$.ajax({ type: "put", url: "http://localhost:27221/api/Charging/Update", contentType: 'application/json', data: JSON.stringify({ ID: "1" }), success: function (data, status) {} });
[HttpPut] public bool Update(dynamic obj ) { return true; }
2、實體作為引數
和post請求相同。
3、陣列作為引數
和post請求相同。
四、delete請求
顧名思義,delete請求肯定是用於刪除操作的。引數傳遞機制和post也是基本相同。下面簡單給出一個例子,其他情況參考post請求。
var arr = [ { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }, { ID: "2", NAME: "Lilei", CREATETIME: "1990-12-11" }, { ID: "3", NAME: "Lucy", CREATETIME: "1986-01-10" } ]; $.ajax({ type: "delete", url: "http://localhost:27221/api/Charging/OptDelete", contentType: 'application/json', data: JSON.stringify(arr), success: function (data, status) {} });
[HttpDelete] public bool OptDelete(List<TB_CHARGING> lstChargin) { return true; }
五、總結
以上比較詳細的總結了WebApi各種請求的各種引數傳遞。每種情況都是博主實際程式碼測試過的,內容不難,但如果剛接觸這麼些東西還是需要一點時間去熟悉的,在此做個總結,希望能幫到剛剛接觸WebApi的園友們。如果本文能幫到你,不妨推薦下,您的推薦是博主繼續總結的動力!
最近打算做點自己的東西出來,將部落格裡面的一些好的技術融合進去。有專案合作的小夥伴趕快聯絡博主吧!
歡迎各位轉載,但是未經作者本人同意,轉載文章之後必須在文章頁面明顯位置給出作者和原文連線,否則保留追究法律責任的權利!
相關推薦
【轉】C#進階系列——WebApi 介面引數不再困惑:傳參詳解
正文 前言:還記得剛使用WebApi那會兒,被它的傳參機制折騰了好久,查閱了半天資料。如今,使用WebApi也有段時間了,今天就記錄下API介面傳參的一些方式方法,算是一個筆記,也希望能幫初學者少走彎路。本篇針對初初使用WebApi的同學們,比較基礎,有興趣的且看看。 WebApi系列文章
C#進階系列——WebApi 介面引數不再困惑:傳參詳解
前言:還記得剛使用WebApi那會兒,被它的傳參機制折騰了好久,查閱了半天資料。如今,使用WebApi也有段時間了,今天就記錄下API介面傳參的一些方式方法,算是一個筆記,也希望能幫初學者少走彎路。本篇針對初初使用WebApi的同學們,比較基礎,有興趣的且看看。 WebApi系列文章 本篇打算通過ge
WebApi 介面引數不再困惑:傳參詳解
get和post請求的區別:1、GET使用URL或者cookie傳參,而POST 將資料放在body中2、GET的URL會有長度的限制,一般為1024,而POST的資料可以非常大3、Post比GET更安全,因為資料在位址列不可見4、GET用於獲取資料,而Post用於修改資料
C#進階系列——WebApi 接口參數不再困惑:傳參詳解
pub 博客 bapi write ids 簡單 指定 數組 這也 https://www.cnblogs.com/landeanfen/p/5337072.html 閱讀目錄 一、get請求 1、基礎類型參數 2、實體作為參數 3、數組作為參數 4
WebApi 接口參數不再困惑:傳參詳解
gin ebr 字符流 sts ash nbsp 之前 ret 傳遞對象 轉自:http://www.cnblogs.com/landeanfen/p/5337072.html 閱讀目錄 一、get請求 1、基礎類型參數 2、實體作為參數 3、數組作為
C#進階系列——WebApi 介面返回值不困惑:返回值型別詳解
前言:已經有一個月沒寫點什麼了,感覺心裡空落落的。今天再來篇乾貨,想要學習Webapi的園友們速速動起來,跟著博主一起來學習吧。之前分享過一篇 C#進階系列——WebApi介面傳參不再困惑:傳參詳解 ,這篇博文內容本身很基礎,沒想到引起很多園友關注,感謝大家的支援。作為程式猿,我們都知道引數和返回值是程式設計
C#進階系列——WebApi 介面測試工具:WebApiTestClient
前言:這兩天在整WebApi的服務,由於呼叫方是Android客戶端,Android開發人員也不懂C#語法,API裡面的介面也不能直接給他們看,沒辦法,只有整個詳細一點的文件唄。由於介面個數有點多,每個介面都要詳細說明介面作用、引數型別、返回值型別等等,寫著寫著把博主惹毛了,難道這種文件非要自己寫不成?難道網
C#進階系列——WebApi 接口測試工具:WebApiTestClient
spa type 區域 all 手動 shee 找到 網絡 打開文件 C#進階系列——WebApi 接口測試工具:WebApiTestClient 前言:這兩天在整WebApi的服務,由於調用方是Android客戶端,Android開發人員也不懂C#語法,API裏
C#進階系列——WebApi 身份認證解決方案:Basic基礎認證
str 常見 bre 這一 dex ace timeout ticket 結合 閱讀目錄 一、為什麽需要身份認證 二、Basic基礎認證的原理解析 1、常見的認證方式 2、Basic基礎認證原理 三、Basic基礎認證的代碼示例 1、登錄過程 2、/Home/I
C#進階系列——WebApi 異常處理解決方案(轉)
機制 輸出 ges 如果 但是 rom lba slist 解決 出處:http://www.cnblogs.com/landeanfen/p/5363846.html 閱讀目錄 一、使用異常篩選器捕獲所有異常 二、HttpResponseException自
C#進階系列——WebApi 路由機制剖析:你準備好了嗎?
事先 blank path can tex 全局配置 dex 找不到 save 前言:從MVC到WebApi,路由機制一直是伴隨著這些技術的一個重要組成部分。 它可以很簡單:如果你僅僅只需要會用一些簡單的路由,如/Home/Index,那麽你只需要配置一個默認路由就能簡
C#進階系列——WebApi 跨域問題解決方案:CORS
dea ati ice pro target default 異常 測試工具 復雜 前言:上篇總結了下WebApi的接口測試工具的使用,這篇接著來看看WebAPI的另一個常見問題:跨域問題。本篇主要從實例的角度分享下CORS解決跨域問題一些細節。 WebApi系列文章
[轉]C#進階系列——WebApi 接口返回值不困惑:返回值類型詳解
try 接口測試工具 des rep home creat port 調用 學習 本文轉自:http://www.cnblogs.com/landeanfen/p/5501487.html 閱讀目錄 一、void無返回值 二、IHttpActionResult
C#進階系列——WebApi 異常處理解決方案
前言:上篇C#進階系列——WebApi介面傳參不再困惑:傳參詳解介紹了WebApi引數的傳遞,這篇來看看WebApi裡面異常的處理。關於異常處理,作為程式設計師的我們肯定不陌生,記得在介紹 AOP 的時候,我們講過通過AOP可以統一截獲異常。那麼在我們的WebApi裡面一般是怎麼處理異常的呢,今天這一篇,博主
C#進階系列——MEF實現設計上的“鬆耦合”(終結篇:面向介面程式設計)
序:忙碌多事的八月帶著些許的倦意早已步入尾聲,金秋九月承載著抗戰勝利70週年的喜慶撲面而來。沒來得及任何準備,似乎也不需要任何準備,因為生活不需要太多將來時。每天忙著上班、加班、白加班,忘了去憤,忘了去算計所謂的價值。天津爆炸事故時刻警示著我們生命的無常,逝者安息,活著的人生活還得繼續,珍惜生命,遠離傷害。武
【8】C++進階系列(過載)
1、過載規則 c++幾乎可以過載全部的運算子,而且只能夠過載c++已有的運算子。 其中,不能過載的運算子:"." 、 ".*" 、"::"、"?:" 過載之後運算子的優先順序和結合性都不會改變。 運算子過載是針對新型資料的實際需要,對原有運算子進行適當的改造。例如: 使複數的物件
【7】C++進階系列(類的繼承與派生)
1、繼承的概念 繼承:在儲存原有類的屬性和功能的基礎上,擴充套件新的功能。 開發類庫的團隊和使用類庫的團隊很可能不是一個,有些東西是不能訪問的。 繼承和派生是同一個問題的不同視角: 保持已有類的特性而構建新類的過程成為繼承;在已有類的基礎上新增自己的特性而產生新類的過程叫做派生。
【5】C++進階系列(陣列和指標2)
1、實驗 實驗1:3 x 3矩陣的轉置 #include<iostream> using namespace std; void swap(int &a, int &b) { int temp = a; a = b; b = temp;
【6】C++進階系列(動態記憶體分配)
問題:之前在寫程式的時候計劃好我們需要哪些資料,都定義好,但是有些時候我們並不知道我要處理的程式規模有多大,也不知道陣列開多大合適,是儘量大?分配了太大空間可能會造成記憶體的浪費。只有在程式真正執行起來才會知道這次執行要處理的資料規模有多大——那就有人想,能不能用變數來確定陣
【9】C++進階系列(泛型設計以及STL標準模板庫)
1、泛型程式設計基本概念 泛型程式設計:編寫不依賴與具體資料型別的程式,將演算法從特定的資料結構中抽象出來,成為通用的。C++的模板為泛型程式設計定義了關鍵的基礎。 兩個術語:概念,模型 概念:用來界定具備一定功能的資料型別,例如:將“可以比較大小的所有資料型別(有比較