复习:强弱类型
数值(numeric)类型分为整数和小数。
1)整数
根据“最多能够存储的数值大小”,将整数分为:
但是,除了byte,short/int/long都是既能存正数,也能存负数,所以需要额外占用一位(格)来存正/负符号,所以他们的存储范围是 -2^(n-1) 到 2^(n-1)。
可以直接通过类型.MinValue或MaxValue查看:(Java不能直接这样操作,详见包装类型)
short.MinValue short.MaxValue
超过最大存储数值的赋值会报错:
byte b = 255; //OK byte b = 257; //报错 short s = 257; //OK
我们实际开发中,最常用的是int类型;I/O文件流时,会使用到byte。
注意:区分"32"和32,有引号(“”)和没引号
2)小数
计算机中小数的存储比整数麻烦一些,但大体上来说,小数也可以说是“按能存储的数值的大小”区分:
但是,对于小数来说,存储容量不仅仅可以决定存储数值的大小,还可以决定存储数值的“精度”(小数点后位数)。
@想一想@:0.000000001虽然很小,但是不是和存储1000000000这种很大的数一样,需要很大的存储空间?
一般场景(默认)我们使用double就OK啦:
float score = 85.5F; //不要忘了F后缀 double avgScore = 92.32345; //可以不要后缀
小心精度问题,(复习:0.1+0.2==0.3),对比:
float fee = 98.000000000006F; double fee = 98.000000000006; Console.WriteLine(fee);
C#中写作bool,Java中boolean:值只能是true/false,(和JavaScript不同)不能是1/0啥的……
char source = '源'; string welcome = "源栈欢迎您";
相关(近似,比如数值类型)间可以有:
int age = 23; long lage = age; //int可隐式转换成long char yuan = '源'; int iYuan = yuan; //char对应的是字符编码复习:编码
short sAge = (short)age; //int转换成short需要显式转换,注意可能有“精度”损失 //string strAge = (string)age; //无法在“大类”之间进行强制转换
注意:
double fee = 98.6; Console.WriteLine((int)fee); //98:小数转整数还好 int big = 986217324; Console.WriteLine((short)big); //31596:整数转整数就崩了……因为转换是在二进制层面进行的,然后再由二进制再转成十进制。
另:在完全不兼容类型间转换,需要使用类库函数,详见后文:C#/Java/JavaScript
需要注意的是:整数除以整数,结果还是整数。要想结果为小数,除数或被除数,至少要有一个是小数:
Console.WriteLine(12 / 5); //结果为2 Console.WriteLine(12F / 5); //结果为2.4 Console.WriteLine(12 / 5F); //结果为2.4
bool result = "3" > 2; //报错 bool result = 3.5M > 2.2; //报错
bool easier = 1.5/0.5 > 0.5/0.3;
Console.WriteLine(1 || 0); //报错
|和&只能用于int值(???)
//位或可以应用于整数和bool值 Console.WriteLine(1 | 0 ); Console.WriteLine(2 | 4); /*猜一猜结果是多少?*/
选择运算符(?:)只能用于赋值,不能用于其它。
拼接(+):除了可以拼接字符串,还可以拼接字符串和其他类型变量(如整数/小数/布尔值)
强类型语言在声明一个数组(变量)时必须指定其类型。数组中能存放元素类型决定了数组类型,如:
double[] scores; //注意这个方括号([]),一个double类型数组一经声明,该数组里的所有元素都只能是这种类型的数据。
数组变量本身(不是其元素)需要被赋值后才能使用:
double[] scores; //1、这就是在使用未被赋值的scores了 //2、这不是在给scores赋值,是在给scores[0]赋值 scores[0] = 100;
和我们之前学习的变量赋值使用“字面量”不同,数组的值需要
double[] scores= new double[3]; //[3]是必须的,指定了数组的长度Length(元素个数)
这时候,数组仍然是“空”的。
注意:两种“空”是不一样的
double[] scores; //null:变量中没有存储任何东西 names = new double[5]; //empty:变量里已经“有”了一个数组,只是数组中每个元素都是空的
断点演示:watch null和double[3]
这样初始化之后,数组里的每个元素都有一个默认值(数值:0,bool:false,字符串:null)
还可以在初始化的时候指定数组元素的值:
double[] scores = new double[] {98, 68, 89.5 };//没有指定数组元素个数
上述写法还可以进一步简化:(语法糖,new的过程并未省略)
double[] scores = { 98, 78, 85.5 }; //仅在给数组赋值时使用
当超过数组最大下标,使用一个数组中元素时,就会报数组越界错误:
注意这就是运行时(runtime)错误,对比:编译时(compile)错误
面向对象中函数被称之为方法method,定义略有不同
必须声明在class中,比如Program{}(不是Main(){}中):
static double min(double[] scores) { return -1; }
PS:同学们先不要管这个static,直到我告诉大家它是什么之前,所有方法都先加上这个关键字
方法的返回类型和方法名都只能有一个而且必须有一个,参数可以没有,也可以有多个
强类型语言,返回值的类型必须和方法签名中返回类型一致,比如这样是不行的:
除非方法返回类型设置为void,否则方法体中 至少 会有一条return语句。
当方法体中出现 if...else 之类的分支,要确保所有code path(分支)都有return语句。
static double min(double[] scores, bool first) { if (first) { return -1; } //报错:if有返回值了,else呢? }而且这是 编译时 审查,你可以理解成“形式”检查。即哪怕这个分支永远永远都不会进入,它也要有一个return语句:
static double min(double[] scores, bool first) { int i = 10; if (i > 5) { return -1; } //哪怕i=10,10总是大于5,仍然报错! }PS:如果不是使用变量 i,直接 if(10>5)或者const int i=10,就可以编译通过,因为常量和字面量会在编译时直接处理,得出10>5永远为true,就不会将其视为一个分支。
方法调用的位置和变量一样,现在我们都在Main(){}中进行调用。
复习/介绍快捷键:F11 / Shift+F11
传递参数时,需要匹配方法声明中参数的
提醒:非常重要,是接下来学习“面向对象”的基础
多快好省!前端后端,线上线下,名师精讲
更多了解 加: