c#语言学习笔记(1)
环境:VS Express 2013 for Desktop 也可以vs社区版,不过学习的话,Express本版做一些小的上位机工具应该是够用了
学习的网站:https://www.runoob.com/csharp/
c#是微软开发的,面面相对象的编程语言,再加上微软的ide,开发起来效率比较高,适合个人维护(知乎上说的),感觉和c语言有点相似。
VS Express 2013 for Desktop 可以开发vb,vc#,vc++,比Microsoft Visual C# 2010强大多了。两者同样都是免费的,win7就安装Microsoft Visual C# 2010
新建工程后,
默认开头就有以下代码,类似于c++的using namaspace std
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
以下是学习的笔记
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; //一般在程序开头添加 using System;,这时 string 相当于 System.String 。 namespace csharphello { class Program { } } //namespace HelloWorldApplication //{ // class HelloWorld // { // static void Main(string[] args) // { // /* 我的第一个 C# 程序*/ // Console.WriteLine("Hello World"); // Console.ReadKey(); // } // } //} namespace RectangleApplication { class Class1 { } class Class2 : Class1 //类Class2是类Class1的子类 { } class Rectangle { // 成员变量 double length; double width; public void Acceptdetails()//一个用来赋值的方法 { length = 4.5; width = 3.5; } public double GetArea()//一个用来计算的方法 { return length * width; } public void Display()//一个用来打印的方法 { Console.WriteLine("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {0}", GetArea());//打印GetArea方法的计算结果 } } class ExecuteRectangle { static void Main(string[] args)//程序入口方法,创建实例,调用相应的方法 { Rectangle r = new Rectangle(); //类的实例化 r.Acceptdetails();//其实是用来声明前面 Acceptdetails() 和 Display()。 r.Display(); /*当 WriteLine() 函数有多个参数时,输出第一个参数中的内容, * 而第二个参数中的内容替换掉第一个参数中对应位置的占位符一起输出. * 如果第一个参数没有留占位符,那么第二个参数内容不输出. * static void Main(string[] args) { Console.WriteLine("A:{0},a:{1}",65,97); Console.ReadLine(); } 运行结果: A:65,a:97 当 WriteLine() 函数有多个参数时,输出第一个参数中的内容,而第二个参数中的内容替换掉第一个参数中对应位置的占位符一起输出。 如果第一个参数没有留占位符,那么第二个参数内容不输出. Console.WriteLine("A:,a:",65,97); 运行结果: A:,a: 占位符从零开始计数,且占位符中的数字不能大于第二个参数的个数减一(要求占位符必须有可替换的值). 占位符数字与第二个参数字符位置一一对应. static void Main(string[] args) { Console.WriteLine("A:{1},a:{0}",65,97); Console.ReadLine(); } 运行结果: A:97,a:65 * / /* * 隐式转换:C# 默认的以安全方式进行的转换。 * 本质是从小存储容量数据类型自动转换为大存储容量数据类型, * 从派生类转换为基类。 */ int inum = 100; long lnum = inum; // 进行了隐式转换,将 int 型(数据范围小)数据转换为了 long 型(数据范围大)的数据 Class1 c1 = new Class2(); // 这里也是隐式转换,将一个新建的 Class2 实例转换为了其基类 Class1 类型的实例 C1 Class1 c11 = new Class1(); //Class2 c22 = c11 as Class2; //使用as进行显式转换 Class2 c22 = new Class2(); Console.WriteLine(c11 is Class1); Console.WriteLine(c22 is Class2); //类型之间的转换 - Convert 和 Parse string locstr = 123.ToString(); Console.WriteLine(locstr); //如果要将"locstr"转成整型数 //方法一: 用 Convert int i16 = Convert.ToInt16(locstr); //方法二: 用 Parse int ii = int.Parse(locstr); Console.WriteLine(i16); Console.WriteLine(ii); /* int.TryParse(string s,out int i) * 该方式也是将数字内容的字符串转换为int类型, * 但是该方式比int.Parse(string s) 好一些, * 它不会出现异常,最后一个参数result是输出值, * 如果转换成功则输出相应的值,转换失败则输出0。 */ string s1 = "abcd"; string s2 = "1234"; int a, b; bool bo1 = int.TryParse(s1, out a); Console.WriteLine(s1 + " " + bo1 + " " + a); bool bo2 = int.TryParse(s2, out b); Console.WriteLine(s2 + " " + bo2 + " " + b); int aa = 9; object obj; obj = aa; obj = 10; Console.WriteLine("2: {0}", aa); // 输出:2: 9 Console.WriteLine("1: {0}", obj); // 输出:1: 10 /* * 关于值类型、引用类型以及“栈”跟“堆”的关系 * 值类型,声明一个值类型的时候,是在“栈”中开辟一个内存空间来存放对应的值, * 当值类型的值发生改变的时候,则直接修改该内存空间所保存的值。例: */ int n1 = 5; int n2 = n1; Console.WriteLine(n1 + " "+ n2); // 5 5 n2 = 7; Console.WriteLine(n1 + " " + n2); // 5 7 /* * * 这里首先在“栈”中开辟一个内存空间用来保存 n1 的值 5, * 接着再在“栈”中开辟一个新的内存空间用来保存 n2 的值 5, * 所以显示出来的结果是 5 5。然后将 n2 在“栈”中对应的内存空间保存的值修改成 7, * 故显示出来的结果是 5 7。引用类型,声明一个引用类型的时候, * 首先是在“堆”中开辟一个内存空间来存放对应的值, * 然后在“栈”中开辟一个内存空间用于保存在“堆”中开辟的内存空间的地址。 * 当系统调用引用类型的时候,首先去“栈”中获取到地址, * 然后根据地址在“堆”中找到对应的内存空间来获取到对应值。 * 像数组这样的引用类型 */ string[] a1 = new string[] { "a", "b", "c" }; string[] a2 = a1; for (int i = 0; i < a2.Length; i++) { Console.Write(a2[i] + " "); //a b c } a1[2] = "d"; Console.WriteLine(); //换行 for (int i = 0; i < a2.Length; i++) { Console.Write(a2[i] + " "); //a b d } /* * 这里首先是在“堆”中开辟一个内存空间(假设:0X55)用来保存数组a1的值, * 然后在“栈”中开辟一个内存空间(a1)用于保存地址 0X55。当将 a1 赋给 a2 时, * 是将地址赋给 a2,即在“栈”中开辟一个内存空间(a2)用于保存地址 0X55, * 所以输出 a2 的值是 a b c。当将 a1[2]修改成”d”的时候, * 修改的是“堆”中 0X55 内存空间保存的值, * 因为 a2 的地址和 a1 的地址一样,所以输出结果是 a b d。 * 而 string 是一个特殊的引用类型,先看下面代码: */ string ast = "123"; string bs = ast; Console.WriteLine(ast + " " + bs); //123 123 bs = "456"; Console.WriteLine(ast + " " + bs); //123 456 /* * C# 中对 double 类型的数据取整,可以使用 convert.toint32() 方法, * 也可使用 int 强制转换为整数,使用 int 时并不存在四舍五入的情况,而是直接将后面的小数位数丢掉。比如: * * 如此可见,我们在进行数据转换前选择转换方法要谨慎,如果是数字类型可以考虑直接用(int)强制转换, * 如果是整型字符串类型的,考虑用 int.Parse() 进行转换,如果不是这两种类型, * 再考虑用 Convert.ToInt32() 进行转换。 */ double da = 1.35; double db = 1.65; int ua1 = Convert.ToInt32(da); int ua2 = (int)(da); int ub1 = Convert.ToInt32(db); int ub2 = (int)(db); Console.WriteLine("{0}使用convert方法转化的结果为:{1}", da, ua1); Console.WriteLine("{0}使用int强制转换的结果为:{1}",da, ua2); Console.WriteLine("{0}使用convert方法转化的结果为:{1}", db, ub1); Console.WriteLine("{0}使用int强制转换的结果为:{1}", db, ub2); //ua1 = int.Parse("4.5"); //能编译,但是运行出错 Console.WriteLine(ua1); //a b c string stra = "123"; // 将stra设置为字符串“123” int intx = int.Parse(stra); // 转换 Console.WriteLine(intx); //a b c try { Console.WriteLine("输入数字,将计算出它加一的答案"); intx = int.Parse(Console.ReadLine()); //有可能会抛出异常 Console.WriteLine("答案是{0}", ++intx); //如果没有异常,程序才会进入这一步 } catch (Exception) { Console.WriteLine("无法转换"); //如果捕获到异常,就说“无法转换” } Console.ReadKey(); //Console.ReadLine(); } } }