CSharp(C#)语言_第一章

1.1 C#程序是一组类型声明

        如果广泛地描述C和C++程序源代码的特征,可以说C程序是一组函数和数据类型,C++程序是一组函数和类,而C#程序则是一组类型声明

C#程序或DLL的源代码是一组一种成多种类型声明
        对于可执行程序,类型声明中必须有一个包含Main方法的类
        命名空间是一种把相关的类型声明分组并命名的方法。既然程序是一组相关的类型声明
        那么通常会把程序声明在你创建的命名空间内部

1.2 类型是一种模板

        既然C#程序就是一组类型声明,那么学习C#就是学习如何创建和使用类型。所以,需要做的第一件事情就是了解什么是类型

        可以把类型想象成一个用来创建数据结构的模板。模板本身并不是数据结构,但它详细说明了由该模板构造的对象的特征

类型由下面的元素定义:
        名称
        用于保存数据成员的数据结构
        一些行为及约束条件

1.3 实例化类型

从某个类型模板创建实际的对象,称为实例化该类型
        通过实例化类型而创建的对象被称为类型的对象或类型的实例。这两个术语可以互换
        在C#程序中,每个数据项都是某种类型的实例。这些类型可以是语言自带的,可以是BCL或其他库提供的,也可以是程序员定义的

1.4 数据成员和函数成员

        像short、int和long等这样的类型称为简单类型。这种类型只能存储一个数据项。其他的类型可以存储多个数据项。比如数组(array)类型就可以存储多个同类型的数据项。这些数据项称为数组元素。可以通过数字来引用这些元素,这些数字称为索引

成员的类别
        一些类型可以包含许多不同类型的数据项。这些类型中的数据项个体称为成员,并且与数组中使用数字来引用成员不同,这些成员有独特的名称
        有两种成员:数据成员函数成员
                数据成员 保存了与这个类的对象或作为一个整体的类相关的数据
                函数成员 执行代码。函数成员定义类型的行为

1.5 预定义类型

        C#提供了16种预定义类型,其中包括13种简单类型和3种非简单类型
        所有预定义类型的名称都由全小写的字母组成。预定义的简单类型包括以下3种

        11种数值类型
                ■ 不同长度的有符号和无符号整数类型
                ■ 浮点数类型float和double
                ■ 一种称为decimal的高精度小数类型。与float和double不同,decimal类型可以准确地表示分数。decimal类型常用于货币的计算

        一种Unicode字符类型char
        一种布尔类型bool。bool类型表示布尔值并且必须为true或false

扫描二维码关注公众号,回复: 10432243 查看本文章

        3种非简单类型如下:
                string,它是一个Unicode字符数组
                object,它是所有其他类型的基类
                dynamic,使用动态语言编写的程序集时使用

预定义类型
        所有预定义类型都直接映射到底层的.NET类型。C#的类型名称就是.NET类型的别名,所以使用.NET的类型名称也能很好地符合C#语法,不过并不鼓励这样做。在C#程序中,应该尽量使用C#类型名称而不是.NET类型名称!!!

1.6 用户定义类型

        除了C#提供的16种预定义类型,还可以创建自己的用户定义类型。有6种类型可以由用户自己创建

类类型(class )
结构类型(struct)
数组类型(array)
枚举类型(enum)
委托类型(delegate)
接口类型(interface)

类型通过类型声明创建,类型声明包含以下信息:

要创建的类型的种类
新类型的名称
对类型中每个成员的声明(名称和规格)。array和delegate类型除外,它们不含有命名成员

        一旦声明了类型,就可以创建和使用这种类型的对象,就像它们是预定义类型一样。使用预定义类型是一个单步过程,简单地实例化对象即可。使用用户定义类型是一个两步过程:必须先声明类型,然后实例化该类型的对象

1.7 栈和堆

        程序运行时,它的数据必须存储在内存中。一个数据项需要多大的内存、存储在什么地方、以及如何存储都依赖于该数据项的类型

运行中的程序使用两个内存区域来存储数据:栈和堆
        栈

栈是一个内存数组,是一个LIFO(Last-In First-Out,后进先出)的数据结构。栈存储几种类型的数据:
        某些类型变量的值
        程序当前的执行环境
        传递给方法的参数

        系统管理所有的栈操作。作为程序员,你不需要显式地对它做任何事情。但了解栈的基本功能可以更好地了解程序在运行时正在做什么,并能更好地了解C#文档和著作

栈的特征:
        数据只能从栈的顶端插入和删除
        把数据放到栈顶称为入栈(push)
        从栈顶删除数据称为出栈(pop)

        堆

        堆是一块内存区域,在堆里可以分配大块的内存用于存储某类型的数据对象。与栈不同,堆里的内存能够以任意顺序存入和移除

        虽然程序可以在堆里保存数据,但并不能显式地删除它们。CLR的自动GC(Garbage Collector,垃圾收集器)在判断出程序的代码将不会再访问某数据项时,自动清除无主的堆对象。我们因此可以不再操心这项使用其他编程语言时非常容易出错的工作了

1.8 值类型和引用类型

        数据项的类型定义了存储数据需要的内存大小及组成该类型的数据成员。类型还决定了对象在内存中的存储位置——栈或堆
        类型被分为两种:值类型和引用类型,这两种类型的对象在内存中的存储方式不同

值类型只需要一段单独的内存,用于存储实际的数据
引用类型需要两段内存
        ■第一段存储实际的数据,它总是位于堆中
        ■第二段是一个引用,指向数据在堆中的存放位置

1.8.1 存储引用类型对象的成员

        引用类型对象的数据部分始终存放在堆里
        值类型对象,或引用类型数据的引用部分可以存放在堆里,也可以存放在栈里,这依赖于实际环境
        例如,假设有一个引用类型的实例,名称为MyType,它有两个成员:一个值类型成员和一个引用类型成员。它将如何存储呢?是否是值类型的成员存储在栈里,而引用类型的成员栈和堆之间是分成两半呢?答案是否定的

        请记住,对于一个引用类型,其实例的数据部分始终存放在堆里。既然两个成员都是对象数据的一部分,那么它们都会被存放在堆里,无论它们是值类型还是引用类型。下图阐明了MyType的情形
在这里插入图片描述

        尽管成员A是值类型,但它也是MyType实例数据的一部分,因此和对象的数据一起被存放在堆里
        成员B是引用类型,所以它的数据部分会始终存放在堆里,正如图中“数据”框所示。不同的是,它的引用部分也被存放在堆里,封装在MyType对象的数据部分中

1.9 变量

一种多用途的编程语言必须允许程序存取数据,而这正是通过变量实现的
        变量是一个名称,表示程序执行时存储在内存中的数据
        C#提供了4种变量

名        称 描        述
本地变量 在方法的作用域保存临时数据,不是类型成员
字段 保存和类型或类型实例相关的数据,是类型成员
参数 用于从一个方法到另一个方法传递数据的临时变量,不是类型成员
数组元素 (通常是)同类数据项构成的有序集合的一个成员,可以为本地变量,也可以为类型的成员
1.9.1 变量声明

        变量在使用之前必须声明。变量声明定义了变量,并完成两件事:
                给变量命名,并为它关联一种类型
                让编译器为它分配一块内存
        一个简单的变量声明至少需要一个类型和一个名称

变量的初始化:
语法:数据类型 变量名 = 值

未初始化的本地变量有一个未定义的值,在未赋值之前不能使用,试图使用未初始化的变量会造成程序的报错

1.9.2自动初始化

        一些类型的变量如果在声明时没有初始化语句,那么会被自动设为默认值,而另一些则不能。没有自动初始化为默认值的变量在程序为它赋值之前包含未定义值。下表展示了哪种类型的变量会被自动初始化以及哪种类型的变量不会被初始化

变量类型 存储位置 自动初始化 用途
本地变量 栈或栈和堆 用于函数成员内部的本地运算
类字段 类成员
结构字段 栈或堆 结构成员
参数 用于把值传入或传出方法
数组元素 数组成员
1.9.3 多变量声明

        可以把多个变量声明在一条单独的声明语句中
                多变量声明中的变量必须类型相同
                变量名必须用逗号分隔,可以在变量名后包含初始化语句

                语法:数据类型 变量名 = 值 , 变量名;
可以直接初始化,也可以不初始化。变量的数据类型必须相同

1.9.4 静态类型和 dynamic 关键字

        每一个变量都包括变量类型。这样编译器就可以确定运行时需要的内存总量以及哪些部分应该存在栈上,哪些部分应该存在堆上。变量的类型在编译的时候确定并且不能在运行时修改。这叫做静态类型

        但是不是所有的语言都是静态类型的,诸如IronPython和IronRuby之类的脚本语言是动态类型的。也就是说,变量的类型直到运行时才会被解析。由于它们是.NET语言,所以C#程序需要能够使用这些语言编写的程序集。问题是,程序集中的类型到运行时才会被解析,而C#又要引用这样的类型并且需要在编译的时候解析类型

        针对这个问题,C#语言的设计者为语言增加了dynamic关键字,代表一个特定的、实际的C#类型,它知道如何在运行时解析自身

        在编译时,编译器不会对dynamic类型的变量进行类型检查。相反,它将与该变量及该变量的操作有关的所有信息打包。在运行时,会对这些信息进行检查,以确保它与变量所代表的实际类型保持一致性。否则,将在运行时抛出异常

1.9.5 可空类型

        在某些情况下,特别是使用数据库的时候,你希望表示变量目前未保存有效的值。对于引用类型,这很简单,可以把变量设置为null。但定义值类型的变量时,不管它的内容是否有有效的意义,其内存都会进行分配
        对于这种情况,你可能会使用一个布尔指示器来和变量关联,如果值有效,则设置为true,否则就设置为false
        可空类型允许创建可以标记为有效或无效的值类型,这样就可以在使用它之前确定值的有效性。普通的值类型称作非可空类型


C#第一章到此结束

发布了48 篇原创文章 · 获赞 55 · 访问量 4473

猜你喜欢

转载自blog.csdn.net/qq_43562262/article/details/104727651