c#学习 第一章 数据类型,运算符,枚举与结构

本文是作者C#学习的第一章总结,涵盖值与引用的区别、string类型的匹配与转义、带ref和out参数的方法、运算符的使用规则、枚举的定义与限制,以及结构体的知识。通过实例解析了C#中引用类型和值类型的特性,以及各种运算符的优先级和用法。
摘要由CSDN通过智能技术生成
 

最近打算把C#基础重新学一遍,所以发个C#的学习日记,接触C#有近半年了,发现C#在做界面上确实非常强大。以下文章为C#第一章,包括 值与引用,string类型匹配与转义,基本函数,带ref函数,带out函数,运算符,枚举,结构体。参考图书:《C#:开发技术大全》

一.值与引用

值类型存储的是值,而引用类型存储的是对值的引用,相当于C语言的指针将一个值赋值给另外一个变量时,将会新开辟一个内存空间给新变量用来存储值。而对于引用类型,不会新开辟存储空间,只会将地址赋给新的变量。值类型不能包含null,但是引用类型可以。引用类型为Object和String类型,char类型属于String类型内。Object类型是Object的别名,C#中可以将任何类型的值赋给Object类型的变量。

#region valueANDreference
        /// <summary>
        /// 值与引用
        /// </summary>
        public void valueANDreference()
        {
            // new 创建的对象初始值是0.不同类型的默认值不同,但是都有默认值
            short shortnew = new short();
            char charnew = new char();
            byte bytenew = new byte();
            short shortS; <span style="font-family: Arial, Helvetica, sans-serif;">//直接定义为未附值,要想使用需要赋值,此处是未赋值,不是NULL</span>
            shortS = 1;
            Console.WriteLine("short shortnew = new short():{0},   
						TYPE:{1}", shortnew, shortnew.GetType());
            Console.WriteLine("char charnew = new char():{0},       
						TYPE:{1}", charnew, charnew.GetType());  //char类型默认初始值是null
            Console.WriteLine("byte bytenew = new byte():{0},       
						TYPE:{1}", bytenew, bytenew.GetType());
            Console.WriteLine("short shortS=1:{0},                  
						TYPE:{1},   TYPECODE:{2}", shortS, shortS.GetType(), shortS.GetTypeCode());
            Console.WriteLine();//空行,等同于ENTER

            object objclass = new refClass(); //object 类型,创建类的实例
            refClass refclass = (refClass)objclass; //若要将object 类型转化为类实例,需先强制转化
            refClass newrefclass = new refClass();
            refclass.refint = 1;
            Console.WriteLine("类中成员值改变后输出:refint={0}", refclass.refint);
            Console.WriteLine("类中成员值未改变后输出:newrefint={0}", newrefclass.refint);
            Console.WriteLine();//空行,等同于ENTER         
        }
        #endregion
	#region refClass
        /// <summary>
        /// 用于引用的类
        /// 关于类的使用后面再说
        /// </summary>
        class refClass
        {
            public int refint = 0; // 为什么此处一定要用public
        }
        #endregion






二.string 类型匹配与转义

string类型为引用类型(指针类型)

所以在以下程序中我们可以看出,对于值的比较,是TRUE

而对于a和b实例的比较,是FLASE,说明a和b引用的不是同一个string实例。(即a与b指向的不是同一个内存地址)

对于存在'\' 的字符串,如果不是表示转义,需要先对其处理,处理的方法有两种

1.再加一个\

2.在开头前加上@

<span style="white-space:pre">	</span>#region transferredMeaning
        ///<summary>
        ///string 类型
        /// 值和引用的比较
        /// 转义字符串
        ///</summary>
        public void transferredMeaning()
        {
            string a = "hello";
            string b = "h";
            b = b + "ello";
            string filepathA = "C\\ABC.text";//多加\转义
            string filepathB = @"C\ABC.text"; //直接加@转义

            Console.WriteLine("a=b直接匹配:{0}", a == b); //输出true
            Console.WriteLine("(object)a=(object)b 引用匹配:{0}", (object)a == (object)b);  //输出false
            Console.WriteLine();  //空行,等同于ENTER
            Console.WriteLine("string filepathA = \"C\\\\ABC.text\":{0}", filepathA);
            Console.WriteLine("string filepathB = {0}:{1}", "@\"C\\ABC.text\"", filepathB);
        }
        #endregion



三.带参数方法

带一个基本参数的方法,就不用多说了

我们来说一说带ref引用与out输出的方法。

ref 引用,说白了,就是和C++中带指针参数的方法是相同的。掉用方法是,将变量的地址作为传递参数,

所以在方法里,对于参数的操作,即是对该变量内存空间内数字的直接操作,会改变变量的值。

out输出参数,与ref原理相同。区别是使用out修饰符,则在方法里要对参数进行赋值,而对于传递之前

有没有赋值则没有要求。

带引用参数或者基本参数的方法,在调用方法时,传递的参数一定要赋值。

<span style="white-space:pre">	</span>#region ClassTest
        /// <summary>
        /// ClassTest 类
        /// 带一个参数
        /// 带ref 参数
        /// 带out 参数
        /// </summary>
        class ClassTest
        {
            /// <summary>
            /// 带一个标准参数
            /// </summary>
            /// <param name="a">test</param>
            public void test(string a)
            {
                a = "test";
                string test = a; //static 为什么在方法里不能用
                Console.WriteLine("标准参数的方法  test=a test={0}", test);
            }

            /// <summary>
            /// 带一个ref 参数
            /// </summary>
            /// <param name="a">testref</param>
            public void testref(ref string a)
            {
                a = "testref";
                string testref = a;
                Console.WriteLine("ref参数的方法  testref=a testref={0}", testref);
            }

            /// <summary>
            /// 带一个out参数
            /// </summary>
            /// <param name="a">testout</param>
            public void testout(out string a)
            {
                a = "testout";
                string testout = a;
                Console.WriteLine("out参数的方法  testout=a testout={0}", testout);
            }
             public void printf()
            {
                string teststring = "teststring";
                test(teststring);
                Console.WriteLine("teststring = {0}", teststring);
                testref(ref teststring);
                Console.WriteLine("teststring = {0}", teststring);
                string teststringout;
                testout(out teststringout);
                Console.WriteLine("teststringout = {0}", teststringout);
            }

        }
        #endregion






四.运算符

基本的运算符就不介绍了,介绍以下几种运算符。

赋值操作符的运算规则。



运算符的优先级



代码中几个位运算符。

1. | 或运算符。当且仅当两个运算符都位false时,结果才为flase。 下图为5|7的运算结果。


2. &与运算符。当且仅当两个操作数均为true时,结果才为true。下图为5&7的结果。



3.^异或运算符。当且仅当只有一个操作数为ture时,结果才为true。下图为5^7的结果。



4.~ 取补运算符。具体步骤如下。下图为5取补的结果。



5.左移操作符。a<<=b.等同于 a=a<<b.



6.右移操作符。同左移。



7. / 除法取整。当除数或者被除数为浮点型时,为除法计算。


8. % 取余。当除数为浮点型时,则计算小数点后相应位数的余数。


9.(?:)条件运算符。根据布尔型表达式的值返回两个值中的一个。如果条件是true,则计算第一个表达式并以计算结果为准。如果为false,则为第二个。

<span style="white-space:pre">	</span>#region  Operator
        /// <summary>
        /// 运算符
        /// </summary>
        class Operator
        {
            class A
            {
                public const int a = 5;
                public double b = 7.3;
                public int c = 8;
            }
            class B : A
            {
                public int x = 6;
                public double y = 2.734 + .5; //加小数可以直接加.X,不用加0
                public int z = 7;
            }
            public void test()
            {
                Console.WriteLine("'/'运算符 取整  5/3  ={0}", 5 / 3);
                Console.WriteLine("'/'运算符 除法  5/3.2={0}", 5 / 3.2);
                Console.WriteLine("'%'运算符 取余  5%3  ={0}", 5 % 3);
                Console.WriteLine("'%'运算符 取余  5%3.2={0}", 5 % 3.2);
                A A = new A();
                B B = new B();
                B.x = B.c >= B.a ? B.a : B.c;
                Console.WriteLine("关系运算符 B.x = B.c(8)>= B.a(5)? B.a : B.c B.x={0}", B.x);
                Console.WriteLine("逻辑运算符 5|7 ={0}", 5 | 7);
                Console.WriteLine("逻辑运算符 5&7={0}", 5 & 7);
                Console.WriteLine("逻辑运算符 5^7={0}", 5 ^ 7);
                Console.WriteLine("逻辑运算符 ~5 ={0}", ~5);
                int a = 2, b = 3, c = 5, d = 1;
                Console.WriteLine("左移位运算符 a=2,b=3 a<<=b,a={0}", a <<= b);
                Console.WriteLine("右移位运算符 c=5,d=1 c>>=d,c={0}", c >>= d);
            }
        }
        #endregion






五.枚举

枚举是值类型的一种特殊形式。它从System.enum继承而来。

如存在基础类型,基础类型必须是一个内置的正数类型。枚举成员是静态文本字段。

其中每一个字段都表示为常数。同一值可以分配多个字段。

若同一值分配多个字段,则必须将其中某个值标记为主要枚举值,以便进行反射和字符串转换。

对于枚举还有以下附加限制:

枚举不能定义自己的方法。

枚举不能实现接口。

没救不能定义属性和事件。

枚举分为传统型枚举和位域型枚举,区别见代码。

<span style="white-space:pre">	</span>#region enumTest
        /// <summary>
        /// enumTest
        /// 枚举
        /// </summary>
        class enumTest
        {
            /// <summary>
            /// 枚举
            /// enum 枚举名称[:基础类型]
            /// {
            ///    枚举成员1 [=整型变量],  //此处是逗号分开
            ///    枚举成员2 [=整型变量|枚举成员1] //表示此处整型变量,枚举成员1的整型变量都是枚举成员2的枚举
            /// }
            /// 
            /// 位域通常用于由可组合初选的元素组成的列表,而枚举常数通常用于由互斥元素组成的列表
            /// 因此,位域设计为通过或运算组合来生成未命名的值,而枚举常数则不是。
            /// </summary>

            enum InfoValue : long  //带长整型的枚举,传统型枚举。
            {
                A = 0,
                B,             //未对其进行赋值,从结果中可以看出,会自动对其赋值。
                C,	       //从结果可以看出,当检索不到值所对应的枚举成员时,则不处理。
                D,
            }

            [Flags]          //位域型枚举标识符
            enum fields : short
            {
                Black = 0,    //从结果可以看出,当检索不到值所对应的枚举成员时,系统会根据
                Red = 1,      //已存在的枚举成员累加和等于检索值的成员作为新成员。
                Green = 2,
                Blue = 4
            };                 //加不加分号的区别
            enum SomeRootVegetable
            {
                枸杞,
                西红柿,
                苹果
            }
            [Flags]           //域标识
            enum Seasons
            {
                无 = 0,
                夏天 = 1,
                秋天 = 2,
                冬天 = 4,
                春天 = 8,
                所有季节 = 夏天 | 秋天 | 冬天 | 春天
            };
            public void test()
            {
                Console.WriteLine("\r\n传统型枚举:");
                for (int i = 0; i < 8; i++)
                {
                    Console.WriteLine("{0,3}-{1}", i, ((InfoValue)i).ToString());
                }
                Console.WriteLine("\r\n位域型枚举:");
                for (int i = 0; i < 8; i++)
                {
                    Console.WriteLine("{0,3}-{1}", i, ((fields)i).ToString());
                }
                Console.WriteLine("\r\n位域型枚举 季节:");
                for (int i = 0; i < 16; i++)
                {
                    Console.WriteLine("{0,3}-{1}", i, ((Seasons)i).ToString());
                }

                Hashtable vgtblAndsn = new Hashtable();
                vgtblAndsn[SomeRootVegetable.枸杞] = Seasons.春天;
                vgtblAndsn[SomeRootVegetable.苹果] = Seasons.所有季节;
                vgtblAndsn.Add(SomeRootVegetable.西红柿, Seasons.秋天 | Seasons.冬天); //与下面的语句效果一样
                // vgtblAndsn[SomeRootVegetable.西红柿] = Seasons.秋天|Seasons.冬天;
                Seasons[] seasons = new Seasons[]{Seasons.春天,Seasons.秋天,
                                                    Seasons.夏天,Seasons.冬天};//Seasons[] seasons=new Seasons[4];
                //数组的创建必须有大小或者设置初始值
                Console.WriteLine("\r\n枚举举例:");
                for (int i = 0; i < seasons.Length; i++)
                {
                    Console.WriteLine("以下蔬菜在{0,2}季节收获", seasons[i].ToString());
                    foreach (DictionaryEntry e in vgtblAndsn)    //哈希表的遍历需要用到DictionaryEntry
                    {
                        if (((Seasons)e.Value & seasons[i]) > 0) //与运算
                        {
                            Console.WriteLine(((SomeRootVegetable)e.Key).ToString());
                        }

                        /*  if(e.Value.ToString()==seasons[i].ToString())
                          {
                              Console.WriteLine(e.Key.ToString());
                          }
                          */
                    }
                }
            }
        }

        #endregion





 六.结构
结构是值类型,该类型将多个不用类型的成员组成一种新的类型,
与类相同的是,结构成员的默认可访问级别也是private,如果需要调用,必须将其声明为public.
 结构可以包含构造函数,常量,字段,方法,属性,索引器,运算符,事件和嵌套类型等。
结构的特点:
 结构是值类型,而类是引用类型。
与类不同,结构实例化可以不使用new运算符。
结构可以声明构造函数,但其必须在参数。
 一个结构不能从另一个结构或类继承,而且不能作为其他结构或基类。
结构可以实现接口。
结构可用null值对结构成员进行赋值。

<span style="white-space:pre">	</span>#region struct
        /// <summary>
        /// 结构体
        /// 结构是值类型,该类型将多个不用类型的成员组成一种新的类型,
        /// 与类相同的是,结构成员的默认可访问级别也是private,如果需要调用,必须将其声明为public.
        /// 结构可以包含构造函数,常量,字段,方法,属性,索引器,运算符,事件和嵌套类型等。
        /// struct 结构名称
        /// {
        ///     结构成员
        /// }
        /// 
        /// 结构的特点:
        /// 结构是值类型,而类是引用类型。
        /// 与类不同,结构实例化可以不使用new运算符。
        /// 结构可以声明构造函数,但其必须在参数。
        /// 一个结构不能从另一个结构或类继承,而且不能作为其他结构或基类。
        /// 结构可以实现接口。
        /// 结构可用null值对结构成员进行赋值。
        /// </summary>
        class structTest
        {
            struct employee
            {
                public string name;
                public int age;
                public string sex;
                public string address;
                public employee(string name, int age, string sex, string address) //构造函数必须带参数
                {
                    this.name = name;       //而且要对结构体成员进行赋值
                    this.age = age;
                    this.sex = sex;
                    this.address = address;
                }
            }
            struct company
            {
                public string name;
                public object employee;   //设置obj成员存储员工信息
                public string phone;
                public company(string name, object employee, string phone)
                {
                    this.name = name;
                    this.employee = employee;
                    this.phone = phone;
                }
            }
            public void test()
            {
                employee emp = new employee("move", 18, "男", "江苏南京");  //可以用new实例化,生成对象
                company com;             //也可以直接实例化
                com.name = "南信大";
                com.phone = "12345678901";
                com.employee = emp;
                Console.WriteLine("公司:{0}\r\n电话:{1}\r\n员工姓名:{2}\r\n员工性别:{3}\r\n员工地址:{4}\r\n",
                                    com.name, com.phone, ((employee)com.employee).name,
                                    ((employee)com.employee).sex, ((employee)com.employee).address);
            }
        }
        #endregion












 

                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值