第 6、7 节 详解类型、变量与对象(特别重要)

什么是类型(Type)

类型又称为数据类型(Data Type),数据结构是类型的延伸。

  • 定义:A data type is a homogeneous collection of values(性质相同值的集合), effectively presented, equipped with a set of operations which manipulate these values(一些具体操作是专门针对某种数据类型的).
    1)是数据在内存中存储时的“型号”;
    2)小内存容纳大尺寸数据会丢失精确度、发生错误;
    3)大内存容纳小尺寸数据会导致浪费;
    4)编程语言的数据类型与数学中的数据类型不完全相同
    注意型号指的是一条数据在内存中所占有的空间;内存是计算机程序运行的空间;扩展存储器是程序未运行时存储的空间,例如计算机的硬盘。硬盘转速越高,程序由硬盘向内存转移的速度越快,固态硬盘(SSD硬盘)比电磁性的硬盘更快。
  • 强类型语言与弱类型语言的比较
    当用一门编程语言编写程序时,若数据受数据类型的约束,则称该编程语言为“强类型语言”;反之,若数据受数据类型的约束很弱或者不受数据类型的约束,则称该编程语言为“弱类型语言”。
    强类型语言保证了数据的完整性正确性
    C#语言是强类型编程语言。
    示例1:
int x; //int:4字节,32bit
x = 100;
long y; //long:8字节,64bit
y = 100L;
x = 100L;有误
bool b;
b = true;
b = 100;有误

示例2:比较 C# 和 C 的 if 语句
1)C#语言(强类型语言)

int x = 100;
if (x = 200)有误 //if条件语句的判断条件只能是bool类型的值ture或false
{
   Console.WriteLine("It's OK!");
}

2)C语言(弱类型语言)

int x = 100;
if (x = 200) //非0即为真,所以为了避免发生这样的错误,一般写成 if(200 == x)
{
	printf("It's OK!\n");
}

结果:

示例3:
JavaScript(动态类型)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title> //敲出<title>的另一半</title>只需要在打出“<title”之后,再敲“shift+/”即可
    <script>
        function ButtonClicked() {
            var myVar = 100; //整型
            myVar = "Sue!"; //字符串类型,说明JavaScript语言是一种弱类型的语言
            alert(myVar);
        }
    </script>
</head>
<body>
    <h1>Hello, JavaScript!</h1>
    <input type="button" value=" Click Me" onclick="ButtonClicked()" /> //type、value、onclick之间不能用逗号隔开,只能用空格
</body>
</html>

C#语言对弱类型/动态类型的模仿(dynamic

dynamic myVar = 100; //模仿JavaScript的弱类型
Console.WriteLine(myVar);
myVar = "Miss.Wang!";
Console.WriteLine(myVar);

类型在C#语言中的作用

  • 一个C#类型中所包含的信息有
    1)存储此类型变量所需的内存空间大小
    2)此类型的值可表示的最大、最小值范围


    3)此类型所包含的成员(如方法、属性、事件等)
    程序的静态:程序非执行时(编辑期、编译期)
    程序的动态:程序执行时(运行期)
Type myType = typeof(Form); //获取Form的对象
PropertyInfo[] pInfos = myType.GetProperties();
foreach (var p in pInfos)
{
    Console.WriteLine(p.Name); //打印出Form的所有属性
}
Type myType = typeof(Form); 
MethodInfo[] mInfos = myType.GetMethods();
foreach (var m in mInfos)
{
    Console.WriteLine(m.Name); //打印出Form的所有方法
}

4)此类型由何基类(父类)派生而来

Type myType = typeof(Form);
Console.WriteLine(myType.BaseType.FullName);  //打印出Form的父类的全称

5)程序运行的时候,此类型的变量在分配内存的什么位置
(1)Stack简介(栈):
空间较小,1~2兆,方法调用时使用 。
(2)Stack overflow(栈溢出):
函数调用太多;程序编写错误,分配内存太多。栈溢出的实例如下,
–>函数调用太多导致栈溢出

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StackOverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            BadGuy bg = new BadGuy();
            bg.BadMethod();
        }
    }

    class BadGuy
    {
        public void BadMethod()
        {
            int x = 100;
            this.BadMethod(); //只递不归
        }
    }
}

–>分配内存太多

unsafe
{
    int* p = stackalloc int[9999999];
}

C#语言中,不推荐使用指针,指针被认为是不安全语言,所以在程序运行前,需要做如下操作。

(3) Heap简介(堆):
空间较大,几个G,存储对象。 堆的实例如下,

namespace HeapSample
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        List<Window> winList;
        private void Button1_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 Button2_Click(object sender, RoutedEventArgs e)
        {
            winList.Clear();
        }
    }
}

(4) 使用Performance Monitor查看进程的堆内存使用量






(5) 关于内存泄漏:忘记内存回收
C++语言需要手动回收内存,而C#语言有垃圾收集器,会在合适的时候回收内存。

6)此类型所允许的操作(运算)

double result = 3.0 / 4.0;

结果:0.75

double result = 3 / 4;

结果:0

C#语言的类型系统

  • C#的五大数据类型
    1)类(Classes):如Windows,Form,Console,String
    以Form为例,判断Form是不是类:
    (1)光标放在Form中间,点击f1键。
    (2)Type myType = typeof(Form); Console.WriteLine(myType.FullName);
    找出Form的全称,再利用MSDN文档,点击Index进行搜索。
    (3)Type myType = typeof(Form); Console.WriteLine(myType.IsClass);
    直接判断是不是类。
    (4)光标放在Form中间,点击f12键,查看Form的定义。
    2)结构体(Structures):如Int32,Int64,Single,Double
    3)枚举(Enumerations):如HorizontalAlignment,Visibility
    Form f = new Form();
    f.WondowState = FormWindowState.Maximized; //窗口的大小只有最大化(Maximized)、最小化(Minimized)、正常(Normal)三种可供用户选择
    f.ShowDialog();
    4)接口(Interfaces)
    5)委托(Delegates)

注意:class:声明和定义;struct:声明和定义结构体;enum:声明和定义枚举

  • C#类型的派生谱系

变量、对象与内存

变量 = 以变量名所对应的内存地址为起点,以其数据类型所要求的存储空间为长度的一块内存区域

  • 什么是变量
    1)表面上来看(从C#代码的上下文行文上看),变量的用途是存储数据
    2)实际上,变量表示了存储位置,并且每个变量都有一个类型,以决定什么样的值能够存入变量
    3)变量一共有7种:静态变量,实例变量(成员变量、字段),数组元素,值参数,引用参数,输出参数,局部变量。
    4)狭义的变量指局部变量,因为其他种类的变量都有自己的约定名称
    简单地讲,局部变量就是方法体(函数体)里声明的变量
    5)变量的声明
    有效地修饰符组成(opt) 类型 变量名 初始化器(opt)(opt表示可选的,可有可无)
public static int Amount = 0; //public static:有效地修饰符组合,int:类型,Amount:变量名,= 0:初始化器

另外,对7种变量做简单的实例介绍:
静态成员变量是隶属于类的,而不是类的实例;

public static int Amount; //静态成员变量

属性是为了保护字段,不让其随便被赋值;

 public int Age;
 public string Name;

数组元素:

int[] array = new int[100];
array[0] = 100;

值参数:

public double Add(double a, double b) //a、b是值参数变量
{
    return a + b;
}

引用参数、输出参数变量:

public double Add(ref double a, out double b) //a是引用参数变量,b是输出参数变量
{
    return a + b;
}
  • 值类型的变量
    1)以byte(无符号1字节)/sbtye(有符号1字节)/short(有符号2字节)/ushort(无符号2字节)为例
    有符号位:0表示正数,1表示负数
    100:01100100
    -100:10011011+00000001= 10011100(对100的二进制数按位取反,再加1)
    :高八位存储在地址的高位上,低八位存储在地址的低位上
    2)值类型没有实例,所谓的“实例”与变量合而为一

  • 引用类型的变量与实例
    引用类型变量与实例的关系:引用类型变量里存储的数据是对象的内存地址(引用类型变量被分配的内存空间是4个字节

  • 局部变量是在stack(栈)上分配内存,实例和实例的成员变量是在heap(堆)上分配内存。

  • 变量的默认值
    成员变量在声明之后,会获得默认值0;C#的本地变量必须要有明显的赋值,没有默认值。

  • 常量(值不可改变的变量)
    const int x = 100; //const表示常量,初始化器不能省略

  • 装箱与拆箱(Boxing & Unboxing)
    装箱和拆箱会使性能有所损失。
    装箱:将栈上值类型的值封装成obj类型的实例,存储在堆上;
    拆箱:将堆上obj实例里的值按照要求拆成目标类型,放在栈上

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值