C#笔记(上)

参考https://blog.csdn.net/mahoon411/article/details/109442403

 

C# 占位符{}
当 WriteLine() 函数有多个参数时,输出第一个参数(双引号内的)中的内容,而第二个及后面的参数中的内容替换掉第一个参数中对应位置的占位符一起输出。

    • 占位符从零开始计数,且占位符中的数字不能大于第二个及后面的参数的总个数减一(要求占位符必须有可替换的值)。
      占位符数字与第二个及后面的参数字符位置一一对应。

C# 数据类型

在 C# 中,变量分为以下几种类型:

值类型(Value types)

引用类型(Reference types)

指针类型(Pointer types)

 

从内存上看,值类型是在栈中的操作,而引用类型是在堆中的操作。
(导致 => 值类型存取速度快,引用类型存取速度慢。)
从本质上看,值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用。
(值类型是具体的那个数值所占用的空间大小,而引用类型是存放那个数值的空间地址。)
从来源上看,值类型继承自System.ValueType,引用类型继承自System.Object。
特别的:结构体是值类型,类和string是引用类型。

堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:
  • 堆中某个结点的值总是不大于或不小于其父结点的值;
  • 堆总是一棵完全二叉树。
将根结点最大的堆叫做最大堆或大根堆,根结点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。
堆是非线性数据结构,相当于一维数组,有两个直接后继。

 

 

内置的引用类型有:object、dynamic 和 string。

对象(Object)类型 是 C# 通用类型系统(Common Type System - CTS)中所有数据类型的终极基类。Object 是 System.Object 类的别名。所以对象(Object)类型可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,在分配值之前,需要先进行类型转换。

当一个值类型转换为对象类型时,则被称为装箱;另一方面,当一个对象类型转换为值类型时,则被称为拆箱。

装箱:值类型转换为对象类型,
拆箱:之前由值类型转换而来的对象类型再转回值类型

只有装过箱的数据才能拆箱。

动态(Dynamic)类型

您可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。
声明动态类型的语法:

dynamic <variable_name> = value;
动态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。

编译一个 C程序可以分为四阶段:预处理阶段--->生成汇编代码阶段--->汇编阶段--->链接阶段。

1.在讲解 C# 程序的编译与执行之前,首先了解以下两个概念,以便充分理解C# 程序的运行。

CLI--Common Language Infrastructure 的简称,C# 程序在Microsoft .NET Framework 上运行时,

它是 Windows 的一个必要组件,包括一个称为公共语言运行库(CLR,在第1章中对该内容有过详细讲解)的虚拟执行系统和一组统一的类库。

IL--Intermediate Language 的简称,称为中间语言,又称为 MSIL。所有Microsoft .NET 源代码(使用任何语言)被编译为 IL,

然后在软件的安装点上或者运行时,IL 由即时(JIT)编译器转换为机器码。
图2.1演示了C# 源文件、基类库、程序集和 CRL 的编译与执行过程。

第一阶段--把 C# 编写的源文件编译为一种符合 CLI 规范的中间语言(IL)。IL 代码与资源(如位图和字符串)一起作为一种称为

程序集的可执行文件存储在磁盘上,通常具有的扩展名为 .exe 或 .dll。

第二阶段--执行 C# 程序时,程序集将加载到 CLR 中,这可能会根据清单中的信息执行不同的操作。如果符合安全要求,

CLR 执行即时(JIT)编译以将 IL 代码转换为本机机器语言。CLR 还提供与自动垃圾回收、异常处理和资源管理有关的其他服务。

由 CLR 执行的代码有时称为"托管代码",它与编译为面向特定系统的本机机器语言的"非托管代码"相对应。

 

字符串(String)类型 允许您给变量分配任何字符串值。字符串(String)类型是 System.String 类的别名。它是从对象(Object)类型派生的。字符串(String)类型的值可以通过两种形式进行分配:引号和 @引号。

C# string 字符串的前面可以加 @(称作"逐字字符串")将转义字符(\)当作普通字符对待,比如:

string str = @"C:\Windows";

等价于:

string str = "C:\\Windows";

@ 字符串中可以任意换行,换行符及缩进空格都计算在字符串长度之内。

string str = @"<script type=""text/javascript"">
    <!--
    -->
</script>";存疑

用户自定义引用类型有:class、interface 或 delegate。

指针类型(Pointer types)

指针类型变量存储另一种类型的内存地址。C# 中的指针与 C 或 C++ 中的指针有相同的功能。
声明指针类型的语法:

type* identifier;

C# 类型转换
类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型。在 C# 中,类型铸造有两种形式:

隐式类型转换 :这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。
显式类型转换 :显式类型转换,即强制类型转换。通过用户使用预定义的函数显式完成的,显式转换需要强制转换运算符,而且强制转换会造成数据丢失。转换类型的范围大小和从属关系和隐式转换相反。显式转换可能会导致数据出错,或者转换失败,甚至无法编译成功。

namespace TypeConvertion
{ class Class1
{

}

class Class2 : Class1 //类Class2是类Class1的子类
{

}
class Program
{
static void Main(string[] args)
{
int inum = 100;
long lnum = inum; // 进行了隐式转换,将 int 型(数据范围小)数据转换为了 long 型(数据范围大)的数据
Class1 c1 = new Class2(); // 这里也是隐式转换,将一个新建的 Class2 实例转换为了其基类 Class1 类型的实例 C1
}
}
}

C# 类型转换方法

C# 提供了下列内置的类型转换方法:

 

 

 

int i = 75;
float f = 53.005f;
double d = 2345.7652;
bool b = true;

Console.WriteLine(i.ToString());
Console.WriteLine(f.ToString());
Console.WriteLine(d.ToString());
Console.WriteLine(b.ToString());
Console.ReadKey();

Convert.ToInt32()的取整

C# 中对 double 类型的数据取整,可以使用Convert.ToInt32()方法,也可使用 int 强制转换为整数,使用 int 时并不存在四舍五入的情况,而是直接将后面的小数位数丢掉。

接受来自用户的值
System 命名空间中的 Console 类提供了一个函数 ReadLine(),用于接收来自用户的输入,并把它存储到一个变量中。
例如:

int num;
num = Convert.ToInt32(Console.ReadLine());
函数 Convert.ToInt32() 把用户输入的数据转换为 int 数据类型,因为 Console.ReadLine() 只接受字符串格式的数据。

C# 中的 Lvalues 和 Rvalues
C# 中的两种表达式:

lvalue(左值):lvalue 表达式可以出现在赋值语句的左边或右边。
rvalue(右值):rvalue 表达式可以出现在赋值语句的右边,不能出现在赋值语句的左边。
变量是 lvalue 的,所以可以出现在赋值语句的左边。数值是 rvalue 的,因此不能被赋值,不能出现在赋值语句的左边。

 

C# 常量
常量是固定值,程序执行期间不会改变。常量可以是任何基本数据类型,比如整数常量、浮点常量、字符常量或者字符串常量,还有枚举常量。
常量可以被当作常规的变量,只是它们的值在定义后不能被修改。

7.1 整数常量
整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,没有前缀则表示十进制。
整数常量也可以有后缀,可以是 U 和 L 的组合,其中,U 和 L 分别表示 unsigned 和 long。后缀可以是大写或者小写,多个后缀以任意顺序进行组合。

85 /* 十进制 */
0213 /* 八进制 */
0x4b /* 十六进制 */
30 /* int */
30u /* 无符号 int */
30l /* long */
30ul /* 无符号 long */


212 /* 合法 */ 215u /* 合法 */ 0xFeeL /* 合法 */ 078 /* 非法:8 不是一个八进制数字 */ 032UU /* 非法:不能重复后缀 */

一个浮点常量是由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。

 

浮点常量

一个浮点常量是由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
这里有一些浮点常量的实例:

3.14159 /* 合法 */ 314159E-5L /* 合法 */ 510E /* 非法:不完全指数 */ 210f /* 非法:没有小数或指数 */ .e55 /* 非法:缺少整数或小数 */

使用小数形式表示时,必须包含小数点、指数或同时包含两者。使用指数形式表示时,必须包含整数部分、小数部分或同时包含两者。有符号的指数是用 e 或 E 表示的。

 

字符常量
字符常量是括在单引号里,例如,‘x’,且可存储在一个简单的字符类型变量中。一个字符常量可以是一个普通字符(例如 ‘x’)、一个转义序列(例如 ‘\t’)或者一个通用字符(例如 ‘\u02C0’)。

在 C# 中有一些特定的字符,当它们的前面带有反斜杠时有特殊的意义,可用于表示换行符(\n)或制表符 tab(\t)。

 

静态常量(编译时常量)const

在编译时就确定了值,必须在声明时就进行初始化且之后不能进行更改,可在类和方法中定义。定义方法如下:

const double a=3.14;// 正确声明常量的方法

const int b; // 错误,没有初始化

 

动态常量(运行时常量)readonly

在运行时确定值,只能在声明时或构造函数中初始化,只能在类中定义。

class Program
{
readonly int a=1; // 声明时初始化
readonly int b; // 构造函数中初始化
Program()
{
b=2;
}
static void Main()
{
}
}

静态常量与动态常量的使用场景

在下面两种情况下,可以使用 const 常量:

  • 取值永久不变(比如圆周率、一天包含的小时数、地球的半径等)。
  • 对程序性能要求非常苛刻。

除此之外的其他情况都应该优先采用 readonly 常量。

 

 算术运算符

c = a++: 先将 a 赋值给 c,再对 a 进行自增运算。
c = ++a: 先将 a 进行自增运算,再将 a 赋值给 c 。
c = a --: 先将 a 赋值给 c,再对 a 进行自减运算。
c = --a: 先将 a 进行自减运算,再将 a 赋值给 c 。

 

关系运算符

 

 逻辑运算符

 

 &&逻辑与

||逻辑或

 

位运算符

 

 

 

 

赋值运算符

 

 

 

 

其他运算符

 

 

C# 中的运算符优先级

运算符的优先级确定表达式中项的组合。

下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。

 

posted @   漆雕默  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示