第一章 基础
一个 计算机程序就像时一架壮观的机器,当这架机器里的齿轮、杠杆和活塞运转起来的时候,整个房间就将充满着华丽复杂而又美妙动听的音里。我们将看到变化着的逻辑、运动着的算法和舞蹈着的数据.。
1. C#区分大小写。
变量名必须以一个字母或者下划线字符开头;变量名只能由字母、下划线字符和数字组成。
当一个 C#程序运行时,其中的声明语句将使一小块内存被专门拿出来存放有关变量的值。把这一过程称为‘给变量赋值’。
2. Main方法永远是计算机在执行这个程序时最先执行的 方法,所以人们又把Main方法称为程序的‘入口点’。
3. 经典解释:一个方法将以一些 变量的 形式获得输入,这些变量被称为这个 变量的 “输入参数”;该方法对这些变量进行有关的 处理后将输出一个结果,这个结果被称为这个方法的 “返回值”。
4. C#原代码以“.CS”作为后缀。
Joke:与其他科学相比,程序设计方面的 实验既容易进行又很安全。它绝不像化学实验那样弄不好炸掉你的房子。
=是唯一按从右向左的 顺序进行关联的 操作符,在同一表达式里的 多个赋值操作符将从表达式的最右端开始吧自己的 右操作数依次赋值给自己的左操作数。
例如:A=B=C=27;(先C,在B,在A)
第二章 基本数据类型
1.单个的字母、数字、标点符号或者其他符号成为一个“字符”(Character)
一组由文本字符构成的单词或者短语称为一个“字符串”
字符串存放在HEAP上。
C#中,结构都是值类型、类都是引用类型。
2. 空字符串: Name = “”;虽然不包含任何字符,但C#仍然会从堆里为它分配一些内存以保存与这个空字符串有关的信息。
Name = null;“null”是一个取值为0的引用指针,不从堆里分配内存。
ToString()方法:把变量转换为字符串,是一个 实例方法。
Int32.Parse():把字符串转换为整数,是一个静态方法。
3.在声明一个 常数的时候 ,你必须 给出它的 值,例如:
CONST INT A =10;
CONST STRING REPONSE = CONSOLE.READLINE(); 错误的哦
这是因为READLINE方法的 调用动作发生在程序的 运行阶段而不是程序的编译阶段,可C#只允许你使用那些能够在 编译阶段被确定下来的 值去设置一个常数。
4. 把一个带有小数部分的十进制数值直接赋值给一个 DECIMAL变量
E = 45.72 错误 E = 45.72M 正确
C#中,必须给十进制数加上一个字母“M”后缀。
5.C#是不会隐含的 把一个DECIMAL值转换为一个整数
DECIMAL A = 54.32M ; INT NUM = A ; 错误
可以进行一次显示的 类型转换,利用DECIMAL结构的 TOINT32()或者CONVERT类中的TOINT32(),最简单的 做法是使用一个强制类型转换。
NUM = A.TOINT32(); OR NUM = CONVERT.TOINT32(A) OR
NUM = (INT)A
6.DECIMAL变量使用128比特存储,96比特存储一个整数,5比特决定小数点的位置,1比特保存DECIMAL值的正负号,空26比特。(1 字节= 8比特)。
DECIMAL.TRUNCATE(VALUE)与DECIMAL.FLOOR(VALUE).比如-25.645
TRUNCATE()为-25,向0方向舍入;FLOOR()为-26,向负无穷小方向舍入。
DECIMAL.ROUND(VALUE,DIGITS) :ROUND方法的第2个参数是是INT类型,它代表你想舍入到小数点后的 第几位。
DECIMAL.ROUND(1.2885M,2) 等于1.29,对于最后一位数字是5的数值按照舍入为偶数的规则进行舍入,即舍入结果将是最接近的偶数。(8.335,2)与(8.345,2)都等于8.34
7.STATIC:表明该方法将作用于类或结构而不是作用于类或结构中的 某个特定方法。
8.在对程序进行调试或者在挑选算法时,程序员大都会吧被测试的 代码安排在MAIN方法的前半部分,把暂时不想运行的 代码安排在MAIN方法的后半部分。你可以把你不想运行的代码全部改为注释,但更简单的 办法是在这部分的 代码前面架上一条RETURN语句 ,编译器警告:UNRECHABLE CODE DELECTED
9.“一个文件只容纳一个类”的做法确实是一种非常好的 源代码管理办法。
10.同一个类里有多个方法都包含有同样或者类似的代码的现象是一个很明显的信号:应该把这些重复出现的代码拿出来另行封装。
11.数组本身就是一种“引用”类型;NEW表达式将返回一个引用(指针),它指向从堆里划分出来的内存块(数组变量本身保存的是一个指向堆的引用);C#甚至还允许你吧 明确的为数组分配内存的 NEW操作符部分省略掉——等号后面可以直接跟着用来给出数组元素初始值的花括号:
INT[] A ={4,3,2,1};
虽然无NEW,但系统还是将从堆里为这个数组分配足够的内存,但需要注意的是 :这种省略NEW操作符的做法只有在你打算在声明语句里对数组进行初始化的时候才允许。
12.CONSOLE.WRITELINE()中调用数组:平行数组使用时最重要的原则就是要保持它们之间的 “平行性”,下标保持同步增减。
13.INT A = 55; 执行完B等于55
INT B = A;
A =0; 堆栈 堆
INT[] A = NEW INT[3] {33,55,77}; A: 73645 指向 33 0 77
INT[] B = A; B: 73436 指向
A[1] = 0;
A和B将指向堆里的同一个内存块
14.NEW STRING[]{“aB”,”bB”,”CB”,”DB”} [2]
这个表达式为一个由4个字符串构成的数组分配内存,这个数组的 各个元素本身又是一个引用(指针),它们分别指向系统为存放各有关字符串而在堆中分配的内存块;【2】将选中该数组的第3个元素,整个表达式的值为“CB”
15.如果某个数组是在MAIN方法里被声明的,它的创建和初始化步骤将在程序启动时发生且仅发生一次。
反复调用一个包含数组的方法,系统反复为数组分配和释放内存过于浪费。(注意,C#不允许用 CONST去声明一个数组——只有在编译阶段被确定或计算出来的值才能被声明为常数;数组需要一个NEW操作符,而NEW操作符只有等到运行阶段才会发生),有没有高效的解决方法了?
“把变量—不管它是数组还是其他的类型—尽可能声明为局部变量”是程序设计的一个基本原则。
当需要在一个程序里频繁调用某个方法而这个方法又要用到一个其元素都是些常数的数组时,就要把那个数组搬到那个方法的外部并把它声明为一个STATIC,被声明为静态的数组在程序执行过程中只会被初始化一次。
16.INT[] A =NEW INT[2] {0,1};
A.LENGTH(等于2,LENGTH即数组里的元素个数)
17.类都是引用(指针)类型,所以类的实例都要从堆里分配内存。
18.BOOL A; A = 0;错误 只能A = false;
“true”和”false”必须写成小写的形式
19.用来存放数组元素的 内存都是从堆里 分配的 ,而堆内存又总是被初始化为0——对于数值类型的数组,这意味着数组里的各个元素的初始值都是0;
对于字符串数组,这意味着数组里的各个元素的初始值都是null;
对于布尔数组,这意味着数组里的各个元素的初始值都是false
20.德.莫干定律:
!(A|B)= !A & !B
!(A&B) = !A | !B
PleasureWeather = !IsRaining & !IsSnowing
Joke:好天气是既不下雨啊,也不下雪啊。哈哈!
21. string str = “hello,world”;
Ch = str [0]; 对char变量CH进行赋值的时候就将把字符串STR当成一个 数组对待,CH为‘H’,如果这样:
Str[0] =’h’; 编译错误
字符串的索引是只读的,事实上,一旦在程序里创建一个字符串,就不能在改变它。C#中的字符串是不可改变的,如果需要在程序里改变一个字符串,就必须编写一些代码来创建一个新字符串——对旧字符串的修改将体现在新字符串里,并且值能发生在新字符串的创建过程中。
22.千万不要吧一个字符串的索引与一个字符串数组的下标混为一谈:
String[] astr = { “bach”,”Beethoven”,”brahms”}
Astr[1]是字符串”Beethoven”,而 Astr[1][6]是字符‘V‘
23.String类不支持无输入参数的构造器
第三章 条件与循环
1.C#仍然允许在同一语句块的不同子块里使用同名的变量。
2.基本原则:当发现IF语句块和ELSE语句块里有相同的代码时,就应该尽可能的把这些相同的代码挪到IF语句的外部去。
尽量减少IF语句块里的代码的好处:如果这个语句块里只有一条语句,就可以省略花括号。例如 :
If (mSales>10000)
mBounds =1000;
else
mBounds = 0;
2.在对程序进行测试时,一定要对边界值—即程序行为将在那一点发生变化(不管这种变化有多么细化)的数值—进行检查。
最后一个教训:把程序设计要求写成书面文字,当你的老板说 “我说过。。。。。。”
的时候,你得拿出一份书面的东西来证明“不,你没说过”(hahaha..)
3. else
If → else if 由来
4.有时候,刚写出IF语句里的布尔表达式,就发现自己吧顺序弄反了——该IF语句的 ELSE部分应该在那个布尔表达式为TRUE时得到执行。此时,你不必去改变代码的排列顺序,只要把那个布尔表达式用圆括号括起来,再在它的前面加上一个逻辑非操作符(“!”)就行了。
5.三元操作符: bExpression ? A:B
bExpression为真,条件表示的结果为A,反之为B
A和B必须是同一类型(或能被隐含地转换为同一类型)的表达式。
bExpression ? 29:28
6.break语句,执行后程序将跳出while循环并去执行紧跟在它后面的语句。
Continue语句,作用使程序跳过循环体中的后续语句而直接进入下一次循环。
7.While循环采用了人们在对数组进行处理时的“标准“流程结构——先把数组下标初始化为0,在把下标值与数组长度进行比较,在后在while循环的 末尾再对下标值进行递增。
Int I = 0;
While (I < array.length)
{……………………
i++;
}
8. try{
dvalue =Double.Parse(Console.Readline());
}catch{
dvalue = Double.NaN;
}
对dvalue变量的声明和赋值是在两个地方进行的。如果把Dvalue变量声明在TRY语句块里,TRY语句块外的代码就不能使用这个变量。
9.一旦执行了某个方法中的THROW语句,这个方法就结束了——跟在THROW语句后面的语句将不会执行。
IF ….THROW()…
ELSE… 无意义
把想在异常没有发生时执行的代码直接写在“IF.THROW.”语句的后面就行了
If … throw()…
//未发生异常时执行的语句
10.FOR语句中的步长表达式,通常是一个FOR循环在每次循环结束之前将要执行的最后一条语句。
For(;;) 等价于无限循环 while(true)
{ {
} }
C#允许在FOR语句的初始化表达式里对多个变量进行初始化,但是这些变量必须是相同的类型,而且必须把类型名字写在最前面。