《C#从入门到项目实践》笔记4

《C#从入门到项目实践》基础知识 第4章

  • 第4章 C#程序开发基础——数据类型与运算符
        • 声明
    • 4.1 数据类型概述
    • 4.2 数据类型之间的转换
      • 4.2.1 隐式转换
      • 4.2.2 显式转换
      • 4.2.3 使用Convert进行任意类转换
      • 4.2.4 数值和字符串之间的转换
      • 4.2.5 Convert.ToInt32()、(int)与int.Parse()的区别
    • 4.3 其他常用类型
      • 4.3.1 日期和时间
      • 4.3.2 全局唯一标识符
      • 4.3.3 统一资源标识符
    • 4.4 运算符
      • 4.4.1 算术运算符
      • 4.4.2 赋值运算符
      • 4.4.3 关系运算符
      • 4.4.4 逻辑运算符
      • 4.4.5 位运算符
      • 4.4.6 特殊运算符
      • 4.4.7 运算符优先级
    • 4.5 就业面试技巧与解析
      • 4.5.1 面试技巧与解析(一)
      • 4.5.2 面试技巧与解析(二)

第4章 C#程序开发基础——数据类型与运算符

声明

本博客中的源代码由于电脑系统问题,均未编译调试过,都是按照《C#从入门到项目实践》一书人工敲上去的(为了练手速),待重装完系统安装了软件之后,立马马上调试修改。

4.1 数据类型概述

在C#中有两种基本类型,分别是值类型和引用类型。而值类型还可以细分为内置值类型、结构和枚举;引用类型可以细分为类类型、接口以及委托等。
《C#从入门到项目实践》笔记4_第1张图片
1.值类型
内置的值类型就是整型、浮点型和bool类型等,而结构是一种特殊的值类型,它是抽象类型System.ValueType的直接派生类,而System.ValueType本身又是直接从System.Object派生的,所以结构体拥有值类型所有的特权和限制。
如果需得到一个类型或一个变量在特定平台上的准确空间大小,可以使用sizeof方法。表达式sizeof(type)可以产生以字节为单位的存储对象或类型的存储空间大小。
2.引用类型
引用类型变量又称为对象,可存储对实际数据的引用。内置的引用类型有对象类型、动态类型和字符串类型。
(1)对象类型的关键字是object,也就是System.Object的别名。在C#的统一类型系统中,所有类型都是直接或间接从Object继承的。可以将任何类型的值赋给object类型的变量。但是,在分配值之前,需要先进行类型转换。
例如:定义object类型的变量用于接收任何数据类型的值。

using System;
namespace Progect
{
	class Program
	{
		static void Main(string[] args)
		{
			object age, name, height, sex;		//定义4个object变量
			age = 16;							//整型赋值成功
			name = "周小红";						//string类型赋值成功
			height = 152.32;					//double类型赋值成功
			sex = '女';							//char类型赋值成功
			Console.WriteLine("年龄:{0}\t姓名:{1}\t身高:{2}\t性别:{3}", age, name, height, sex);
		}
	}
}

《C#从入门到项目实践》笔记4_第2张图片
本例演示了object类型的变量如何在.NET Framework中使用Object的方法。在代码中首先定义四个object类型的变量,分别为age、name、height和sex;然后分别赋予整型值、字符串值、浮点值和字符值;最后进行输出。
(2)动态类型的关键字是dynamic,该类型的作用是绕过编译时类型检查,改为在运行时解析这些操作。dynamic类型简化了对COM AP(I例如OfficeAutomation API)、动态API(例如IronPython库)和HTML文档对象模型(DOM)的访问。
在大多数情况下,dynamic类型与object类型的行为类似。但是,如果操作包含dynamic类型的表达式,那么不会通过编译器对该操作进行解析或类型检查。dynamic类型只在编译时存在,在运行时则不存在。
例如:对dynamic类型的变量与object类型的变量进行对比。

using System;
namespace Project
{
	class Program
	{
		static void Main(string[] args)
		{
			dynamic dyn = 1;
			object obj = 1;
			//编译时的类型
			Console.WriteLine(dyn.GetType());
			Console.WriteLine(obj.GetType());
		}
	}
}

《C#从入门到项目实践》笔记4_第3张图片
本例演示了dynamic的用法。在代码中首先定义dynamic类型的变量dyn和object类型的变量obj,并对它们都赋值为1;然后使用GetType()方法输出代码编译时两个变量的数据类型。
(3)字符串类型的关键字是string,也就是System.String的另外一个名字。string类型是一个字符序列(0个或更多的Unicode字符)。“+”运算符用于连接两个或更多的字符串。
例如:

string str = "Hello" + "World";		//输出Hello World

3.装箱和拆箱(不能理解)
装箱和拆箱是值类型和引用类型之间相互转换时要执行的操作。
(1)装箱在值类型向引用类型转换时发生。
例如:

object obj = 1;

这行语句将整型常量1赋给object类型的变量obj;众所周知,常量1是值类型,值类型是要放在栈上的,而object是引用类型,它需要放在堆上;所以,执行装箱操作时不可避免地要在堆上申请内存空间,并将堆栈上的值类型数据复制到申请的堆内存空间上,这肯定是要消耗内存和CPU资源的。
(2)拆箱在引用类型向值类型转换时发生。
例如:

object obj = 5;
int value = (int)obj;

这两行代码会执行一次装箱操作将整型数字常量5装箱成引用类型object变量obj;然后又执行一次拆箱操作,将存储到堆上的引用变量obj存储到局部整型变量value中。拆箱操作的执行过程和装箱操作过程正好相反,是将存储在堆上的引用类型值转换为值类型并赋给值类型变量。

4.2 数据类型之间的转换

类型转换是把数据从一种类型转换为另一种类型。在C#中,转换分为隐式转换和显式转换。

4.2.1 隐式转换

隐式类型转换就是指C#默认的以安全方式进行的转换,不会导致数据丢失。隐式转换可能会在许多情况下出现,包括方法调用和赋值语句。如下表所示列出了预定义隐式转换的数据类型。
《C#从入门到项目实践》笔记4_第4张图片
例如,将int类型的值隐式转换成long型。

int i = 100;		//声明一个整型变量i并初始化为100
long j = i;			//隐式转换成long型

关于隐式类型转换,需要注意以下几点。
(1)在从int、uint、long或ulong转换为float,以及从long或ulong转换为double时,可能会丢失精度。
(2)不存在针对char类型的隐式转换。
(3)浮点类型与decimal类型之间不存在隐式转换。
(4)int类型的常数表达式可以转换为sbyte、byte、short、ushort、uint或ulong,前提是常数表达式的值处于目标类型的范围内。

4.2.2 显式转换

当类型转换可能会发生数据丢失时,编译器就会要求执行显式转换。显式转换也称为强制转换。强制转换是显式告知编译器用户打算进行转换,并且用户知道可能会发生数据丢失的一种方式。如果要执行强制类型转换,需要在要转换的值或变量前面的括号中指定要强制转换到的类型。
例如:将double强制转换为int。

using System;
namespace Project
{
	class Program
	{
		static void Main(string[] args)
		{
			double d = 314.159;
			int i;
			//强制转换double为int
			i = (int)d;
			Console.WriteLine(i);
		}
	}
}

《C#从入门到项目实践》笔记4_第5张图片
本例演示了显式类型转换的用法。在代码中,首先定义一个double类型的变量d,并为其赋值为314.159;接着再定义一个int类型的变量i;最后将变量d通过强制类型转换的方式,赋给变量i。但是如不进行强制转换,则该程序不会进行编译。
由于显式转换包括所有隐式转换和显式转换,因此总是可以使用强制转换表达式,将任何数值类型转换为任何其他的数值类型。如下表所示列出了需要进行显式转换的数据类型。
《C#从入门到项目实践》笔记4_第6张图片
显式转换可能会导致精度降低或导致引发异常,所以需要注意以下几点。
(1)将decimal值转换为整型类型时,此值会向零舍入到最接近的整数值。如果生成的整数值处于目标类型的范围之外,则会引发溢出错误。
(2)从double或float值转换为整型类型时,会截断该值。如果生成的整数值处于目标值范围之外,则结果会取决于溢出检查上下文。在已检查的上下文中,引发溢出错误;而在未检查的上下文中,结果是目标类型的未指定值。
(3)将double转换为float时,double值舍入为最接近的float值。如果double值太小或太大,无法匹配目标类型,结果将为零或无穷大。
(4)将float或double转换为decimal时,源值转换为decimal表示形式,并四舍五入到第28位小数后最接近的数。根据源值的值,可能出现以下结果之一:
① 如果源值太小,无法表示为decimal,结果则为零。
② 如果源值为NaN(非数值)、无穷大或太大而无法表示为decimal,则引发溢出错误。
(5)将decimal转换为float或double时,decimal值舍入到最接近的double或float值。

4.2.3 使用Convert进行任意类转换

类型如果是相兼容的两个变量,则可以使用隐式类型转换或者强制类型转换,但是,如果两个变量不兼容,例如说string和int或者string和double类型,这个时候用户就需要一种名叫Convert的转换工厂进行转换。
Convert是专门进行类型转换的类,它能够实现各种基本数据类型之间的装换。C#提供了内置的类型转换方法,如下表所示。
《C#从入门到项目实践》笔记4_第7张图片
例如:使用ToInt32方法,将string字符串类型转换成int和double类型并且输出。

using System;
namespace Project
{
	class Program
	{
		static void Main(string[] args)
		{
		string str = "123456";				//定义字符串类型的变量str
		int a = Convert.ToInt32(str);		//Convert类的方法将字符串转换为int类型
		Console.WriteLine(a);
		double d = Convert.ToDouble(str);	//Convert类的方法将字符串转换为double类型
		Console.WriteLine(d);
		}
	}
}

《C#从入门到项目实践》笔记4_第8张图片
本例演示了Convert类的转换方法。在代码中首先定义字符串类型的变量str,并为其赋值为“123456”;然后通过ToInt32方法,将str的数据分别转换为int类型和double类型。
注意:使用Convert进行强制类型转换也要满足一个条件只有能够表示成数字的字符串才可以进行转换。
例如:

string num = "123abc";		//不能转换成int数值型

4.2.4 数值和字符串之间的转换

C#中不仅存在数值类型的数据之间的转换,字符串和数值之间也是可以互相转换的,只是方法不同而已。
1.数值型转换为字符型数值型数据转换为字符串用ToString()方法即可实现。
例如:

int num1=10;
string munum=num1.ToString();

2.字符串转换为数值型字符串数据转换为数值型使用Parse ()方法。
(1)使用int.Parse ()方法,将字符串类型转换为整型。

string str="10";
int number=int.Parse(str);

(2)使用double.Parse ()方法,将字符串类型转换为双精度浮点型。
例如:

string str="20";
double number=double.Parse(str);

(3)使用float.Parse ()方法,将字符串类型转换为单精度浮点型。

string str="30";
float number=float.Parse(str);

并不是所有的字符串都可以转换为数值型数据,只有能够表示成数字的字符串才可以进行转换,例如名字“张三”,转换成数字就没有符合的表达式,所以不能实现转换。
注意:Parse ()括号中的参数只能是字符串,不能为其他数据类型。

4.2.5 Convert.ToInt32()、(int)与int.Parse()的区别

C#中数据转换的方法很多,本节主要讲解Convert.ToInt32()、(int)与int.Parse()的区别。在实际开发项目的过程中,需要被转换的类型大概分为三大类,分别是空值(null)、数字类型(包含float,double,int,long等)和字符串(string)。
(1)对null值进行类型转换。
例如:

int x = Convert.ToInt32(null);
int y = int.Parse(null);			//编译器提示值不能为null
int z = (int)null;					//编译器无法将null转换为“int”,因为后者是不可以为null的类型值

对于空值null,从运行报错的角度讲,(int)强制转换和int.Parse()都不能接受null;Convert.ToInt32()其实是在转换前先做了一个判断,参数如果为null,则直接返回0。
(2)转换数字类型,主要测试double和long类型。
对于double类型:

double m = 1.5d;
int x = Convert.ToInt32(m);
int y = int.Parse(m.ToString());	//输入字符串的格式不正确
int z = (int)m;

针对于浮点型的取舍问题,浮点型只有Convert.ToInt32()和(int)能进行转换,但是也是进行取舍了的。Convert.ToInt32()采取的取舍是进行四舍五入,而(int)则是截取浮点型的整数部分,忽略小数部分。
例如,Convert.ToInt32(1.49d)和(int)1.49d都返回1,Convert.ToInt32(1.5d)返回2,而(int)1.5d还是返回1。
对于long类型:

long m = 67211468794645315;
int x = Convert.ToInt32(m);			//编译器报错,值对于Int32太大或太小
int y = int.Parse(m.ToString());	//编译器报错,值对于Int32太大或太小
int z = (int)m;

将大的数据类型转换为小的数据类型时,Convert.ToInt32()和int.Parse()都会报溢出错误,值对于Int32太大或太小,而(int)不报错,但是返回值为-1。
(3)转换字符串类型。

string m = "1.32";
int x = Convert.ToInt32(m);			//编译器报错,输入字符串的格式不正确
int y = int.Parse(m.ToString());	//编译器报错,输入字符串的格式不正确
int z = (int)m;						//编译器报错,无法将类型“string”转换为“int”

Convert.ToInt32()可以转换多种类型(例如非数字类型bool、DateTime等),int.Parse()只能是整型字符串类型(即各种整型ToString()之后的形式,不能为浮点型,否则int.Parse()就会出现输入的字符串格式不正确的错误),(int)只能是数字类型(如float、int、uint等)。

4.3 其他常用类型

在C#中还有许多用于设置日期和时间的方法,这些功能都是通过特定的类来生成的。

4.3.1 日期和时间

在C#中,DateTime是一个包含日期、时间的类型,此类型通过ToString()方法转换为字符串,可根据传给ToString()的参数转换为多种字符串格式。DateTime调用ToString()传入的参数可分为制式和自定义两种。
1.制式类型
制式类型就是系统自带的,传入特定的单个字符就可转换为系统已设定好的格式。

  • 符号对照表
    在调用ToString()进行转换时,许多转换方式都是通过短日期、长日期、短时间和长时间这4个分类进行组合,下表列出了制式类型对应的格式符号。
    《C#从入门到项目实践》笔记4_第9张图片
    例如:通过使用DateTime这个类来获取当前的时间,并以标准模式输出。
using System;
namespace Project
{
	class Program
	{
		static void Main(string[] args)
		{
			string dt = DataTime.Now.ToString();
			Console.Write("当前测试时间:{0}\n",dt);
			Console.WriteLine("\t{0}", DateTime.Now.ToString("d"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("D"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("f"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("F"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("g"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("G"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("t"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("T"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("u"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("U"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("m"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("M"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("r"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("R"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("y"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("Y"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("o"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("O"));
			Console.WriteLine("\t{0}", DateTime.Now.ToString("s"));
		}
	}
}

《C#从入门到项目实践》笔记4_第10张图片
本例演示了如何获取当前系统的时间,并且通过标准格式符号,输出不同格式的日期。
2.自定义格式
类型自定义格式类型是通过自由组合日期代码(y、M、d、h、m、s、f)来展示丰富的日期格式。下表列出了可被合并以构造自定义的模式。这些模式是区分大小写的。例如,识别“MM”,但是不识别“mm”。
《C#从入门到项目实践》笔记4_第11张图片
注意:用户在创建自定义模式时,长度至少为两个字符。
例如:

DateTime.ToString("d");		//返回DateTime值;“d”是标准短日期模式
DateTime.ToString("%d");	//返回月中的某天;“%d”是自定义模式
DateTime.ToString("d ");	//返回后面跟有一个空白字符的月中的某天;“d”是自定义模式

4.3.2 全局唯一标识符

全局唯一标识符(Globally Unique IDentifier),简称GUID。它的主要目的是产生完全唯一的数字。而GUID的唯一缺陷在于生成的结果串会比较大,所以在理想情况下,随机生成两个相同GUID的可能性是非常小的,但并不为0。通常平台会提供生成GUID的API。(我不理解)
1.全局唯一标识符的特点
(1)一个GUID为一个128位的整数(16字节),在使用唯一标识符的情况下,用户可以在所有计算机和网络之间使用这一整数。
(2)GUID的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个x是0~9或a~f范围内的一个十六进制的数字。例如,337c7f2b-7a34-4f50-9141-bab9e6478cc8即为有效的GUID值。
(3)世界上的任何两台计算机都不会生成重复的GUID值。GUID主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。
(4)在Windows平台上,GUID应用非常广泛,如注册表、类及接口标识、数据库,甚至自动生成的机器名、目录名等。
2.在.NET中使用GUID
当Windows开发人员需要一个唯一数值时,他们通常使用到一个全局唯一标识符。微软采用GUID术语来表示这一唯一数值,而这一数值能够标识一个实体,例如一个Word文档。
在.NET Framework中的基本System类,包括GUID数值类型。除此之外,这一数值类型包含处理GUID数值的方法。通过使用NewGuid方法允许用户很容易地生成一个新的GUID。
例如:通过使用NewGuid方法,生成一个GUID。

using System;
namespace Project
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("GUID:{0},Guid.NewGuid().ToString());
		}
	}
}

《C#从入门到项目实践》笔记4_第12张图片
本例通过调用NewGuid方法,获取一个全局唯一标识符。

4.3.3 统一资源标识符

统一资源标识符(Uniform Resource Identifier,URI)是用来标识资源名称的字符串。URI即统一资源标识符,是一个用于标识某一互联网资源名称的字符串。该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。
协议URI由3部分组成:存放资源的主机名、片段标识符和相对URI。

4.4 运算符

运算符是处理和操作数据的一种符号单元,其作用是标识出数据与数据之间的运算关系,帮助程序来操作这些数据的运算过程。
运算符,又称为操作符。在C#中有6种运算符,包括算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符和特殊运算符。

4.4.1 算术运算符

算术运算符的作用是对整数型,或者实数型变量进行各种基本的算术运算。在C#中,算术运算符包括7种,下表显示了C#支持的所有算术运算符。
《C#从入门到项目实践》笔记4_第13张图片
自增自减运算符是两个特殊的一元运算符。所谓元,是指操作数的数量,一个操作数为一元,两个操作数为两元,以此类推。
自增自减运算符除了分别进行加法运算和减法运算,还有赋值的功能,下面以自增运算符为例。
(1)后缀方式,变量先赋值再进行加法运算。
例如:

int a = 5, b;
b = a++;

该段语句表示,先把a的值赋给b,然后再对a进行自增运算。所以,最后的结果a为6,b为5。
(2)前缀方法,变量先进行加法运算再赋值。
例如:

int a = 5, b;
b=++a;

该段语句表示,先对a进行自增运算,然后再把a的值赋给b。所以,最后的结果a为6,b也为6。

4.4.2 赋值运算符

赋值运算符的作用是对常量和变量进行初始化,或者为变量赋予一个新的值。赋值运算符不仅可以在变量被声明时赋值,还可以对已经初始化的变量赋值。
如果为某个变量多次赋值,改变量的值以最新的赋值为标准。下表列出了C#支持的赋值运算符。
《C#从入门到项目实践》笔记4_第14张图片

4.4.3 关系运算符

关系运算符又称为比较运算符,其作用是对运算符两侧的表达式进行比较,获取一个比较后的结果,若成立返回逻辑真true,否则返回逻辑假false。通常作为条件分支控制语句。下表显示了C#支持的所有关系运算符。
《C#从入门到项目实践》笔记4_第15张图片

4.4.4 逻辑运算符

逻辑运算符用来连接多个bool类型表达式,实现多个条件的复合判断。下表显示了C#支持的所有逻辑运算符。
《C#从入门到项目实践》笔记4_第16张图片

4.4.5 位运算符

1.位逻辑与运算(&)
位逻辑与运算将两个运算对象按位进行与运算。与运算的规则:1与1等于1,1与0等于0,0与0等于0。
2.位逻辑或运算(|)
位逻辑或运算将两个运算对象按位进行或运算。或运算的规则是:1或1等于1,1或0等于1,0或0等于0。
3.位逻辑异或运算(^)
位逻辑异或运算将两个运算对象按位进行异或运算。异或运算的规则是:1异或1等于0,1异或0等于1,0异或0等于0。即:相同得0,相异得1。

在进行&(与)、|(或)和^(异或)运算时,如果两个运算对象的类型一致,则运算结果的类型就是运算对象的类型。例如对两个int类型变量a和b做与运算,运算结果的类型还是int型。如果两个运算对象的类型不一致,则C#要对不一致的类型进行类型转换,变成一致的类型,然后进行运算。类型转换的规则同算术运算中整型量的转换规则一致。下表列出了C#支持的位运算符。
《C#从入门到项目实践》笔记4_第17张图片
4.位逻辑非运算(~)
位逻辑非运算是单目的,只有一个运算对象。位逻辑非运算按位对运算对象的值进行非运算,即:如果某一位等于0,就将其转变为1;如果某一位等于1,就将其转变为0。
5.移位运算符
“<<”和“>>”运算符用于执行移位运算,分别称为左移位运算符和右移位运算符。对于X<>N形式的运算,含义是将X向左或向右移动N位,得到的结果的类型与X相同。此处,X的类型只能是int、uint、long或ulong,N的类型只能是int,N的类型只能是int,或者显式转换为这些类型之一,否则编译程序时会出现错误。
(1)左移位运算符(<<)。
使用左移位运算符可以将二进制数据向左移位。其作用是所有的位都向左移动指定的次数,高次位就会丢失,低位以0来填充,移位操作从不导致溢出,如下图所示。
《C#从入门到项目实践》笔记4_第18张图片
(2)右移位运算符(>>)。
右移位运算符是把二进制数据向右移位,其作用是所有的位都向右移动指定的次数。
注意:如果第一个操作数是int或uint(32位数),则移位数由第二个操作数的低5位给出,如果第一个操作数是long或ulong(64位数),则移位数由第二个操作数的低6位给出。如果第一个操作数为int或long,则右移位是算术移位(高序空位设置为符号位)。如果第一个操作数是uint或ulong类型,则右移位是逻辑移位(高位填充0),如下图所示。
《C#从入门到项目实践》笔记4_第19张图片

4.4.6 特殊运算符

和C语言相比,在C#中多了一些特殊的运算符,如typeof、is和as。下表列出了C#支持的其他一些重要的运算符。
《C#从入门到项目实践》笔记4_第20张图片
1.sizeof运算符
sizeof运算符用于获取值类型的字节大小。
注意:
(1)sizeof运算符仅适用于值类型,而不适用于引用类型。
(2)不能重载sizeof运算符。
2.typeof运算符
typeof运算符用于获得指定类型在system名字空间中定义的类型名字。
注意:(1)typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称。
(2)不能重载typeof运算符。
3.&和*运算符
(1)&运算符既可作为一元运算符也可作为二元运算符。在当作一元运算符时称为取地址运算符,用于返回变量的地址。在当作二元运算符时,对两个整型数据进行逻辑按位与操作。
(2)*运算符同样既可作为一元运算符也可作为二元运算符。在作为一元运算符时,称为取消引用运算符或者间接寻址运算符,用于对指针执行读取和写入操作。在作为二元运算符时,用于表示乘法运算符。
注意:&和*在作为一元运算符使用时,仅可用于不安全的上下文,通过使用unsafe关键字表示,并且需要/unsafe编译器选项。
在设置编译器选项时,首先在Visual Studio 2017开发环境中打开项目的“属性”页,接着单击“生成”属性页,最后选中“允许不安全代码”复选框即可。
4.is和as运算符
在C#中关于类型的判断和转换有is和as这两个操作符。
(1)is运算符用于检查变量是否为指定的类型。如果是,就返回true,否则就会返回false。
(2)as运算符主要用于在兼容的引用类型之间执行转换。如果要转换的类型与指定类型兼容,转换就会成功,如果类型不兼容,则返回null,并且不抛出异常,因此转换是否成功可以通过结果是否为null进行判断。
5.条件运算符
条件运算符“?:”是C#中唯一的一个三元运算符,其语法格式如下:

条件表达式? 表达式1: 表达式2;

该语句表示首先求出条件表达式的值(bool类型),为true时调用表达式1,为false时调用表达式2。其逻辑为“如果条件为真执行第一个,否则执行第二个”。

4.4.7 运算符优先级

运算符的优先级确定表达式中项的组合,这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。
例如,x=7+62,在这里,x被赋值为19,而不是15,因为运算符“”具有比“+”更高的优先级,所以首先计算乘法“6*2”,然后再加上7。
按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。
《C#从入门到项目实践》笔记4_第21张图片

4.5 就业面试技巧与解析

4.5.1 面试技巧与解析(一)

面试官:语句“Console.ReadLine();”的用法?
应聘者:该语句用于接收用户的输入,输入类型默认为字符串string类型。
例如:

Console.WriteLine("请问你喜欢吃什么?");
string food = Console.ReadLine();
Console.WriteLine("哈哈哈,我也喜欢吃{0}", food);

对于“Console.WriteLine();”语句来说,括号里双引号的内容可原样输出,但是转义字符及索引号“{ }”除外。
面试官:&、|、^除了用于位运算,还可以用于什么运算?请详细介绍。
应聘者:还可以用于逻辑运算,它们分别对应与、或、异或。
(1)对于bool操作数,与运算符(&)计算其操作数的逻辑AND;即,当且仅当其两个操作数皆为true时,结果才为true。
例如:

Console.WriteLine(true & false);	//返回false
Console.WriteLine(true & true);		//返回true

(2)对于bool操作数,或运算符(|)会计算其操作数的逻辑OR;即,当且仅当其两个操作数皆为false时,结果才为false。
例如:

Console.WriteLine(true | false);	//返回true
Console.WriteLine(false | false);	//返回false

(3)对于bool操作数,异或运算符(^)计算其操作数的逻辑异或;即,当且仅当其一个操作数为true时,结果才为true。
例如:

Console.WriteLine(true ^ false);	//返回true
Console.WriteLine(false ^ false);	//返回false
Console.WriteLine(true ^ true);		//返回false

4.5.2 面试技巧与解析(二)

面试官:运算符&、|的运算结果和运算符&&、||有什么区别?
应聘者:C#为整型和布尔型预定义了二进制“&”运算符。对于整型,“&”计算操作数的按位与;对于布尔操作数,“&”计算操作数的逻辑与,当且仅当两个操作数均为true时,其结果才为true。
而“&&”则是这样:条件1为false时不去理会条件2,因为即使条件2为true,结果还是false,“&”则会去判断条件2。
例如:

bool a = true;
bool b = false;
bool c = a || b;

检查第一个操作数a时已经得出c为true,就不用再处理第二个操作数b了。

你可能感兴趣的:(c#,visual,studio,unity,经验分享,面试)