C#学习笔记(一):C#与C++语法的一些不同
1,C#中没有了"::"的域操作符,全部用了"."了。但是继承还是用的":",C#的"::"是用作命名空间别名的修饰符。
2,在C#中变量使用前必须初始化,程序员显式的或者编译器自动的。其中:变量是类或者结构中的字段,如果没有显式初始化,则在默认创建这些变量的时候其值就是0。然而方法的局部变量必须在代码
中显式初始化。(这与C++中不同)。
3,例如对于下面语句:SomeType obj;在C++这个是一个值类型,会在堆栈中创建一个SomeType的实例。但是在C#中这个只会为SomeType对象创建一个引用,这个引用还没有指向任何的对象。也就不能调用它的方法。然而C#中实例化对象要使用new关键字,将对象存储在堆上。返回一个引用。
4,下面的代码:
public static in Mian()
{
int j = 20;
for (int i = 0; i < 10; i++)
{
int j = 30;
//....use value j...
}
}
与C++不同的是这个时候C#不能隐藏for循环的变量:j,前面的j还在定义域中。但是对于下面代码:
static int j = 20;
public static void Main()
{
int j = 30;
//....use j
}
这个就是可以的,这个是静态变量,但是注意静态方法中不能使用类的实例变量。
5,C#中常量总是静态的,同时不允许在常量的声明前加上static。C#中变量是值还是引用只取决于变量的数据类型,int总是值类型(除非利用装箱技术)。但是C++中显然我们可以直接选择是值还是指针访问变量。注意:string和object是引用类型。
6,C#中自定义的Struct类型就是一个值类型,而自定义的Classe类型就是引用类型。C++则无此区别。
7,C#中byte类型在默认的状态下是无符号的,有符号版本是sbyte。
8,几个表示浮点的类型:
float类型:CTS类型为System.Single,32位单精度浮点数,小数位数7位,范围大致:(+/-)1.5*10^(-45) ~ (+/-)3.4*10^38。
double类型:CTS类型为System.Double,64位双精度浮点数,小数点后15/16位,范围大致:(+/-)5.0*10^(-324) ~ (+/-)1.7*10^308。
decimal类型:CTS类型为System.Decimal,128位高精度十进制数表示法。小数点位数是28位,(+/-)1.0*10^(-28) ~ (+/-)7.9*10^28,多用于财务计算。demical不是基本类型,使用会有性能损失。decimal d = 12.30M;
9,C#的char类型是16位的(Unicode)字符。
10,关于string类型一些注意的:虽然string类型是引用类型但是有很多不同。
例如:string s1 = "aaa"; string s2 = s1; s1 = "ccc"; 这时s2并不会跟着s1的改变而改变,这点和引用类型不同的了。
字符串字面量前面可以加上@符号:就表示输出就是“”里面的内容。即使里面有个回车换行也就代表换行:
@"aa\b" 等同于 "aa\\b"
@"'asdasdfa a aggagag
fafafafa dfa"输出就是:
asdasdfa a aggagag
fafafafa dfa
11,switch...case...语句中,case后面必须是常量表达式(包括字符串常量)或枚举枚举类型。但是要注意的是:除非case语句后面处理程序是空的,否则,就一定要加上break;语句。如果case子句是空的,也可以跳到下一个语句中去。还可以用goto语句随便跳。(goto语句在C#中的switch...case...语句中跳转是个好用处)。
case "America":
do....;
goto case "Britain";
case "France":
do....
break;
case "Britain":
do...
break;
这个也是可以的。
12,foreach循环不能改变集合中各个项的值。
13,C#的数组定义是:int[] integers = new int[32];
所有的数组都是引用类型,遵循引用的语义。而数组的各个元素可以是值类型。int[] copy = integers;表示copy指向同一个数组,不是创建一个新的。
14,Console.WriteLine()的格式化输出:
int i = 900, j = 80;
Console.WriteLine("{0} plus {1} equals {2}", i, j, i + j);
也可以为值指定宽度,调整文本在宽度中的位置,正值右对齐,负值左对齐。格式{n, w}中,n为索引参数,w是宽度值。
Console.WriteLine("{0,4}\n+{1,4}\n----\n{2,4}", i, j, i+j);
15,C#中保留字前面加上@就表示是个标识符了。
16,string类型不能改变字符串的值,(如果改变就会在堆中创建一个新的字符串),所以它不同于一般的引用。所以string作参数的时候不能改变实参的。
17,ref和out的区别:
ref:可以使值类型的参数变为引用类型,void Fun(int[] ints, ref int i),调用这个方法的时候也要加上这个关键字Fun(ints, ref i)。注意:无论是值传递还是引用传递,变量实参都必须初始化的。
out:参数前面加上out的话,传递给该方法的变量可以不初始化。但是在函数中一定要给这个参数赋值,也就初始化了实参了。
18,C#的重载:
(1),不支持默认实参。
(2),两个方法不能根据返回类型区别。
(3),两个方法不能根据参数是声明为ref还是out来区分。
19,关于静态构造函数:
(1),类(不一定要静态类)可以编写静态构造函数,但是不能有任何参数。
(2),静态构造函数由.Net调用,程序员不能确定它在哪个确切时刻调用,但是它一定在程序第一次使用类之前调用,只能调用一次,如果类的静态变量有默认值,一定在调用静态构造函数之前指定。
(3),静态构造函数的一个很好的用处是:初始化静态的字段或者属性。包括常量或者只读成员。
20,C#的构造函数的初始化器只能调用构造函数(可以用this()),不能初始化变量。
21,只读变量:readonly
readonly允许把一个字段设置为一个常量,但是可以执行一些运算,确定它的初始值。只能在构造函数中给他赋值(当然声明的时候可以初始化),不能在其他地方。只读字段还可以是一个实例变量(常量const默认就只能是静态成员),在实例构造函数中初始化,这样类的每个实例都可以有不同的值。要把只读字段设置为静态必须显示的声明才行。我们没必要把只读字段或者常量设置为私有,因为它们不能在外部修改。在构造函数中如果没有给只读字段赋值它也会是其数据类型的默认值,或者声明时候的初始化值。
22,struct和class的区别:
(1),结构是值类型,类是引用类型。结构存储在堆栈中或者存储为内联,其生命周期和简单的数据类型一致的。
(2),结构不支持继承的,但是它派生于VlaueType,也就是Object类的派生类,可以继承或者重载其方法。
(3),结构的构造函数的工作方式与类不同,其中,结构的总是由编译器提供一个无参的默认构造函数,用户不能替换的,也就是说用户只能自己定义有参数的构造函数。
(4),使用结构可以指定字段在结构中的布局。
(5),例如:
Dimensions point = new Dimensions(); point.Length = 3;这里的new运算符与类类型不同,它不在堆中分配内存空间,只是根据相应的参数调用相应的构造函数。
然而对于:Demensions point; double d = point.Length;就不行了,因为这个只是在堆栈中分配了变量point的内存空间,但是没有初始化其成员,就像未初始化的成员不可访问的(可以赋值)。
(6),结构中定义的变量不能在声明时候初始化:struct Dimensions{public double Length = 1; int Width = 2;}错误的。