類(lèi)型
就是數(shù)據(jù)類(lèi)型晦雨,數(shù)據(jù)結(jié)構(gòu)其實(shí)就是數(shù)據(jù)類(lèi)型的一個(gè)延伸架曹。
1)數(shù)據(jù)類(lèi)型就是一系列性質(zhì)相同的值的集合,并對(duì)它們進(jìn)行有效的表達(dá)闹瞧“笮郏可見(jiàn),數(shù)據(jù)類(lèi)型來(lái)源于生產(chǎn)實(shí)踐奥邮,不是憑空想象出來(lái)的万牺。
2)數(shù)據(jù)類(lèi)型配備了一系列與之相配套的操作∏⑾伲可見(jiàn)脚粟,某些操作是專(zhuān)門(mén)針對(duì)某一類(lèi)數(shù)據(jù)類(lèi)型的,不能混用蘸朋。
3)數(shù)據(jù)類(lèi)型核无,可以看成數(shù)據(jù)的“型號(hào)”,有不同的size藕坯。
計(jì)算機(jī)硬件系統(tǒng)分為運(yùn)算器团南,控制器噪沙,存儲(chǔ)器和I/O系統(tǒng)。
運(yùn)算器+控制器:CPU
存儲(chǔ)器:內(nèi)存吐根。程序要運(yùn)行正歼,必須要從硬盤(pán)加載到內(nèi)存中才能運(yùn)行。內(nèi)存就是程序運(yùn)行的空間拷橘。
數(shù)據(jù)類(lèi)型(數(shù)據(jù)型號(hào))局义,指數(shù)據(jù)在內(nèi)存中所占的空間。
好的程序員要考慮程序運(yùn)行時(shí)的內(nèi)存使用是否合理冗疮,有沒(méi)有浪費(fèi)內(nèi)存萄唇,有沒(méi)有出現(xiàn)內(nèi)存泄漏(內(nèi)存空間不能被釋放)等等內(nèi)存問(wèn)題。
內(nèi)存浪費(fèi)赌厅,一是浪費(fèi)硬件投資穷绵,二是擠占其他程序所需的內(nèi)存空間,拖慢系統(tǒng)特愿。程序性能不好。
擴(kuò)展存儲(chǔ)器:如硬盤(pán)勾缭,程序不運(yùn)行時(shí)揍障,就放在擴(kuò)展存貯器中。即便斷電俩由,數(shù)據(jù)也不會(huì)丟毒嫡。
啟動(dòng)一個(gè)程序快,要求內(nèi)存大幻梯,硬盤(pán)快兜畸。
編程語(yǔ)言的數(shù)據(jù)類(lèi)型和數(shù)學(xué)中的數(shù)據(jù)類(lèi)型,大多數(shù)情況下一樣碘梢,有時(shí)會(huì)有顯著區(qū)別咬摇。
e.g. 數(shù)學(xué)中 :int 3 / int 4?= 0,75.
編程中,int 3 / int 4?= 0. 因?yàn)榕鋫浣o整數(shù)的運(yùn)算方法和配備給小數(shù)的運(yùn)算方法不一樣煞躬,整數(shù)運(yùn)算的答案也要是int(在操作符部分會(huì)詳解)肛鹏。
編程語(yǔ)言分為
1)強(qiáng)類(lèi)型(受數(shù)據(jù)類(lèi)型約束很強(qiáng)),如:C#
長(zhǎng)整型賦值給整型的變量恩沛,會(huì)報(bào)錯(cuò)在扰。以此保證數(shù)據(jù)的完整性和安全性。
不允許類(lèi)型的混用雷客,保證了數(shù)據(jù)的正確性
C語(yǔ)言的強(qiáng)弱性沒(méi)有C#強(qiáng)芒珠。C語(yǔ)言中,整型和bool是混用的搅裙,if判斷條件只要不是0皱卓,都是true总放。
C#為了模仿弱類(lèi)型的靈活性,引入了動(dòng)態(tài)類(lèi)型dynamic
//用dynamic可以獲得類(lèi)似Javascript在類(lèi)型上的靈活性
? ? ? ? ? ? dynamic myVar = 100;
? ? ? ? ? ? Console.WriteLine(myVar);
? ? ? ? ? ? myVar = "Mr.Okay!";
? ? ? ? ? ? Console.WriteLine(myVar);
?2)弱類(lèi)型(不怎么受數(shù)據(jù)類(lèi)型的約束)好爬,如:Javascript, 基本上不受數(shù)據(jù)類(lèi)型的約束局雄,很靈活,但是優(yōu)點(diǎn)也是缺點(diǎn)存炮,很容易把邏輯弄亂炬搭。寫(xiě)C和Javascript,一定要注意數(shù)據(jù)類(lèi)型穆桂。
<!DOCTYPE html>
<html>
<head>
? ? <meta charset="utf-8" />
? ? <title></title>
? ? <script>? ? ? ?
? ? ? ? function ButtonClicked()
? ? ? ? ? ? {
? ? ? ? ? ? var myVar = 100;
? ? ? ? ? ? myVar = "Mr.Okay";
? ? ? ? ? ? alert(myVar);
? ? ? ? }
? ? </script>
</head>
<body>
? ? <h1> Hello Javascript! </h1>>
? ? <input type="button"value="Click Me"onclick="ButtonClicked()"/>
</body>
</html>
類(lèi)型系統(tǒng)非常重要宫盔,有很多相關(guān)面試題。
1)sbyte享完,帶正負(fù)號(hào)灼芭,由于帶符號(hào),所以要用最高一位來(lái)給正負(fù)號(hào)般又。
2)byte彼绷,不帶正負(fù)號(hào)
3)Char,Unicode16位茴迁,能放65535個(gè)字節(jié)寄悯,對(duì)于全世界的大多數(shù)語(yǔ)言都?jí)蛴昧恕nicode中收入的常用漢語(yǔ)也就幾千個(gè)字符堕义。
4)short猜旬,有正負(fù)號(hào)的短整型,若一個(gè)數(shù)字的范圍在-32768 --- +32768之間倦卖,用一個(gè)短整型代表就行了洒擦,不會(huì)占用過(guò)多的內(nèi)存空間。
5)ushort怕膛,無(wú)正負(fù)號(hào)的短整型熟嫩。
6)int 帶正負(fù)號(hào)的整型,32位嘉竟,-2147483648 --- +2147483648邦危。比方說(shuō)某個(gè)幼兒園的孩子,數(shù)目不超過(guò)200舍扰,用一個(gè)短整型ushort表示就夠了倦蚪,不需要用int。
7)uint边苹,32位陵且,無(wú)正負(fù)號(hào)的整數(shù),0 --- 4294967295
8)long,64位慕购,帶正負(fù)號(hào)的長(zhǎng)整型聊疲。
9)ulong,64位沪悲,不帶正負(fù)號(hào)的長(zhǎng)整型获洲。一般用于大型系統(tǒng)中,表示身份ID殿如,長(zhǎng)度足夠用了贡珊。
float,可以精確到~6-9位小數(shù)涉馁。
基類(lèi)型(BaseType也叫“副類(lèi)型”)
在面向?qū)ο笤O(shè)計(jì)中门岔,被定義為包含所有實(shí)體共性的class類(lèi)型,被稱(chēng)為“基類(lèi)”烤送。
一個(gè)類(lèi)型可以知道自己的基類(lèi)型是誰(shuí)寒随,在整個(gè)繼承鏈上,位于什么位置帮坚。兩大作用:
1) 靜態(tài)作用
非靜態(tài)的類(lèi)成員妻往,就是實(shí)例成員。
一個(gè)程序在沒(méi)有執(zhí)行的時(shí)候叶沛,就是程序的靜態(tài)時(shí)期蒲讯,即:編輯期和編譯期(build)。靜態(tài)分析程序灰署。
如:寫(xiě)好一段代碼,其中需要訪(fǎng)問(wèn)一些類(lèi)型的成員(變量局嘁,實(shí)例等)溉箕,用編譯器編譯它,此時(shí)依然是靜態(tài)期悦昵,此時(shí)編譯器可以用所要訪(fǎng)問(wèn)的類(lèi)型肴茄,去檢驗(yàn)代碼,如果有誤但指,編譯器直接報(bào)錯(cuò)寡痰。保證了程序的正確性。
2)動(dòng)態(tài)作用
一個(gè)程序在執(zhí)行起來(lái)后棋凳,就是程序的動(dòng)態(tài)時(shí)期拦坠,即:運(yùn)行期。動(dòng)態(tài)調(diào)試程序剩岳。
C#的反射技能(高級(jí)技能)贞滨,給定一個(gè)類(lèi)型或?qū)ο螅梢粤⒓粗榔渲杏心男┏蓡T拍棕,并根據(jù)需要來(lái)操作這些成員晓铆。e.g.?
? ? ? ? ? ?Type myType = typeof(int);
? ? ? ? ? ? Console.WriteLine(myType.Name);??????????????????//類(lèi)型名稱(chēng)
? ? ? ? ? ? Console.WriteLine(myType.FullName);????????????//類(lèi)型全名
? ? ? ? ? ? Console.WriteLine(myType.BaseType);? ? ? ? ???//基類(lèi)
? ? ? ? ? ? Console.WriteLine(myType.BaseType.BaseType.FullName);?????????// 基類(lèi)的基類(lèi)
e.g.??? ? Type myType = typeof(FormatException);
? ? ? ? ? ? PropertyInfo[] pInfos = myType.GetProperties();
? ? ? ? ? ? foreach (var p in pInfos)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Console.WriteLine(p.Name);
? ? ? ? ? ? }
//打印出FormatException的 Properties勺良。
? ? ? ? ? ? Console.WriteLine(myType.Name);? ? ?????????????//類(lèi)型名稱(chēng)
? ? ? ? ? ? Console.WriteLine(myType.FullName);????????????//類(lèi)型全名
? ? ? ? ? ? Console.WriteLine(myType.BaseType);? ? ? ? ? //基類(lèi)
? ? ? ? ? ? Console.WriteLine(myType.BaseType.BaseType.FullName);????????// 基類(lèi)的基類(lèi)
//打印出FormatException的 Methods。
MethodInfo[] mInfos = myType.GetMethods();
? ? ? ? ? ? foreach (var m in mInfos)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Console.WriteLine(m.Name);
? ? ? ? ? ? }
類(lèi)型的運(yùn)算
e.g.?
double result = 3.0 / 4.0;
Console.WriteLine(result);? ?// 結(jié)果為0.75
double result = 3 / 4;
Console.WriteLine(result);? ?// 結(jié)果為0骄噪,3和4是整型尚困,運(yùn)算結(jié)果也為整型,即便有double链蕊。
可見(jiàn)事甜,數(shù)據(jù)類(lèi)型知道自己該進(jìn)行什么運(yùn)算。如果是整型示弓,除法的結(jié)果就是取整讳侨。
程序運(yùn)行時(shí),變量在內(nèi)存的存貯
1. Stack 棧:內(nèi)存分為堆和棧奏属。
用于調(diào)用方法跨跨,比較小,一般只有幾兆
2. Stack overflow:棧溢出
棧比較小比較快囱皿,但是會(huì)爆掉勇婴。如果:
a)算法沒(méi)寫(xiě)好,函數(shù)調(diào)用過(guò)多嘱腥,會(huì)漲爆耕渴。
b)程序有錯(cuò)誤,分配了過(guò)多的內(nèi)存齿兔,也會(huì)爆橱脸。
e.g 1.? 下列程序,方法自己調(diào)用自己分苇,只遞不歸添诉,無(wú)限循環(huán)下去,就會(huì)撐爆棧医寿,導(dǎo)致棧溢出栏赴。
class BadGuy
? ? ? ? {
? ? ? ? ? ? public void BadMethod()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? int x = 100;
? ? ? ? ? ? ? ? this.BadMethod();
? ? ? ? ? ? }
? ? ? ? }
static void Main(string[] args)
? ? ? ? {
? ? ? ? ? ? BadGuy bg = new BadGuy();
? ? ? ? ? ? bg.BadMethod();
? ? ? ?}
e.g 2. 直接到棧上切內(nèi)存,只要切大了靖秩,棧就會(huì)爆掉须眷,導(dǎo)致棧溢出。
unsafe?
? ? ? ? ? ? {
? ? ? ? ? ? ? ? int* p = stackalloc int[99999999];
? ? ? ? ? ? }
3. Heap?堆
存放對(duì)象和實(shí)例沟突,比較大花颗,可以有幾個(gè)G
4. 使用Performance monitor查看進(jìn)程的內(nèi)存使用量
e.g.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Liu6HeapSample
{
? ? /// <summary>
? ? /// Interaction logic for MainWindow.xaml
? ? /// </summary>
? ? public partial class MainWindow : Window
? ? {
? ? ? ? public MainWindow()
? ? ? ? {
? ? ? ? ? ? InitializeComponent();
? ? ? ? }
? ? ? ? List<Window> winList;
? ? ? ? private void Button_Click(object sender, RoutedEventArgs e)
? ? ? ? {
? ? ? ? ? ? winList = new List<Window>();
? ? ? ? ? ? for (int i = 0; i < 15000; i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Window w = new Window();
? ? ? ? ? ? ? ? winList.Add(w);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? private void Button_Click_1(object sender, RoutedEventArgs e)
? ? ? ? {
? ? ? ? ? ? winList.Clear();
? ? ? ? }
? ? }
}
Build編譯上述代碼。Build指編譯自己的代碼事扭,以便和其他的代碼組件“組裝”在一起捎稚。build就是“組裝”。軟件工程師有個(gè)分支,叫build工程師今野,就是專(zhuān)門(mén)給大型軟件做build葡公。
右鍵點(diǎn)擊,選中Open Folder条霜,bin\Debug下有個(gè)應(yīng)用程序催什。雙擊程序,使其從硬盤(pán)加載到內(nèi)存中宰睡,開(kāi)始執(zhí)行之后蒲凶,就形成一個(gè)進(jìn)程。也就是這個(gè)程序正在運(yùn)行的一個(gè)實(shí)例拆内。程序運(yùn)行起來(lái)后旋圆,會(huì)產(chǎn)生一個(gè)同名的進(jìn)程,進(jìn)程還會(huì)有進(jìn)程ID麸恍,簡(jiǎn)稱(chēng)為pID(process id)灵巧。
windows+r,打開(kāi)運(yùn)行窗口抹沪,輸入perfmon
打開(kāi)性能監(jiān)視器
5. 內(nèi)存泄
堆不會(huì)爆掉刻肄,但是在堆里分配了很多對(duì)象,最后忘了回收這些對(duì)象融欧,浪費(fèi)內(nèi)存敏弃,稱(chēng)作“內(nèi)存泄漏”。
C++需要手動(dòng)釋放內(nèi)存噪馏。
c#有內(nèi)存垃圾收集器麦到,會(huì)自動(dòng)回收不用的內(nèi)存。C#不容易出現(xiàn)內(nèi)存泄漏欠肾。相對(duì)安全很多隅要。
6.總結(jié):類(lèi)型在C#中的作用
變量都有自己的類(lèi)型,程序會(huì)根據(jù)變量類(lèi)型董济,將變量分配到堆或者棧(注意:實(shí)例永遠(yuǎn)放在堆里)。