C#学习笔记第一篇

C#简介

C#是微软公司开发的一种面向对象的,运行在.NET Framework上的高级程序设计语言。.NET Framework是 Microsoft 为开发应用程序而创建的一个具有革命意义的平台。.NET Framework主要包含一个庞大的代码库,可以在客户语言中通过面向对象编程技术来使用这些代码。这个库分为多个不同的模块,这样就可以根据希望得到的结果来选择使用其中的各个部分。

变量和表达式

变量

变量是有名称和类型的数据块。变量只有经过声明和初始化后,才能使用。

变量类型

在C#中,变量类型分为简单类型和复杂类型,简单类型包括整数类型,浮点数类型,字符类型(char),字符串类型(string),布尔类型(bool) 。整数类型包括sbyte, byte, short, ushort, int, uint, long, ulong;浮点数类型包括float, double, decimal 。复杂类型包括枚举,结构,数组。枚举和结构在代码主体之外进行声明,则此命名空间内的所有类都可以访问到。另外,按照存储方式可将变量分为引用类型和值类型。值类型在内存的同一处存储它们自己和它们的内容;引用类型存储指向内存中其他某个位置(称为堆)的引用,实际内容存储在这个位置。值类型有int, double, bool, char, struct 结构, enum 枚举等类型;引用类型有string, object, class 类等类型。

变量命名

变量命名规则:变量名的第一个字符必须是字母,下划线或@,其后的字符可以是字母,下划线或数字。且变量名不能使用C#中的关键字。

类型转换

类型转换采用以下两种形式:

  • 隐式转换: 让编译器执行转换
  • 显式转换: 明确要求编译器把数值从一种数据类型转换为另一种数据类型

隐式转换规则是:任何类型A,只要其取值范围完全包含在类型B的取值范围内,就可以隐式转换为类型B。显式转换的语法是:(<destinationType>)<sourceVar>或使用Convert命令进行显式转换。

字符串的处理

  • 使用+运算符可以连接字符串
  • string 类型的变量可以看成 char 变量的只读数组,可以通过下标来访问字符
  • ToCharArray():返回一个可写的char类型数组
  • Length属性:返回字符串中的字符数
  • ToLower() :返回字符串的小写形式
  • ToUpper():返回字符串的大写形式
  • Trim():删除字符串前后的空格
  • TrimStart(),TrimEnd():删除字符串前面或后面的空格
  • PadLeft(length):在字符串的左边添加空格或指定的字符,使字符串达到指定的长度
  • PadRight(length):在字符串的右边添加空格或指定的字符,使字符串达到指定的长度
  • Split():把 string 转换为 string 数组,把它在指定的位置隔开,这些位置采用 char 数组形式
  • Replace():把字符串中指定的子字符串替换成新的子字符串

注:上面的所有方法会返回一个新字符串,都不会改变原字符串。

表达式

表达式由操作数(变量和字面值)和运算符构成。运算符分为三类:一元运算符,二元运算符,三元运算符(即条件运算符)。

运算符的优先级

运算符优先级表

名称空间

名称空间是.NET中提供应用程序代码容器的方式,这样就可以唯一地标识代码及其内容。默认情况下,C#代码包含在全局名称空间中,这意味着对于包含在这段代码中的项,全局名称空间中的其他代码只要通过名称进行引用,就可以访问它们。使用 namespace 关键字可以为花括号中的代码块显式定义名称空间。如果在该名称空间代码的外部使用名称空间中的名称,就必须写出该名称空间中的限定名称。限定名称包括它所有的分层信息,限定名称在不同的名称空间级别之间使用句点字符(.)。

流程控制

分支:三元运算符,if语句,switch语句
循环:do循环,while循环,for循环
循环中断:break(终止循环),continue(终止当前循环,继续执行下一次循环),return(跳出循环及包含该循环的函数)

函数

函数其实就是可重用的代码块,在程序中使用函数可提高代码的可读性。函数还可以用于创建多用途的代码,让它们对不同的数据执行相同的操作。函数的定义包括函数名,返回类型以及一个参数列表,这个参数列表指定了该函数需要的参数数量和参数类型。函数的名称和参数共同定义了函数的签名。

定义和使用函数

static <returnType> <FunctionName>(<paramType> <paramName>, ...)
{
	...
	return <returnValue>;
}

这里唯一的限制是<returnValue>必须是<returnType>类型的值,或者可以隐式转换为该类型。
执行一行代码的函数可使用 Lambda 箭头函数:
static <returnType> <FunctionName>(<paramType> <paramName>, ...) => <statement>;
在使用函数(即调用函数时),必须使提供的参数与函数定义中指定的参数完全匹配,这意味着要匹配参数的类型,个数和顺序。C#允许为函数指定一个(只能指定一个)特殊参数,这个参数必须是函数定义中的最后一个参数,称为参数数组。参数数组允许使用个数不定的参数调用函数,可使用 params 关键字定义它们。参数数组可以简化代码,因为在调用代码中不必传递数组,而是传递同类型的几个参数。例如:

static int SumVals(params int[] arrs)
{
    int sum = 0;
    foreach(int arr in arrs)
    {
        sum += arr;
    }
    return sum;
}
int sum = SumVals(1, 2, 3, 4); //调用函数

引用参数与值参数

使用值参数的函数不会改变函数调用中指定的实参,使用引用参数会改变(函数执行完毕后,该参数的值将返回给函数调用中使用的变量),只需在函数定义和调用的时候使用ref关键字指定参数。例如:

static void ShowDouble(ref int val)
{
    val *= 2;
    Console.WriteLine($"Val double = {val}");
}
ShowDouble(ref myNumber); //myNumber的值将会被改变

用作ref参数的变量有两个限制:必须使用“非常量”变量;必须使用初始化过的变量。

输出参数

使用 out 关键字,指定所给的参数是一个输出参数。使用方式和执行方式与引用参数几乎完全一样,但有些许不同:out 参数可以且必须看成是尚未赋值的变量(可以把已赋值的变量用作out参数,但存储在该变量中的值会在函数执行时丢失)。例如编写一个函数返回数组中最大值,同时获取数组中最大值的元素索引:

static int MaxValue(int[] intArray, out int maxIndex)
{
    int maxVal = intArray[0];
    maxIndex = 0;
    for(int i=1; i<intArray.Length; i++)
    {
        if(intArray[i] > maxVal)
        {
            maxVal = intArray[i];
            maxIndex = i;
        }
    }
    return maxVal;
}
static void Main(string[] args)
{
    int[] myArray = { 1, 8, 3, 6, 2, 5, 9, 3, 0, 2 };
    int maxIndex;
    Console.WriteLine($"此数组的最大值为 {MaxValue(myArray, out maxIndex)}");
    Console.WriteLine($"此数组的最大值的下标为 {maxIndex + 1}");
    Console.ReadKey();
}

由于变量是有作用域的,所以我们需要利用函数来交换数据。变量的作用域包含定义它们的代码块和直接嵌套在其中的代码块。按作用域可将变量分为全局变量和局部变量。在控制台应用程序中,需要使用 static 或 const 关键字来定义和修改(const不能修改)全局变量(的值)。如果函数中出现了与全局变量同名的局部变量时,必须用一个完整限定的名称来使用全局变量。

namespace Practice1
{
    class Program
    {
        static string myString; //声明全局变量
        static void Main(string[] args)
        {
            string myString = "局部变量";
            Program.myString = "全局变量";
            Console.WriteLine($"{myString}");
            Console.WriteLine($"{Program.myString}");
            Console.ReadKey();
        }
    }
}

函数重载

在调用函数时,必须匹配函数的签名。函数重载允许创建多个同名函数,每个函数可使用不同的参数类型,参数个数等等。即函数重载就是定义名称相同但签名不同的多个函数。

委托

委托是一种存储函数引用的类型。委托的声明非常类似于函数,但不带函数体,且要使用 delegate 关键字。定义了委托后,就可以声明该委托类型的变量,接着把这个变量初始化为与委托具有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样。

namespace Practice1
{
    class Program
    {
        delegate double ProcessDelegate(double param1, double param2);//定义委托类型
        static double Multiply(double param1, double param2) => param1 * param2;//定义要委托的函数
        static double Divide(double param1, double param2) => param1 / param2;//定义要委托的函数
        static void Main(string[] args)
        {
            ProcessDelegate process;
            Console.WriteLine("输入两个数字并用逗号隔开");
            string input = Console.ReadLine();
            int commaPos = input.IndexOf(',');
            double param1 = Convert.ToDouble(input.Substring(0, commaPos));
            double param2 = Convert.ToDouble(input.Substring(commaPos + 1, input.Length - commaPos - 1));
            Console.WriteLine("输入M表示两数相乘,输入D表示两数相除");
            input = Console.ReadLine();
            if (input == "M")
                process = new ProcessDelegate(Multiply); //这是委托赋值的一种独特语法,参数是要使用的函数名
            else
                process = new ProcessDelegate(Divide); //初始化委托变量,即要把一个函数引用赋给委托变量
            Console.WriteLine($"结果为{process(param1, param2)}");
            Console.ReadKey();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章