启动Visual Studio 2012 —— 新建项目 —— 生成可执行文件 —— 开始运行
namespace ch1yx1
{
class yx1
{
static void Main(String[] arge)
{
Console.WriteLine("Hello worder"); //这条是输出语句,括号里面的是输出的内容
Console.ReadLine();
}
}
}
namespace(命名空间)是C#组织代码的方式,它的作用类似于java中package包。
在java中如果导入其他包,应该使用import关键字。在C#中实验、使用using来引用其他命名空间,它的作用和java中的import类似。
和java一样,C#也是面对对象的一门语言,使用class关键字表示类。我们编写的代码都包括在一个类里面,类要包含在一个命名空间中。
C#中的Main方法和java中放入main方法是一样的,是程序运行的入口,应用程序从这里运行开始,注意!C#中的Main方法首字母必须大写,Main方法的返回值可以是void或者int类型,C#中Main方法有四种:
static void Main(string[] args) {}
static void Main() {}
static int Main(string [] args) {}
static int Main() {}
onsole.Write(); //这是输出语句,
Console.WriteLine(); //这是输出语句,这个多了一个Line,作用是换行和java中ln一样
Console.ReadLine(); //这是控制台输入string类型
java与C#的对比:
java | C# |
---|---|
java使用包package | C#使用命名空间namespace |
引入空间的关键字import | 引入空间的关键字using |
程序入口main一种形式 | C#四种形式Main方法 |
常用数据类型 | java | C# | 举例 |
---|---|---|---|
整型 | int | int | 年龄 |
浮点型 | float | float | 成绩 |
双精度型 | double | double | 圆周率 |
字符串型 | String | string | 姓名 |
布尔型 | boolean | bool | 是否是少数名族 |
语法:数据类型 变量名称;
C#的命名规则:
只能以字母下划线开头。
不能是C#中的关键字,$是不能在C#中使用的。
语法:const 数据类型 常量名称 = 值;
例如:public const int dayMax = 7; //定义常量dayMax
常量就是在程序运行过程中保持不变的值。
常量命名规范:
常量命名最好大写字母开头,右边要有简单的注释
常量名称不要超过25个字符。
一般什么时候使用常量:用于在程序中被经常引用的值。
namespace ch1yx4
{
class yx4
{
static void Main(string[] args)
{
string course = "C#";
Console.WriteLine(course);
Console.WriteLine("我的课程名称是:" + course);
Console.WriteLine("我的课程名称是:{0}", course);
}
}
}
{0}这个是占位符,里面有多少个占位符,就要有多少个变量,占位符从0开始,跟数组下标一样
语法:Console.ReadLine(); //Read是读的意思
这里出来一个强转的属性:数据类型.Parse();这个只能吧string类型转为int整型。
namespace ch1yx5
{
class yx5
{
static void Main(string[] args)
{
Console.WriteLine("请输入姓名:");
string name = Console.ReadLine();
Console.WriteLine(name + "您好!");
Console.WriteLine("请输入年龄:");
int age = int.Parse(Console.ReadLine());
Console.WriteLine("学员姓名:{0},年龄:{1}", name, age);
Console.ReadLine();
} //输出不管是使用加号好是格式字符串都可以。
}
}
语法:
访问修饰符 返回值类型 方法名(参数列表)
{
//方法的主体
}
public void Name()
{
//主体
}
跟java一样,在比喻一下动物是一个类,狗狗是类里面的实例,狗狗就是对象。
访问修饰符 class 类名
{
//类的主体
}
在java中的类中包括属性和方法,属性:用来描述类的特征,方法来描述类的行为。
C#在类中包含字段、属性和方法,每个类可以使用访问修饰符来设置该类的访问权限。
namespace ch1yx6
{
public class Student
{
public string name;
public int age;
public void Show()
{
Console.WriteLine("学员姓名:{0},年龄:{1}", name, age);
}
}
class yx6
{
static void Main(string[] args)
{
Student stu = new Student();
Console.WriteLine("请输入姓名:");
stu.name = Console.ReadLine();
Console.WriteLine("请输入年龄:");
stu.age = int.Parse(Console.ReadLine());
stu.Show();
}
}
}
C#有三种注释:
文档注释:///
多行注释:块注释:/* */ 单行注释://
折叠注释:#region
#endregion
程序调试常用的快捷键:
F5:开始调试
Shift+F5:停止调试
F9:设置或取消断点
Ctrl+F9:取消断点
F10:单步执行
F2:转到所调用过程或变量的定义
Ctrl+F2:将焦点转移到类的下拉类表框
跟java里面的if结构一样,就不多解释了,可以去看看我前面的博客,里面有if选择结构的详细介绍。
C#里面的switch与java有什么不同呢?第一个不同,java里面可以省略break,C#必须要,不然报错。其他的就都一样了。
语法:
数据类型[] 数组名; //不和java一样,C#中[]不能改变位置
using System;
namespace yx3
{
class Program
{
static void Main(string[] args)
{
int[] arr1 = new int[] (0, 1, 2, 3,4);
int[] array = new int[5] { 0, 1, 2, 3, 4 };
int[] arr2 = (0, 1, 2, 3, 4);
Console.WriteLine("数组 array 的元素个数是 {0}",array.Length);
Console.WriteLine("数组 array 的元素个数是 {0}", arr1.Length);
Console.WriteLine("数组 array 的元素个数是 {0}", arr2.Length);
}
}
}
获得数组的长度:
语法:
数组名.Length[下标] //下表都是从0开始,在C#把它叫做索引
语法:
数组名[下标]
在前面java中也学过,想看的话去前面看看吧,都写了,下面这个代码给你们看看:
using System;
namespace yx4
{
public class Student
{
public string name; //姓名
public double score; //成绩
public void shohwInfo()
{
Console.WriteLine(name + "\t" + score);
}
}
class Program
{
static void Main(string[] args)
{
//定义对象数组
Student[] dd = new Student[3];
dd[0] = new Student();
dd[0].name = "张浩";
dd[0].score = 100;
dd[1] = new Student();
dd[1].name = "李成";
dd[1].score = 99;
dd[2] = new Student();
dd[2].name = "蒋毅";
dd[2].score = 95;
Console.WriteLine("前三名学员信息为:");
foreach (Student stu in dd) ;
{
stu.showInfo();
}
Console.WriteLine("Hello World!");
}
Console.ReadLine();
}
}
Student[] dd = new Student[3];定义了一个Student类型的对象数组,其长度为3,包含三个对象,每个元素类型都是Student。
循环结构也和java相同,三个while,do——while,for,但是C#比java多了一个foreach,:
语法:
foreach(元素类型 元素变量名 in 数组)
{
//代码块
}
语法中的“元素”是一个只读变量。
foreach结构的执行过程是循环体依次取出数组中的每一个元素,然后对每个元素都执行一次循环操作。
using System;
namespace yx7
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入一个字符串:");
string line = Console.ReadLine();
foreach(char c in line)
{
Console.WriteLine(c);
}
Console.ReadLine();
}
}
}
除了在switch中使用之外,也可以用于for,while,do——while,foreach的循环结构中。还记得break是结束循环的,是结束当前循环,进入下一个循环结构。
continue语句与break相似,也可以用于for,while,do——while,foreach的循环结构中。但continue的作用是,退出本次循环,进入下一次循环。
差不多跟java相似。
using System;
namespace yx9
{
class Program
{
static void Main(string[] args)
{
int i, j;
//外层循环行数
for(i = 1; i <= 5; i++)
{
//内层循环控制每行打印的个数
for(j = 1; j <= i; j++)
{
Console.Write(j);
}
Console.WriteLine();
}
Console.ReadLine();
}
}
}
这就是二重循环,其实也就跟java一样两个for循环,外面的for循环是循环次数,里面的是每次的循环个数。下面就是输出的样子了,是不是觉得和神奇。
只要弄清楚问题的关键是每层循环都控制什么,循环条件是什么。外层循环一遍,里面就要从头到尾都要循环一遍。
冒泡排序的过程跟他的名称一样,把较小的气泡比较数字,排序的过程就是气泡不断向上冒泡,的过程,越小的数冒的越高。从最小的开始,然后数字越来越大。排序的过程就是比较相邻的连个数进行交换,直到所有的数都比较过并排好序。
了解一下,现在有五个数32、43、54、23、21,使用冒泡排序,下代码:
using System;
namespace yx10
{
class Program
{
static void Main(string[] args)
{
int[] score = new int[5];
int i, j;
int temp;
Console.WriteLine("请输入五位成员的成绩");
for(i = 0;i < score.Length - 1; i++)
{
//将最大元素交换到最后
for(j = 0;j < score.Length - 1; j++)
{
if(score[j] > score[j + 1])
{
//交换元素
temp = score[j];
score[j] = score[j + 1];
score[j + 1] = temp;
}
}
}
}
}
}
冒泡排序速记口诀:N个数字来排队,两两相比小靠前。外层循环N-1,内层循环N-1-i。如果要降序排序,只要把大于号换成小于号就行了。
在java中我们就已经学过一个访问修饰符public(公共的),接下来,我们要又认识另一个修饰符private(私有的),那他们有什么区别呢,比如任何人都可以去餐馆进餐,但餐馆的厨房却是重的,所有客人都不能进去,只有餐馆工作人员可以,这种环境下,餐馆餐厅就是public,而厨房就是private。每个访问修饰符只能为紧随其后的成员指定特定的访问权限。
访问修饰符 | 访问权 | 访问级别 |
---|---|---|
public | 不受任何限制 | 最高 |
private | 只有类的内部可以使用 | 最低 |
using System;
namespace yx
{
class Student
{
private string _name;
public int _age = 19;
public string _cardID = "110882198110225476";
}
class Program
{
static void Main(string[] args)
{
Student student = new Student();
student._name = "灰太狼";
}
}
}
里面的_name不能被赋值,因为他是private私有的,不能被访问。
this是表示访问当前类的属性或方法,可以解决成员变量的冲突。this不能再static静态属性中使用。this光健字可以区分局部变量和成员变量。
using System;
namespace yx3
{
class Program
{
class Student
{
private string _name;
private int _age;
public string _cardID;
public int GetAge()
{
return this._age;
}
public void SetAge(int age)
{
if(age < 0 || age > 100)
{
this._age = 19;
}
else
{
this._age = age;
}
}
}
static void Main(string[] args)
{
Student student = new Student();
student.SetAge(-10);
Console.WriteLine("年龄是:{0}", student.GetAge());
student.SetAge(25);
Console.WriteLine("年龄是:{0}", student.GetAge());
Console.ReadLine();
}
}
}
如果age的值小于0或大于100,那么就会赋值为19,当将SetAge()方法参数设置为25时,程序输出的结果则是25.从输出的结果可以看到问题得到了解决。但是要两个个用方法SerAge()和GetAge。通过SetAge()方法验证用户的输入是否合法,执行GetAge()方法输出当前对象的年龄。
相对调用方法设置获得类的私有字段值来说,属性,使用get和set访问器可以轻松地完成字段的赋值和读取。
在C#中,字段通常是私有的。如果要访问其他类里面的字段,需要通过get和set访问器实现,这种结合了字段和方法的实现方式我们称之为属性(property)。
语法:
private string _name;
public string Name
{
get{return _name;} //get访问器用来返回相应的私有字段的值,get访问器与方法相似
set{_name = valie;} //set访问器用来设定相应的私有字段的值 set访问器类似于返回类型为void的方法。
}
using System;
namespace yx4
{
class Student
{
private string _name = "灰太狼";
private int _age;
public string _caidID;
public int Age
{
get
{
return _age;
}
set
{
if(value < 0|| value > 100)
{
_age = 19;
}
else
{
_age = value;
}
}
}
}
class Program
{
static void Main(string[] args)
{
Student student = new Student();
student.Age = -20;
Console.WriteLine("年龄是:{0}", student.Age);
student.Age = 40;
Console.WriteLine("年龄是:{0}",student.Age);
}
}
}
定义类中的一个属性时,属性的数据类型必须与他所访问的字段类型一致。
属性的访问类型:
只读属性:只包含get访问器
只写属性:只包含set访问器
读写属性:包含get和set访问器
get和set的灵活运用,可以保障类中字段的安全,在类私有字段命名时,要以下划线开头,使用帕斯卡命名法。
对象初始化器:
Student student = new Student();
student.Age = -20;
这就是初始化,要是有很多的话,可以用逗号隔开。
Student student = new Student(){Age = -20};
这样可以将内部细节隐藏。
比如去银行取钱把,你去取钱只要把密码和取款金额输入就好了,这就是只写,然后你看得到的比如提取成功,这就是只读,你那ATM机里面提钱的过程是你不知道的,这就是封装,把过程隐藏。
封装是将数据和操作方法保存在一起的技术,或是有选择的隐藏或公开类中的属性和方法的过程。
using System;
namespace yx5
{
class Pay
{
public void Inputpay()
{
int pay;
float taxRate = 0.5f;
float afterTax;
Console.WriteLine("请输入税前工资(元)");
pay = int.Parse(Console.ReadLine());
afterTax = GetPay(pay, taxRate);
Console.WriteLine("税前工资:{0},税后工资:{1},", pay, afterTax);
}
public float GetPay(int pay, float taxRate)
{
float afterTax;
if(pay <= 3500)
{
afterTax = pay;
}
else
{
afterTax = pay - (pay - 3500) * taxRate;
}
return afterTax;
}
}
class Program
{
static void Main(string[] args)
{
Pay pay = new Pay();
pay.Inputpay();
}
}
}
把值传到方法里面,如果在被调用的方法中对参数的值进行了修改,在方法调用之后,参数还是原来的值。
using System;
namespace yx6
{
class Program
{
public void InputDate()
{
int num1, num2;
Console.WriteLine("请输入两个数字:");
num1 = int.Parse(Console.ReadLine());
num2 = int.Parse(Console.ReadLine());
Console.WriteLine("交换前两个数为:{0}和{1}", num1, num2);
Swap(ref num1, ref num2);
Console.WriteLine("交换后两个数为:{0}和{1}", num1, num2);
}
public void Swap(ref int num1,ref int num2)
{
int temp;
temp = num1;
num1 = num2;
num2 = temp;
}
static void Main(string[] args)
{
Program pr = new Program();
pr.InputDate();
}
}
}
使用ref修饰参数后后,在Swap()方法中交换了num1和num2的值,在Main方法中输出这两个数。
进行一个总结,打个比方,我有一个doc文档,我的同事需要我这个文档,我发给他,他在自己电脑上修改,我的不会变,这就是值传递,
同事通过网络访问我的计算机去修改,在进行修改保存的时候里面的内容就会改变,这就是引用传递。
值传递试将变量的值复制一份传递给对方,使得该方法的形参和实参的值相同在调用方法中修改形参也只是对实参复制的数据做更新,并没有改变实参的值。
引用传递是将要传递的对象的引用复制给对方的形参,使得被调用的方法直接对引用对象进行更改,会影响实参原来的值。
C#中有一个专门处理字符串的类String,它位于System命名空间中。我们一直使用的string不过是String的一个别名,就好比你的一个名字,到哪里都能用,在家里家人叫你的小名,都一样都是叫你,但是在外面就不一样了,别人不知你的小名,string就是String在C#里面的外号。在C#中两个使用都是一样的。
方法 | 说明 |
---|---|
bool Equals(string value) | 比较一个字符串与另一个字符串value的值是否相等,如二者相等,则返回true;若不相等则返回false。 |
int Compare(string strA,string strB) | 比较两个字符串的大小关系,返回一个整数。若strA小于strB,则返回值小于0;若strA等于strB,则返回值为0;若strA大于strB,作为返回值大于0 |
int LndexOf(string value) | 获取指定的value字符串在当前中第一个匹配项的位置。如果找到了value,就返回它的位置,如果没找到,就返回-1. |
int LastLindexOf(string value) | 获取指定的value字符串在当前中最后一个匹配项的位置。如果找到了value,就返回它的位置,如果没找到,就返回-1. |
string Join (string separator,string[] value) | 把字符串数组value中每个字符串用指定的分隔符separator连接返回连接后的字符串 |
string[]Split(char separator) | 用指定的分隔符separator分割字符串,返回分割后的字符串数组 |
string Substring (int startIndex,int length) | 从指定的位置startIndex开始检索长度为length的子字符串 |
string ToLower() | 获得字符串的小写形式 |
string ToUpper() | 获得字符串的大写形式 |
string Trim() | 去掉字符串前后两端多余的空格 |
String类另外两个常用的方法join()和Split()方法,他们的功能分别是连接和分割字符串。
using System;
namespace yx2
{
class Program
{
static void Main(string[] args)
{
string inputString;
string[] splitStrings;
string joinString;
Console.WriteLine("请输入一串字符,用空格分割单词:");
inputString = Console.ReadLine();
splitStrings = inputString.Split(' ');
Console.WriteLine("\n分割后的字符串:");
foreach(string s in splitStrings)
{
Console.WriteLine(s);
}
joinString = string.Join("_", splitStrings);
Console.WriteLine("\n连接后的新字符串为:{0}", joinString);
Console.ReadLine();
}
}
}
就是一个分割,一个连接字符串,很简单。
语法:
String myString = String.Format("格式字符串",参数列表);
{索引[,对齐] [:格式字符串]}
字符 | 说明 | 示例 | 输出结果 |
---|---|---|---|
C | 货币格式 | String.Format("{0:C3}",2000) | ¥2 000.000 |
D | 十进制格式 | String.Format("{0:D3}",2000) | 2000 |
F | 小数点后的位数固定 | String.Format("{0:F3}",2000) | 2000.000 |
N | 用逗号(,)隔开的数字 | String.Format("{0:N}",250000) | 250,000 |
P | 百分比计数法 | String.Format("{0:P3}",0.29768) | 29.768 |
X | 十六进制格式 | String.Format("{0:X000}",12) | C |
隐式类型转换:对于任何数值类型A,只要其取值范围完全包括在类型B的取值范围内,就可以隐式转化为B,也就是说,int型可以隐式转换为float型或double型,float型可以隐式转换为double型。
显示类型转换:当要把取值范围大的类型转换为取值范围小的类型时,就需要执行显式转换。
1、字符串转换为数值型
接收整型代码
int.Parse(Console.ReadLine());
转换为整型:
int.Parse(string);
转换为单精度浮点型:
float.Parse(string);
转换为栓精度浮点型:
double.Parse(string);
int age = 18;
string myage = age.Tostring();
方法 | 说明 |
---|---|
Convert.ToInt32() | 转换为整型 |
Convert.ToSingle() | 转换为单精度浮点型 |
Convert.ToDouble() | 转换为双精度浮点型 |
Convert.ToString() | 转换为字符串 |
using System;
namespace yx4
{
class Program
{
static void Main(string[] args)
{
double myDouble = 85.63;
int myInt;
float myFloat;
string myString;
Console.WriteLine("原始数值为:double类型:{0}",myDouble);
myInt = Convert.ToInt32(myDouble);
myFloat = Convert.ToSingle(myDouble);
myString = Convert.ToString(myDouble);
Console.WriteLine("转换后:");
Console.WriteLine("int\t float \t string");
Console.WriteLine("{0}\t {1}\t {2}", myInt, myFloat, myString);
Console.ReadLine();
}
}
}
---------------: | :----------------: |
| Convert.ToInt32() | 转换为整型 |
| Convert.ToSingle() | 转换为单精度浮点型 |
| Convert.ToDouble() | 转换为双精度浮点型 |
| Convert.ToString() | 转换为字符串 |
using System;
namespace yx4
{
class Program
{
static void Main(string[] args)
{
double myDouble = 85.63;
int myInt;
float myFloat;
string myString;
Console.WriteLine("原始数值为:double类型:{0}",myDouble);
myInt = Convert.ToInt32(myDouble);
myFloat = Convert.ToSingle(myDouble);
myString = Convert.ToString(myDouble);
Console.WriteLine("转换后:");
Console.WriteLine("int\t float \t string");
Console.WriteLine("{0}\t {1}\t {2}", myInt, myFloat, myString);
Console.ReadLine();
}
}
}
使用Parse方法和Convert类进行转换的时候,如果转换没有意义,则可能会出错。