当前位置:文档之家› C#面向对象程序设计 郑宇军 第三章 C#语法基础

C#面向对象程序设计 郑宇军 第三章 C#语法基础

C#面向对象程序设计 郑宇军 第三章 C#语法基础
C#面向对象程序设计 郑宇军 第三章 C#语法基础

第3章C#语法基础

在深入讨论C#面向对象程序设计之前,首先需要掌握C#语言的基本语法结构。本章将讲解C#语法结构的基本要素,包括数据类型、操作符和表达式,以及程序控制结构。

3.1数据类型

数据类型是对客观数据对象的抽象,它将数据和对数据的操作封装为一个整体。C#语言中的数据类型分为值类型和引用类型两大类。值类型包括整数、字符、实数、布尔数等简单值类型,以及结构(struct)和枚举(enum)两种复合值类型;引用类型包括类、接口(interface)、委托(delegate)和数组。这些类型在本质上都是面向对象的。

3.1.1简单值类型

1.整数类型

整数类型是对数学中的整数的抽象,但由于受到计算机的存储限制,程序设计语言中的值类型总是要设置取值范围限制。C#定义了以下8种整数类型:

● int:32位整数,取值范围为-2147483648(-231)~2147483647(231-1)。

● uint:32位无符号整数(即正整数),取值范围为0~4294967295(233-1)。

● long:64位长整数,取值范围为-9223372036854775808(-263)~9223372036854775807(263-1)。

● ulong:64位无符号整数,取值范围为0~18446744073709551615(264-1)。

● short:16位短整数,取值范围为-32768(-215)~32767(215-1)。

● ushort:16位无符号短整数,取值范围为0~65535(216-1)。

● sbyte:8位字节型整数,取值范围为-128(-27)~127(27-1)。

● byte:8位无符号字节型整数,取值范围为0~255(28-1)。

例如,下面的代码就先定义了一个整数变量x,而后将其赋值为80:

int x;

x=80;

上述两行代码还可以合并为:

int x=80;

如果是同类型的多个变量,C#允许将它们的声明语句简写到一行代码中,例如:

int x1=10,x2,x3=20;//x2还未被赋值

下面这些语句则是错误的:

uint x=-10;//错误:无符号整数不能取负数

byte y=500;//错误:超出了取值范围

long z;

Console.WriteLine(z);//错误:z在被赋值前不能使用

定义变量时应尽量选择最为适合的类型:过短的类型可能不足以表达量的变化范围,过长的类型则会造成资源浪费。例如,要表示人的年龄使用byte类型就足够了,要表示人口的数量则使用unit类型比较适合。

2.字符类型

C#中使用char来表示字符类型。由于使用了16为Unicode字符集,因此char类型不仅包含了基本的ASCII 字符还可以表示汉字等各国语言符号。注意:单个字符值要用一对单引号括起来;如果使用了双引号,那么它表示的就是只有一个字符的字符串。例如:

char a=' s ';

char b='人';

string s="人";

对于像单引号、回车符这样的特殊字符,C#中使用加斜杠“\”的转义符来表示。例如:

char a1=' \' ';//a1表示单引号

char a2=' \\ ';//a2表示单斜杠

char a3=' \r ';//a3表示回车符

表3-1列出了C#常见的一些转义符格式。

表3-1 C#常用转义符

转义符含义转义符含义\' 单引号\n 换行

\" 双引号\r 回车

\\ 单斜杠\f 换页

\a 报警(Alert)\t 水平制表符

\b 退格(Backspace)\v 垂直制表符

\c 取消(Esc)\0 空字符

char类型的变量实际上仍以整数方式存储,其取值范围与ushort相同,因此一个字符会使用16位字节的内存空间。

3.实数类型

C#定义了以下3种实数类型。

● float:32位单精度浮点数类型,取值范围为±1.5×10-45~±3.4×1038。

● double:64位双精度浮点数类型,取值范围为±5.0×10-324~±1.7×10308。

● decimal:128位十进制小数类型,取值范围为±1.0×10-28~±7.9×1028。

除了double类型之外,float和decimal类型的变量值都应在小数后加上后缀F和M,以便让编译器知道以何种类型处理这些值,例如:

double x=1.2;

float y=-0.5F;

decimal z=3.2M;

实数类型使用的位数较多,相应的计算也会消耗更多的资源,因此在程序中应尽量使用低精度的类型。有时还可以使用整数来代替实数类型,例如,在货币计算中,如果只需要精确到小数点后两位,那么使用“分”而不是“元”来做单位,就可以将实数运算转换为整数运算。此外,计算机中的实数运算也受到精度和范围的限制,有时候并不能得出数学上完全正确的结果。

4.布尔类型

bool用来表示布尔类型,其可能取值只有两个:true(真)或false(假)。例如:

bool b1=true;

bool b2=false;

布尔类型在计算机内部实际上是使用二进制1和0表示的,其运算效率在各种数据类型之间也是最高的。

3.1.2复合值类型

1.结构

像int、double这些简单值类型都是在.NET类库中预定义的。很多情况下,人们需要将不同的简单值类型组合起来使用,这时候就可以使用结构类型。考虑“复数”这个概念,.NET类库没有类型定义,那么可以在double类型的基础上定义该类型,它由两个double类型的字段组成,其中a表示复数的实部,b表示虚部:

struct ComplexNumber //定义结构类型

{

public double a;

public double b;

}

之后就可以创建该类型的变量,并通过圆点连接符“.”来访问其公有成员,例如:

ComplexNumber c1; //创建结构类型的变量

c1.a=2.5;

c1.b=5;

结构类型还可以有成员方法,这说明结果实际上是部分面向对象的,它也支持信息隐藏和封装,能够进行对象创建和消息通信。在下面的示例程序中,ComplexNumber结构还包含了一个成员方法Write,程序

主方法就调用该方法在控制台输出了两个复数:

//程序P3_1

using System;

namespace P3_1

{

class Program

{

static void Main()

{

ComplexNumber c1; //定义结构变量c1

c1.a=1.5;

c1.b=3;

ComplexNumber c2=c1; //定义结构变量c2

c2.a=c2.b;

Console.Write("c1= ");

c1.Write();

Console.Write("c2= ");

c2.Write();

}

}

struct ComplexNumber

{

public double a;

public double b;

public void Write()

{

Console.WriteLine("{0}+{1}i",a,b);

}

}

}

上面最后一行代码使用了Console类的WriteLine方法的格式化输出功能,它表示用方法的第2个参数值替换第1个字符串参数中的{0}标记,用第2个参数值替换第1个参数中{1}标记……依此类推。程序P3_1的输出内容如下:

c1=1.5+3i

c2=3+3i

实际上,前一小节中介绍的简单值类型在.NET类库内部都是以结构方式来定义的,这些结构不仅包含了变量所存储的值,还提供了类型本身的有关消息。例如,它们都提供了MinValue和MaxValue字段来表示类型的最小值和最大值,实数类型还提供了NegativeInfinity和PositiveInfinity字段表示正无穷大和负无穷大,此外,他们还能够通过成员方法ToString得到数值的字符串表示,通过方法Parse将字符串转换为数值。下面给出了以下代码示例:

short a=short.MaxValue; //a=32767

short b=short.MinValue; //b=-32768

ushort c=ushort.MinValue; //c=0

double x=double.PositiveInfinity;

double y=-x; //y=double.NegativeInfinity

string s=a.ToString(); //s="32767"

int i=int.Parse(s); //i=32767

2.枚举

还有一种情况是要对变量的取值范围作特殊的限定,可以将其定义为枚举类型,在其中“枚举”出所有可能的取值项。考虑“星期”这个概念,其取值可以是星期一到星期日,可以用如下方式定义枚举类型Weekday:

enum Weekday

{

Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday

}

枚举类型的变量值是通过“类型名”加连接符“.”再加“枚举项”来使用的,例如,星期一就是“Weekday.Monday”:

Weekday w1=Weekday.Monday;

枚举类型的成员项是使用文字来进行说明的,这有助于对程序的理解,但他们的实际存储类型都是整数。例如,对于枚举Weekday,其第一个值Monday对应整数0,Tuesday对应整数1……最后一个Sunday对应整数6.而如果将Sunday移到最前面,那么该枚举值就成为0,Monday变为1……依此类推。

C#还允许在程序中明确指定枚举值对应的整数值。例如,对于下面的定义,Monday~Sunday所对应的整数值将分别为1~7:

enum Weekday

{

Monday=1,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday

}

提示:程序中不用滥用枚举类型。事实上大多数的值都是有范围的;除了程序中常用的一些特殊概念之外,大部分还是应直接使用整数类型,并在程序逻辑中控制范围,如“月份”为1~12,“年级”为1~6,“鞋码”为10~30等,而不是将它们都定义为枚举。

3.1.3类

要将程序P3_1中ComplexNumber的类型由结构转换成类也很简单,只需将其定义的关键字由struct改为class即可:

class ComplexNumber

{

public double a;

public double b;

public void Write()

{

Console.WriteLine("{0}+{1}i",a,b);

}

}

但此时编译程序,Main方法的第二行代码会出错,提示“使用了未赋值的局部变量c1”。这是应为结构是值类型,声明变量时就会分配内存;而类是引用类型,如果只是声明变量,得到的就是一个什么都没有的空对象(null),当然也就不能访问其成员。纠错办法是将Main方法的第一行代码改为如下内容:ComplexNumber c1=new ComplexNumber(); //创建c1对象

C#中的new关键字用于显示创建类的变量,这样才得到了在程序中真实存在的内存对象。修改后得到的完整程序代码如下:

//程序P3_2

using System;

namespace P3_2

{

class Program

{

static void Main()

{

ComplexNumber c1=new ComplexNumber(); //创建c1对象

c1.a=1.5;

c1.b=3;

ComplexNumber c2=c1; //创建c2对象

c2.a=c2.b;

Console.Write("c1= ");

c1.Write();

Console.Write("c2= ");

c2.Write();

}

}

class ComplexNumber

{

public double a;

public double b;

public void Write()

{

Console.WriteLine("{0}+{1}i",a,b);

}

}

}

但编译运行该程序,会看到控制台的输出结果发生了变化:

c1=3+3i

c2=3+3i

这就说明了值类型和引用类型的第二个区别:将值类型的一个变量赋值给另一个变量,原始变量的数据会被拷贝给新变量,之后两个变量是互相独立的;将引用类型的一个变量赋值给另一个变量,实际上新变量只是包含了指向原始对象的指针,对其中任何一个变量的修改都会影响到另一个变量。在程序P3_2中使用引用类型的类时,对c2对象的修改也就同时改变了c1对象。

此外,结构类型之间不允许继承。如果要充分享受继承和多态性等面向对象的优越性,还是应使用类这种完全面向对象的类型。定义一个新类时,如果要使其从另一个类中继承,那么应在新类的名称后接冒号再接基类的名称。

下面的代码先定义了一个Student类,而后定义了其派生类Graduate,这样Graduate就继承了Student的3个字段和一个方法,而supervisor则是Graduate类自己独有的。

class Student //基类

{

public string name;

public int age;

public int grade;

public void Register() { }

}

class Graduate : Student //派生类

{

public string supervisor;

}

前面出现过的string类型也是.NET类库中定义的一个类,但C#语言对字符串有着特殊的处理方式,对于两个string变量s1和s2,语句“s1=s2”并不会使他们指向同一个对象,因此不存在修改一个字符串而影响到另一个字符串的情况。但所有的string对象仍是引用类型;和其他对象类型一样,可将空值null赋给string变量,而对于任何值类型的变量都是不允许的:

string s1=null; //正确

int i1=null; //错误

3.1.4数组

数组是一种聚合类型,它表示具有相同类型的一组对象的集合,这些对象叫做数组元素。数组元素的类型可以是值类型,也可以是引用类型。

1.一堆数组

一堆数组的声明是在数组元素的类型声明后面加上一对中括号,例如声明一个整型数组:

int[] nums;

作为引用类型,数组对象同样需要初始化之后才能使用,而且new关键字后面的类型声明的中括号里需要指定数组的长度,例如:

nums=new int[3];

要访问数组元素,则需要在数组对象后的中括号里指定数组元素的下标位置,其中第一个数组元素的下标为0,第二个的下标为1……依此类推,例如:

nums[0]=3; //数组的第一个元素赋值为3

nums[1]=6; //数组的第一个元素赋值为6

nums[2]=9; //数组的第一个元素赋值为9

Console.WriteLine(nums[1]); //输出数组的第二个元素值

使用数组要防止“越界”,即要访问的数组元素的下标不能超过数组的长度范围,如对上面的数组不能访问nums[3]。但这种错误在编译时不会被发现,只有在运行到该代码时才会报错,所以在编程过程时应格外注意。

为了简化代码,C#还允许在初始化数组对象的同时为其中的元素赋值,例如:

int[] xs=new int [3]{10,20,30};

double[] ys=new double[4]{1.25,3.5,3.75,5};

上面的代码还可以进一步简写为:

int[] xs={10,20,30};

double[] ys={1.25,3.5,3.75,5};

对于一个数组变量,通过其Length属性可以判断数组的长度,例如:

int[] nums={3,6,9};

Console.WriteLine(nums.Length); //输出3

当数组元素的类型为值类型时,数据直接存放在数组中;当数组元素的类型为引用类型时,数组中存放的只是各个引用对象的地址,这时不排除多个数组元素指向同一个对象的可能。看下面的程序示例:

//程序P3_3

using System;

namespace P3_3

{

class Program

{

static void Main(string[] args)

{

ComplexNumber c1 = new ComplexNumber();

c1.a = 1.5;

c1.b = 3;

ComplexNumber[] cs = new ComplexNumber[4];

cs[0] = c1;

cs[1] = new ComplexNumber();

cs[1].a = 4;

cs[1].b = 5;

cs[2] = c1;

cs[3] = cs[1];

cs[0].a = 8;

cs[3].b = 9;

Console.Write("c1=");

c1.Write();

Console.Write("cs[1]=");

cs[1].Write();

Console.Write("cs[2]=");

cs[2].Write();

Console.ReadLine();

}

}

class ComplexNumber

{

public double a;

public double b;

public void Write()

{

Console.WriteLine("{0}+{1}i", a, b);

}

}

}

由于使用的ComplexNumber是引用类型,c1、cs[0]、cs[2]同时指向一个对象,而cs[1]和cs[3]同时指向另一个对象。程序P3_3的输出内容如下:

c1=8+3i

cs[1]=4+9i

cs[2]=8+3i

2.多维数组

多维数组的声明是在元素类型后的中括号里增加逗号,并在初始化时指定每一维的长度。例如,下面的语句创建了一个三行两列的二维整型数组:

int[,] nums=new int[3,2];

访问数组元素时同样需要指定每一维的下标,例如:

nums[0,0]=1;

nums[0,1]=2;

nums[1,0]=3;

nums[1,1]=5;

nums[1,2]=8; //错误:数组越界!

对于多维数组变量,其Length属性返回的是整个数组的总长度,通过其GetLength方法还可以获取每一维

的长度。下面的程序就输出了3个数组的总长度和各维长度,其中创建数组时还使用了不同的简写方式。书写数组元素时要注意不同层次上大括号对的匹配性(C#编译器可自动推算出数组每一维的长度):

//程序P3_4

using System;

namespace P3_4

{

class Program

{

static void Main()

{

int[,] x = new int[2, 3] { { 1, 2, 3 }, { 3, 5, 8 } };

int[,] y = new int[,] { { 10, 50 }, { 25, 75 }, { 50, 150 }, { 100, 80 } };

int[, ,] z = { { { 1, 2 }, { 3, 5 }, { 8, 13 } }, { { 1, 2 }, { 3, 5 }, { 8, 13 } } }; Console.Write("数组x长度为:");

Console.WriteLine(x.Length);

Console.WriteLine("各维长度:{0}*{1}", x.GetLength(0), x.GetLength(1));

Console.Write("数组y长度为: ");

Console.WriteLine(y.Length);

Console.WriteLine("各维长度: {0}*{1}", y.GetLength(0), y.GetLength(1));

Console.Write("数组z长度为:");

Console.WriteLine(z.Length);

Console.WriteLine("各维长度:{0}*{1}*{2}", z.GetLength(0),

z.GetLength(1),z.GetLength(2));

Console.ReadLine();

}

}

}

程序P3_4的输出内容如下:

数组x长度为:6

各维长度:2*3

数组y长度为:8

各维长度:4*2

数组z长度为:12

各维长度为:2*3*2

提示:为了提高程序的可读性,创建数组时还是尽量写出数组各维的长度。此外,数组的维数过高不仅会大量占用系统资源,还会增加程序的复杂度以及数组越界的危险性,因此要控制使用三维以上的多维数组。

3.1.5类型转换

相容的数据类型的变量之间可以进行类型转换。有的转换是系统默认的,叫作隐式(implicit)转换;有的转换则需要明确指定转换的类型,叫作显式(explicit)转换。显式转换不能保证成功,还有可能发生信息丢失,使用时应格外小心。

1.值类型之间的转换

从低精度的简单值类型到高精度的简单值类型可以进行隐式转换,包括以下几种情况:

●如果一种整数类型的取值范围被另一种整数类型的取值范围所涵盖,那么从前者到后者可以进行隐式转换;

●从整数类型到实数类型可进行隐式转换;

●从float类型到double类型可进行隐式转换;

●从char类型到ushort、uint、int、ulong、long、float、double、decimal这些类型可进行隐式转换(这和ushort 类型到其他类型的隐式转换是等价的)。

下面给出了从低精度整数类型到高精度整数类型的转换示例:

sbyte x1=100;

short x2=x1;

int x3=x2;

long x4=x3;

不满足上述隐式转换条件的简单值类型之间只能进行显式转换,转换办法是在要转换的值之前加上一对圆括号,并在括号中写上要转换的目标类型。例如:

double y1=13.56;

int y2=(int)y1;

显示转换时要注意值的范围。很明显,实数显示转换为整数后,实属原来的小数部分就会丢失。再看下面的代码示例:

long z1=100;

int z2=(int)z1;

short z3=(short)z2;

sbyte z4=(sbyte)z3;

执行完上述转换后,z1~z4的值还是100.但如果将z1值改成1000,z2和z3的值仍然不变,但z4的值就会变成-24,这是因为整数1000所对应的16位二进制码为00000011 11101000,但转换到8位整数类型sbyte时就只剩下了后8位11101000,对应十进制整数就是-24,这时程序不会报错,有经验的开发人员也可能推断出预期结果,但在程序中应避免这种情况的出现,而绝不能将其作为一种非常规的“技巧”来使用。

整数类型和char类型之间的转换所表达的是字符的整数编码,此时要注意数字字符和数字本身的区别。C#还规定从各种整数类型到char类型都只能进行显式转换。看下面的代码示例:

int x=6;

char a=(char)x; //显式转换

Console.WriteLine(a);

char b='6';

int y=b; //隐式转换

Console.WriteLine(b);

Console.WriteLine(y);

整数编码6对应的字符是黑桃符号‘?’,因此第3行代码将输出该符号;而字符‘6’对应的编码是54,因此第6行和第7行代码将分别输出6和54。(Console类会自动根据参数的类型来选择输出的格式)

自定义的枚举类型在本质上也是整数,但枚举类型和整数类型之间必须使用显示转换,唯一的例外是常数0可以直接赋值给枚举变量。看下面的程序示例:

//程序P3_5

using System;

namespace P3_5

{

class Program

{

static void Main()

{

Weekday w1 = 0;

Weekday w2 = (Weekday)3;

Weekday w3 = (Weekday)100;

Console.WriteLine(w1);

Console.WriteLine(w2);

Console.WriteLine(w3);

int x = (int)Weekday.Friday;

Console.WriteLine(x);

Console.ReadLine();

}

}

enum Weekday

{

Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday

}

}

该程序前两行输出的w1和w2的值将分别为“Monday”和“Thursday”;而w3被赋予的值已经超出了枚举的定义范围之外,因此程序第三行将直接输出整数100;而将枚举值“Friday”转换为整数时,得到的值为4。

此外,布尔类型与整数等其他类型之间不存在任何转换关系,这和C/C++等语言中的布尔类型是不同的。

2.引用类型之间的转换

引用类型之间转换的基本原则是:从派生类的对象到基类的对象可以进行隐式转换;而从基类对象到派生类对象只能进行显式转换,且不一定成功。这一点很容易理解,因为特殊对象同时也是一般对象,而一般对象不能保证是特殊对象。转换之后,两个变量指向的仍是同一个对象。

例如,在下面的程序中,Graduate是Student的派生类,那么Graduate对象g1可以隐式转换为Student对象s1,而s1实际上仍是一个Graduate对象,因此可以显示转换得到g2;Student对象s2并不是一个Graduate 对象,试图将其显示转换为Graduate对象s3时就会失败(错误信息为“无法将类型为P3_6.Student的对象强制转换为类型P3_6.Graduate”)。

//程序P3_6

using System;

namespace P3_6

{

class Program

{

static void Main()

{

Graduate g1 = new Graduate();

https://www.doczj.com/doc/eb5219587.html, = "陈亮";

Student s1 = g1; //从派生类到基类(从后往前看),隐式转换

Student s2 = new Student();

https://www.doczj.com/doc/eb5219587.html, = "宋燕燕";

Graduate g2 = (Graduate)s1; //从基类到派生类,显式转换

Console.WriteLine(https://www.doczj.com/doc/eb5219587.html,);

//Graduate g3 = (Graduate)s2; //错误,转换失败

Console.ReadLine();

}

}

class Student //基类

{

public string name;

public int age;

public int grade;

public void Register() { }

}

class Graduate : Student //派生类

{

public string supervisor;

}

}

进一步推广到数组的情况。C#规定,如果两个数组的维数相同,而它们的数组元素之间可以进行引用转换,那么两个数组之间也可以进行引用转换,且转换方式与数组元素之间的转换方式相同。例如,从一个Graduate[]数组可隐式转换为一个Student[]数组,反之则要进行显式转换。

例如:

Graduate[] gs1=new Graduate[]{g1,g2};

Student[] ss1=gs1;

Graduate[] gs2=(Graduate[])ss1;

但要记住一点:在元素为值类型的数组之间(如int[]数组和long[]数组之间)不能进行任何转换。

3.值类型和引用类型之间的转换

在C++等传统语言当中,整数、布尔等值类型属于语言的内置类型,而这些内置类型本身不是面向对象的。C#语言则采用了一种全新的观点:程序设计语言的类型系统应当是一个有机的整体,所有的变量都是对象,所有的类型都有一个共同的基类——object类。

object类本身是引用类型,所有其它的引用类型都可以与它进行转换。object同时又是所有值类型的基类,所有值类型的变量都可以隐式转换为object类型,这个过程叫作装箱(Boxing);object类型可以显示转换到值类型,这个过程叫作拆箱(Unboxing)。这样值类型和引用类型两部分就有机地联系在了一起。下面给出了装箱和拆箱的简单示例代码:

int x=3;

object y=x; //装箱

int z=(int)y; //拆箱

3.2操作符和表达式

和数学运算中的概念类似,表达式由操作数和操作符(也叫运算符)组成,其作用是将操作符施加于操作数以得到相应的计算结果,而结果的数据类型由操作数的数据类型决定。对于包含两个或两个以上操作符的复杂表达式,操作符执行的顺序取决于他们的优先级(高优先级的操作符先执行)和结合性(同一优先级的操作符从左向右或是从右向左执行)。使用圆括号可以控制表达式的计算顺序。

3.2.1算术操作符

C#中的算术操作符有加(+)、减(-)、乘(*)、除(/)和取模(%),它们可以作用于各种整数和实数类型,从而完成基本的算术运算。它们都是从左向右执行计算,且后3个操作符的优先级要高于前两个操作符,例如:

int x=2*4-1; //从左向右计算,x=7

int y=6+4/2; //先计算4/2,y=8

使用括号可以改变表达式的求值顺序,确保括号内的表达式总是被单独计算的,例如:

int x=2*(4-1); //x=6

int y=(6+4)/2; //y=5

除操作符用于求两个数的商,模操作符用于求两个数相除的余数。对于相同类型的操作数,表达式的计

算结果总是和操作数的类型相同,因此整数相除和取模的结果仍为整数,而实数相除和取模的结果为实数,这一点何处等数学中的玉树概念是有所区别的。例如:

int x1=10/3; //x1=3

int x2=10%3; //x2=1

double y1=5.4/1.5; //y1=3.6

double y2=5.4%1.5; //y2=0.9

枚举变量可与整数进行加减运算,这实际上是先将枚举转换为整数,运算之后再将结果重新转换为枚举。两个枚举变量相减将得到一个整数,但它们不能直接相加。例如:

Weekday w1=Weekday.Friday+1; //w1=Weekday.Saturday

Weekday w2=Weekday.Thursday-2; //w2=Weekday.Tuesday

int i1=w1-w2; //il=4

int i2=w1+w2; //错误,枚举变量不能相加

3.2.2自增和自减操作符

计算机程序中会经常用到加1和减1运算,C#中定义了自增操作符“++”和自减操作符“--”。和算术操作符不同,这两个操作符都只有一个操作数,而它们的优先级也高于算术操作符。

在表达式中,当操作符“++”放在变量之前时,变量值先被加1,而后表达式再使用该变量;而当操作符“++”放在变量之后时,表达式先使用该变量,而后变量值被加1.操作符“--”的情况也是类似的。例如,在下面的代码中,6次输出的内容将分别是100、102、102、49、49、48。

int x=100;

Console.WriteLine(x++); //先输出100,而后计算x=x+1=101

Console.WriteLine(++x); //先计算x=x+1=102,而后输出102

Console.WriteLine(x); //输出102

int y=50;

Console.WriteLine(--y); //先计算y=y-1=49,而后输出49

Console.WriteLine(y--); //先输出49,而后计算y=y-1=48

Console.WriteLine(y); //输出48

3.2.3位操作符

位操作符是对数据按二进制位进行运算的操作符,具体包括以下几种。

●取反操作符“~”:作用于一个操作数,且必须放在操作数前,表示对操作数的各二进制位取反(0变为1,1变为0)

●左移位操作符“<<”:作用于两个操作数,表示将左操作数的各二进制位依次左移,左边的高位被舍弃,右边的低位顺序补0,移动的位数由右操作数指定。

●右移位操作符“>>”:作用于两个操作数,表示将左操作数的各二进制位依次右移,右边的低位被舍弃,左边的高位则对正数补0、对负数补1,移动的位数由右操作数指定。

●与操作符“&”:作用于两个操作数,表示对两个操作数的对应二进制位依次进行与运算。

●或操作符“|”:作用于两个操作数,表示对两个操作数的对应二进制位依次进行或运算。

●异或操作符“^”:作用于两个操作数,表示对两个操作数的对应二进制位依次进行异或运算。

取反操作符的优先级高于算术操作符,其他的则低于算术操作符。与、或、异或这3个操作符可以作用于整数类型和布尔类型,它们的运算规则见表3-2;其他的位操作符则只能作用于整数类型(或是能够转换为整数的其他类型)。

表3-2 与、或、异或运算规则

操作数与或异或

0和0 0 0 0

0和1 0 1 1

1和1 1 1 0 false和false false false false

false和true false true true

true和true true true false

进行位运算时,要注意有符号整数的二进制首位表示符号位(0表示正数,1表示负数)。下面各出了一些简单的位运算代码示例,其各行输出内容分别是-21、9、80、-2、20、-10、-30。

byte x = 20; //二进制00010100

sbyte y = -10; //二进制11110110

Console.WriteLine(~x); //11101011(-21)

Console.WriteLine(~y); //00001001(9)

Console.WriteLine(x << 2); //01010000(80)

Console.WriteLine(y >> 3); //11111110(-2)

Console.WriteLine(x & y); //00010100(20)

Console.WriteLine(x | y); //11110110(-10)

Console.WriteLine(x ^ y); //11100010(-30)

位运算的效率一般会高于加减乘除等算术运算。以移位运算为例,在整数的有效范围内将其左移n位相当于乘以2的n次方,右移n位则相当于除以2的n次方。例如,下面的两行代码得到x和y的值是相同的,但第二行代码的效率会大大高于第一行:

int x=256*256; //x=65536

int y=256<<8; //y=65536

3.2.4赋值操作符

前面已经看到了简单赋值操作符“=”的用法,它表示将右操作数的值赋予左操作数,前提是右操作数的类型与左操作数相同,或是可隐式转换为左操作数的类型。

为了简化程序代码,C#还提供了10个复合赋值操作符“+=”、“-=”、“*=”、“/=”、“%=”、“<<=”、“>>=”、“&=”、“|=”、“^=”,它们实际上是将加、减、乘、除、取模、左移位、右移位、与、或、异或这些运算和简单赋值结合起来。例如,“x+=y”等价于“x=x+y”,“x&=y”等价于“x=x&y”等。

和一般算术运算不同,赋值操作符属于右结合的操作符,即表达式会按照从右向左的顺序进行赋值运算。例如,执行完下面的语句后,x的值为100,而y和z的值均为1000:

int x=10,y=10;

int z=y*=x*=10; //先计算x*=10,在计算y*=x,最后执行z=y

赋值操作符在所有操作符中的优先级最低,即表达式总是计算等号右边的部分而再进行赋值运算。例如,表达式“x+=y+z”会先计算y与z的和,再将其加到x上。

3.2.5关系操作符

关系操作符用于对指定的条件进行判断,并返回一个布尔值来表示判断结果。其中“==”、“!=”、“<”、“<=”、“>”、“>=”这6个操作符又叫做比较操作符,它们分别用于判断左操作数是否等于、不等于、小于、小于等于、大于、大于等于右操作数。默认情况下,它们可用于值类型之间的大小比较,而“==”和“!=”操作符还可用于比较两个引用类型的变量是否指向同一个对象。下面的示例代码说明了这一点:

int x1=5;

int x2=x1;

Console.WriteLine(x1==x2); //输出true

object o1=x1;

object o2=x2;

object o3=o1;

Console.WriteLine(o1==o2); //o1和o2指向不同的对象,输出false

Console.WriteLine(o1==o3); //o1和o3指向同一个对象,输出true

提示:在C#中如果将相等操作符“==”误写为赋值操作符“=”,系统将给出语法错误提示,例如,对于整数x和y,语句“bool b=(x=y)”不能通过编译,这有助于发现代码错误。此外,C#语言不支持连续的关系比较,如语句“bool b=(x==y==z)”和“bool b=(x>y>z)”都是错误的。

C#还有一个特殊的关系操作符“is”它用于判断左操作数的类型是否为右操作数,例如:

int x=5;

object o=x;

Console.WriteLine(o is object); //输出true

Console.WriteLine(o is int); //输出true

Console.WriteLine(o is long); //输出false

操作符“is”主要用于引用类型的判断,只要左操作数的类型为右操作数或是右操作数的派生类型,表达式就返回true。不过如果左操作数为null,那么始终返回false。

3.2.6逻辑操作符

C#中提供了3个逻辑操作符:

●逻辑与操作符“&&”:有两个操作数,用于判断它们的值是否都为true。

●逻辑或操作符“||”:有两个操作数,用于判断它们的值是否至少有一个为true。

●逻辑非操作符“!”:只有一个操作数,用于判断其值是否为false。

以枚举Weekday为例,判断某个枚举变量w1是否为周末的表达式可以写成:

bool b1=(w1==Weekday.Saturday)||(w1==Weekday.Sunday);

而判断w1是否为工作日的表达式可以写成以下两种形式:

bool b2=!((w1==Weekday.Saturday)||(w1==Weekday.Sunday));

bool b3=(w1!=Weekday.Saturday)&&(w1!=Weekday.Sunday);

综合使用这些逻辑操作符,可以对各种复杂的逻辑组合条件进行判断。例如,判断某一个整数变量year 是否表示闰年的语句可以写成:

bool bLeap=(year%400==0)||((year%4==0)&&(year%100!=0));

在逻辑操作符的求值过程中有时不需要计算完整个表达式就可以得到结果,这称为逻辑表达式的“短路”效应。例如,对于上面这行代码,当year的值为2000时,第一对括号中的条件表达式的值为true,那么bLeap 的值就直接确定为true,而不再需要计算操作符“||”右侧的部分。

再看一个考核程序实例,考核小组由5名考官(含1名主考官、2名本单位考官和2名另外单位考官)组成,考核通过的条件是:主考官同意,且至少有1名本单位考官和1名外单位考官同意。将每名考官的评分依次放在一个布尔数组x中,下面的程序P3_7就通过一个复合逻辑表达式来判断考核结果,程序同时还输出了表达式中进行关系判断的次数:

//程序P3_7

using System;

namespace P3_7

{

class Program

{

static void Main()

{

bool[] x = new bool[5];

Console.WriteLine("请依次输入每名考官的评分,1通过,0不通过:");

x[0] = (Console.ReadLine() == "1");

x[1] = (Console.ReadLine() == "1");

x[2] = (Console.ReadLine() == "1");

x[3] = (Console.ReadLine() == "1");

x[4] = (Console.ReadLine() == "1");

int i = 0;

bool b = (x[i++] && (x[i++] || x[i]) && (x[++i] || x[++i]));

Console.WriteLine("考核结果为:{0}", b);

Console.WriteLine("判断此次为:{0}", i);

}

}

}

程序P3_7的输出结果如图3-1所示。利用逻辑运算的短路效应,只要主考官不同意,考核就不通过,此时只需进行一次判断;要确定考核通过,至少需要进行3次判断。

图3-1 程序P3_7的输出结果示例

3.2.7条件操作符

C#中还提供了一个条件操作符“?:”,它的特殊性在于它有3个操作数,使用时符号“?”和“:”分别位于3个操作数之间,其形式为:

b ? x : y

其中第一个操作数b为布尔类型,如果其值为true,则返回x的值,否则返回y的值。例如,下面的语句可用于计算两个整数x和y的最小值:

int z=(x<=y)?x:y;

注意:在任何情况下,条件表达式都不会对x和y同时进行求值,但它仍要求x和y的类型是一致的(相同或是能进行隐式转换)。例如,下面最后一行代码是错误的,因为整数i和字符串s属于不同的类型:

int i=5;

string s="abc";

Console.WriteLine((i%2==0)?i:s); //错误:i和s类型不同!

而将该行语句改为如下内容就是正确的了:

Console.WriteLine((i%2==0)?i.ToString():s); //正确

条件操作符的优先级仅高于赋值操作符,但低于其他的任何操作符。如果一个表达式中使用了多个条件操作符,要注意它们是从右向左结合的,例如,求3个整数的最大值的表达式可以写成:

int w=x>=y?x>=z?x:z:y<=z?z:y

该语句相当于:

int w=(x>=y)?((x>=z)?x:z):((y<=z)?z:y)

不过,为了提高程序的可读性,还是应尽量使用括号来明确条件表达式的求值顺序。

3.3控制结构

方法中的各行代码通常是按照顺序依次执行的。若要改变代码的执行流程,就要使用控制结构。结构化程序设计中最常见的3种控制结构分别是选择、循环和跳转。

3.3.1选择结构

选择结构是根据不同的条件来选择要执行的语句,C#中提供了if和switch两种选择结构。

1.if选择结构

最简单的选择结构是if语句,其形式为:

if (b-exp)

{

statement;

}

其中b-exp表示一个布尔类型的表达式,其值为true时才会执行其后的语句statement(如果该语句只有一行代码,那么其外的一对大括号可以省略)。例如,下面的代码判断整数i是否为一个偶数,如果是,则将i 除以2:

if (i%2==0)

i=i/2;

稍微复杂一点的选择结构是if-else语句,其形式为:

if (b-exp)

{

statement1;

}

else

{

statement2;

}

程序在b-exp的值为true时执行语句statement1,否则执行语句statement2。下面的代码就使用了if-else语句来求两个整数的最小值(注意:不要把变量z的声明放在if-else结构之内,否则之后的语句将不能使用该变量):int z;

if(x<=y)

z=x;

else(x<=y)

z=y;

Console.Write(z);

如果要实现两条以上的选择路径,那么可在if-else语句中嵌入多个else if分支,形如:

if(b-exp1)

{

statement_1;

}

else if(b-exp2)

{

statement_2;

}

else if

b-exp statement 结束

b-exp False

true statement1 结束

False

true statement2

else {

statement_n; }

程序首先检查布尔表达式b-exp1的值,为true 时执行语句statement_1;否则检查b-exp2的值,为true 时执行语句statement_2……以此类推;如果所有条件都不成立,则执行最后一个else 后的语句statement_n 。 假设整数x 表示考试分数,80~100分为优,60~79分为良,40~59分为中,40分以下为差,那么下面的代码可根据分数来输出成绩的等级: if (x >= 80)

Console.WriteLine("优"); else if (x >= 60)

Console.WriteLine("良"); else if (x >= 40)

Console.WriteLine("中"); else

Console.WriteLine("差");

当然,改变一下各个分支的顺序也不会影响到程序的判断结果: if (x < 40)

Console.WriteLine("差"); else if (x < 60)

Console.WriteLine("中"); else if (x < 80)

Console.WriteLine("良"); else

Console.WriteLine("优");

以上3种if 语句的选择流程可用图3-2来说明。

开始

(a)单if 结构

开始

(b)if-else 结构

开始 b-exp1 b-exp2 statement_1

statement_2

statement_n … 结束

False

False

true

true

(c)if-else if-else 结构 图3-2 if 选择结构流程图

if-else 语句中还可以嵌套if-else 语句,此时每个else 分支都与其前面最近的一条不带else 分支的if 语句组成一个if-else 对。不过在这种情况下,还是应尽量使用大括号对来明确if-else 语句的具体结构。程序P3_8就使用了嵌套if-else 语句来计算3个整数的最大值: //程序P3_8 using System; namespace P3_8 {

class Program {

static void Main() {

Console.Write("请输入x 的值:"); int x = int.Parse(Console.ReadLine()); Console.Write("请输入y 的值:"); int y = int.Parse(Console.ReadLine()); Console.Write("请输入z 的值:"); int z = int.Parse(Console.ReadLine()); Console.Write("最大值为:"); if (x >= y) {

if (x >= z)

Console.WriteLine(x); else

Console.WriteLine(z); } else {

if (y >= z)

Console.WriteLine(y); else

Console.WriteLine(z); } } } }

开始

exp=c-exp1

exp=c-exp2

statement_1

statement_2

statement_n

结束

False

False

true true 2.switch 选择结构

实现多条选择路径的另一种方式是使用switch 语句,其形式为: switch(exp) {

case c-exp1: statement_1; break; case c-exp2: statement_2; break; ……

default: //可选 statement_n; break; }

其中switch 标签后的exp 为控制表达式,其类型可以是整数(包括字符和枚举)和字符串,而各个case 标签后的常量表达式c-exp 的类型必须与控制表达式的类型一致(相同或是能进行隐式转换)。程序执行时会将exp 的值与表达式c-exp1、c-exp2……依次进行比较,如果相等,则执行对应case 标签下的statement 语句,然后执行break 语句来结束switch 语句;如果控制表达式的值与所有常量表达式的值均不匹配,则执行default 标签后的语句,这里default 部分是可选的。switch 选择结构执行的流程图如图3-3所示。

图3-3 switch 选择结构流程图

以前面的判断成绩等级的代码为例,使用switch 语句可以将其改写为如下代码: int i=x/20; switch(i) { case 5:

Console.WriteLine("优"); break; case 4:

Console.WriteLine("优"); break; case 3:

Console.WriteLine("良"); break; case 2:

Console.WriteLine("中"); break;

Console.WriteLine("差");

break;

}

显然,switch语句中各个常量表达式的值不能相等。此外,C#还规定每个case分支都必须以break、return、goto或throw语句来结束,而且语句中的代码都不能修改控制表达式的值,这就使得switch语句中case分支的排列顺序不会影响到整个语句的功能。

提示:对于经常使用的选择语句,如果能够判断出不同条件发生的概率,那么应尽量将概率较高的if或case 分支放在选择结构靠前的位置,这样能够减少程序中进行判断的次数,提高程序效率。例如,如果考试成绩x在60~79分之间的学生数量最多,那么可以将相应的条件(x>=60&&x<80)作为第一个if分支,或是将3作为判断(x%20)的第一个case分支。

3.3.2循环结构

循环结构用于代码段的重复执行。C#中提供了while、do-while、for和foreach这4种循环结构。

1.while循环结构

while循环结构指定一个条件,并在该条件为真时反复执行循环体。其形式为:

while(b-exp)

{

statement;

}

假设存款本金为1000元,年利率为8%,下面的代码使用了while循环来计算5年后的本息合计金额:decimal x=1000;

int i=0;

while(i<5)

{

x=x*(1+0.08M);

i++;

}

Console.WriteLine(x);

循环结构在控制台程序中的一个典型应用就是执行某项功能,直至用户按下特定的键后才退出程序。程序P3_9就给出了这样一个例子:

//程序P3_9

using System;

namespace P3_9

{

class Program

{

static void Main()

{

Console.WriteLine("按Q退出,按其他键继续");

while (Console.ReadKey().KeyChar != 'Q')

{

Console.WriteLine("欢迎光临");

Console.WriteLine("按Q退出,按其他键继续");

}

《面向对象程序设计C 》期末试卷及标准答案

《面向对象程序设计C++》期末考试试卷(B) 一、单项选择题(每小题2分,共40分) 1、关于C++与C语言关系的描述中,()是错误的。 A.C语言是C++语言的一个子集B.C语言与C++语言是兼容的 C.C++语言对C语言进行了一些改进D.C++语言和C语言都是面向对象的 2、已知:int m=10; 下列表示引用的方法中,()是正确的。 A.int &x=m; B.int &y=10; C.int &z; D.float &t=&m; 3、考虑下面的函数原型声明:void testDefaulParam(int a,int b=7,char z='*'); 下面函数调用中,不合法的是()。 A.testDefaulParam(5); B.testDefaulParam(5,8); C.testDefaulParam(5,'#'); D.testDefaulParam(0,0,'*'); 4、系统在调用重载函数时往往根据一些条件确定哪个重载函数被调用,在下列选项中,不能作为依据的是()。 A.函数的返回值类型B.参数的类型C.函数名称D.参数个数 5、下列有关C++类的说法中,不正确的是()。 A.类是一种用户自定义的数据类型 B.只有类中的成员函数或类的友元函数才能存取类中的私有成员 C.在类中,如果不做特别说明,所有成员的访问权限均为私有的 D.在类中,如果不做特别说明,所有成员的访问权限均为公用的 6、已知X类,则当程序执行到语句X array[3];时,调用了()次构造函数。 A.0 B.1 C.2 D.3 7、有关析构函数的说法,不正确的是()。 A.析构函数有且仅有一个 B.析构函数和构造函数一样可以有形参 C.析构函数的功能是在系统释放对象之前作一些内存清理工作 D.析构函数无任何函数类型

c面向对象程序设计试题和答案(经典题目)

一、填空题(每空1分,共14分) 1、观看以下程序: class point{ public: void show() {cout<<”point”<

(A)指针(B)引用(C)枚举(D)结构 3、类成员的访问权限中,()只能被本类的成员函数和其友元函数访问。 (A)share (B)public (C)private (D)protected 4、关于构造函数,下列说法不正确的是()。 (A)构造函数名字和类名相同 (B)构造函数在创建对象时自动执行 (C)构造函数无任何函数返回类型 (D)构造函数有且只有一个 5、派生类可以访问其基类的()。 (A)公有成员(B)保护成员 (C)私有派生(D)公有和保护成员 6、下列关于运算符重载的描述中,错误的是()。 (A)运算符重载不可以改变操作数的个数 (B)运算符重载不可以改变运算符的功能 (C)运算符重载不可以改变结合方向 (D)运算符重载不可以改变运算优先级 7、C++语言是从早期的C语言逐渐发展演变而来的.与C语言相比,它在求解问题方法上进行的最大改进是() (A)面向过程(B)面向对象(C)安全性(D)复用性 8、对于类中定义的成员,其隐含访问权限为()。 A.public B.protected C.private D.static 9、下面有关重载函数的说法中正确的是() (A)重载函数必须具有不同的返回值类型;(B)重载函数形参个数必须不同; (C)重载函数必须有不同的形参列表(D)重载函数名可以不同; 10、有如下的对类“CSample”的说明,其中()是错误的。 class CSample { A.int a=23; B.CSample(); public: C.CSample(int val); D.~ CSample(); 11、在int a=3,int *p=&a;中,*p的值是( ) A.变量a的地址值 B.无意义 C.变量p的地址值 D.3 12、每个类()构造函数。 (A)只能有一个(B)只可有公有的

面向对象程序设计教程 (马石安版)

第1章习题答案 名词解释 抽象:抽象(Abstract)就是忽略事物中与当前目标无关的非本质特征,而强调与当前目标有关的本质特征,从而找出事物的共性,并把具有共性的事物划为一类。面向对象方法中的抽象,是指对具体问题(对象)进行概括,抽出一类对象的公共性质并加以描述的过程。 封装:面向对象方法中的封装就是把将抽象出来的对象的属性和行为结合成一个独立的单位,并尽可能隐蔽对象的内部细节。 消息:消息是面向对象程序设计用来描述对象之间通信的机制。一个消息就是一个对象要求另一个对象实施某种操作的一个请求。 填空题 (1) 面向过程的结构化程序设计方法面向对象程序设计方法 (2) 顺序选择循环 (3) 程序=数据结构+算法程序=对象+消息 (4) 过程类 (5) 抽象性封装性继承性多态性 选择题 (1) B (2) C (3) D (4) C (5) D (6) A (7) A (8) B C (9) A D 判断题 (1) t (2) f (3) f (4)f (5) t (6) f (7) f (8) t 简答题 (1) 结构化程序设计方法着眼于系统要实现的功能,从系统的输入和输出出发,分析系统要做哪些事情,进而考虑如何做这些事情,自顶向下地对系统的功能进行分解,来建立系统的功能结构和相应的程序模块结构,有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。 随着程序规模与复杂性的增长,这种面向过程的结构化程序设计方法存在明显的不足之处。首先是数据安全性问题,由于数据被每个模块所共用,因此是不安全的,一旦出错,很难查明原因。其次是可维护性及可重用性差,它把数据结构和算法分离为相互独立的实体,一旦数据结构需要改变时,常常要涉及整个程序,修改工作量极大并容易产生新的错误。每一种相对于老问题的新方法都要带来额外的开销。另外,图形用户界面的应用程序,很难用过程来描述和实现,开发和维护也都很困难。 (2) 面向对象的程序设计方法中,将程序设计为一组相互协作的对象(Object)而不是一组相互协作的函数。在程序中,属性用数据表示,用来描述对象静态特征;行为用程序代码实现,用来描述对象动态特征。可见,在面向对象的程序设计方法中,对象是数据结构和算法的封装体。对象之间存在各种联系,它们之间通过消息进行通信。程序可表示为: 程序=对象+消息 在面向对象程序设计中,它着重于类的设计。类正是面向对象语言的基本程序模块,通过类的设计,来完成实体的建模任务。类通过一个简单的外部接口,与外界发生关系。一个类中的操作不会处理到另一个类中的数据,这样程序模块的独立性、数据的安全性就有了良好的保障。程序的执行取决于事件发生的顺序,由顺序产生的消息来驱动程序的执行。不必预先确定消息产生的顺序,更符合客观世界的实际。并且面向对象程序设计方法提供了软件重用、解决大问题和复杂问题的有效途径,具有抽象性、封装性、继承性和多态性等特点。

什么是面向对象程序设计

1 什么是面向对象程序设计,它与传统的结构式程序有什么不同。 面向对象程序设计是一种适用于设计、开发各类软件的范型。它是将软件看成是一个由对象组成的社会:这些对象具有足够的智能,能理解从其他对象接受的信息,并以适当的行为作出响应;允许低层对象从高层对象继承属性和行为。通过这样的设计思想和方法,将所模拟的现实世界中的事物直接映射到软件系统的解空间。 与传统的结构式程序设计相比,面向对象程序设计吸取了结构式程序设计的一切优点(自顶向下、逐步求精的设计原则)。而二者之间的最大差别表现在: ·面向对象程序采用数据抽象和信息隐藏技术使组成类的数据和操作是不可分割的,避免了结构式程序由于数据和过程分离引起的弊病。 · 面向对象程序是由类定义、对象(类实例)和对象之间的动态联系组成的。而结构式程序是由结构化的数据、过程的定义以及调用过程处理相应的数据组成的 2 用面向对象方法建立模型的思维过程是怎样的。 用面向对象方法建立拟建系统的模型的过程就是从被模拟现实世界的感性具体中抽象要解决的问题概念的过程。这种抽象过程分为知性思维和具体思维两个阶段,其中:·知性思维是从感性材料中分解对象,抽象出一般规定,形成了对对象的普遍认识。·具体思维是从知性思维得到出的一般规定中揭示的事物的深刻本质和规律,其目的是把握具体对象的多样性的统一和不同规定的综合。 3 解释以下概念: ①对象:在现实世界中,对象就是可以感觉到的实体。每个对象具有一个特定的名字以 区别于其他对象;具有一组状态用来描述它的某些特性;具有一组操作,每一个操作决定对象的一种功能或行为(为自身服务的操作和为其他对象提供服务的操作)。而在面向对象系统中,对象是可以标识的存储区域。每个对象的状态被保存在此区域中,而实现一类对象行为的操作(代码)被保存在另外相关的存储器区域中。 ②消息:消息是要求某个对象执行其某种功能操作(方法)的规格说明。因此,消息是 由消息的接收者、消息要求提供的操作(消息名)和必要的参数组成的。 ③类:在现实世界中,类是对一组具有共同特性(属性和行为)的客观对象的抽象。而 在面向对象系统中,类是由程序员自定义的具有特定结构和功能的类型,是一种代码共享的手段。 ④实例:任何一个对象都是该对象所属类的一个具体实例。 ⑤公有消息:是由对象外向对象发送的消息,用于激活该对象的某种方法。 ⑥私有消息:是由对象向自身发送的消息,用于内部操作;该类消息不能从对象外向该 对象发送。 ⑦消息序列:在面向对象系统中一个事件的发生总会有多个对象的多次相互作用才能完 成,使得这些对象能够相互作用的消息组成的序列被称为消息序列。 4 类与实例的关系如何? 类是创建对象的模板,而对象是实现类的实例。属于同一类的不同实例必须具有: ·相同的操作集合; ·相同的静态属性集合; ·不同的对象名和属性动态值。

第3章 面向对象程序设计基础

第3章面向对象程序设计基础

第3章面向对象程序设计基础 【1】什么是Java程序使用的类?什么是类库? 答:类是将一类事物的特性描述出来,然后如果用这个类来定义对象,则该对象就拥有了这个类所描述的所有特性。 在Java系统中,系统定义好的类根据实现的功能不同,可以划分成不同的集合,每个集合称为一个包,所有包合称为类库。 【2】如何定义方法?在面向对象程序设计中方法有什么作用? 答:方法的定义由两部分组成:方法声明和方法体。 方法的声明如下: 返回值类型方法名(参数类型形式参数1,参数类型形式参数2…){ 程序代码; 返回值; } 在面向对象程序设计中,方法的作用是完成对类和对象属性操作。 【3】简述构造方法的功能和特点。下面的程序片段是某学生为student类编写的构造方法,请指出其中的错误。 void Student(int no,String name) {

studentNo=no; studentName=name; return no; } 答:构造方法的功能是:构造方法是一个特殊的方法,主要用于初始化新创建的对象; 特点:构造方法的方法名要求与类名相同,用户不能直接调用,只能通过new运算符调用,而且构造方法是不返回任何数据类型,甚至也不返回void数据类型,即不能在构造方法前加void。 错误之处:(1)构造方法Student()前不能加void,(2)不能用return语句,(3)类名Student 首字母S改成小写s. 【4】定义一个表示学生的student类,包括的域有学号、姓名、性别、年龄,包括的方法有获得学号、姓名、性别、年龄及修改年龄。编写Java程序创建student类的对象及测试其方法的功能。 class Student { String id; String name; String sex; int age; void talk(){

面向对象程序设计教程答案

面向对象程序设计教程(C++语言描述)题解与课程设计指导 第1章 面向对象程序设计概论 一、名词解释 抽象封装消息 【问题解答】 面向对象方法中的抽象是指对具体问题(对象)进行概括,抽出一类对象的公共性质并加以描述的过程。 面向对象方法中的封装就是把抽象出来的对象的属性和行为结合成一个独立的单位,并尽可能隐蔽对象的内部细节。 消息是面向对象程序设计用来描述对象之间通信的机制。一个消息就是一个对象要求另一个对象实施某种操作的一个请求。 二、填空题 (1)目前有面向过程的结构化程序设计方法和面向对象的程序设计方法两种重要的程序设计方法。 (2)结构化程序设计方法中的模块由顺序、选择和循环3种基本结构组成。(3)在结构化程序设计方法中,程序可表示为程序=数据结构+算法;而面向对象的程序设计方法,程序可表示为程序=对象+消息。

(4)结构化程序设计方法中的基本模块是过程;而面向对象程序设计方法中的基本模块是类。 (5)面向对象程序设计方法具有抽象性、封装性、继承性和多态性等特点。 三、选择题(至少选一个,可以多选) (1)面向对象程序设计着重于( B )的设计。 A. 对象 B. 类 C. 算法 D. 数据 (2)面向对象程序设计中,把对象的属性和行为组织在同一个模块内的机制叫做(C )。 A. 抽象 B. 继承 C. 封装 D. 多态 (3)在面向对象程序设计中,类通过( D )与外界发生关系。 A. 对象 B. 类 C. 消息 D. 接口 (4)面向对象程序设计中,对象与对象之间的通信机制是(C )。 A. 对象 B. 类 C. 消息 D. 接口 (5)关于C++与C语言的关系的描述中,(D )是错误的。 A. C语言是C++的一个子集 B. C语言与C++是兼容的 C. C++对C语言进行了一些改进 D. C++和C语言都是面向对象的 【结果分析】 C语言是面向过程的。C++语言是一种经过改进的更为优化的C语言,是一种混合型语言,既面向过程也面向对象。 (6)面向对象的程序设计将数据结构与( A )放在一起,作为一个相互依存、不可分割的整体来处理。

《面向对象程序设计》答案

实验一熟悉VC++IDE开发环境 一、实验目的 1、熟悉VC++6.0集成开发环境,熟练掌握VC++6.0项目工作区、各种编辑器、菜单栏和工具栏的使用。 2、掌握如何编辑、编译、连接和运行一个C++程序。 3、通过运行简单的C++程序,初步了解C++源程序的结构和特点。 二、实验要求 1、分析下列程序运行的结果。 程序一: #include int add(int x,int y=8); void main() { int x=4; cout< void main() { int *p,i; i=5; p=&i; i=*p+10; cout<<"i="< void main(void) { int i=10; int &r=i; r++; cout<<"i="< void func(); int n=1; void main() { static int a; int b= -9; cout <<"a:"<

面向对象程序设计C自学考试课程复习题

(07837)《面向对象程序设计C++》复习题 一、单选题 1.对类成员访问权限的控制,是通过设置成员的访问控制属性实现的,下列不是访问控制属性的是( D ) A. 公有类型 B. 私有类型 C. 保护类型 D. 友元类型 2.下列关于多态性的描述,错误的是( C ) A. C++语言的多态性分为编译时的多态性和运行时的多态性 B. 编译时的多态性可通过函数重载实现 C. 运行时的多态性可通过模板和虚函数实现 D. 实现运行时多态性的机制称为动态绑定 3.在C++语言中,数据封装要解决的问题是( D ) A. 数据的规范化 B. 便于数据转换 C. 避免数据丢失 D. 防止不同模块之间数据的非法访问 4.使用private修饰的成员变量,以下说法正确的是( A ) A. 只能由本类中的函数使用,不能被外面的程序所访问。 B. 可以由本类中的函数使用,也可以被外面的程序所访问。 C. 只能由本类和派生类中的函数使用。 D. 可以在主函数中使用。 5.对类的构造函数和析构函数描述正确的是( A ) A. 构造函数可以重载,析构函数不能重载 B. 构造函数不能重载,析构函数可以重载 C. 构造函数可以重载,析构函数也可以重载 D. 构造函数不能重载,析构函数也不能重载 6.下面对静态数据成员的描述中,正确的是( A ) A. 静态数据成员是类的所有对象共享的数据 B. 类的每个对象都有自己的静态数据成员 C. 类的不同对象有不同的静态数据成员值 D. 静态数据成员不能通过类的对象调用 7.在VC++语言类体系中,不能被派生类继承的有( B ) A. 转换函数 B. 构造函数 C. 虚函数 D. 静态成员函数 8.下面关于句柄正确的说法是( A ) A. 句柄是一个标识Windows资源和设备等对象的变量。 B. 句柄是用户程序自定义的数据类型。 C. 用户程序使用句柄时不需要定义。 D. 句柄仅仅是一个抽象的概念,程序中不能使用句柄。 9.下面关于动态链接库正确的说法是( B ) A. 动态链接库提供的函数,在编译阶段能够连接到应用程序中。 B. 动态链接库提供的函数,在运行阶段能够连接到应用程序中。 C. 动态链接库本身不能单独设计、编译和调试。 D. 动态链接库的使用使得程序缺乏灵活性。 10.下面关于MFC应用程序中InitInstance函数正确的说法是( D ) A. 该函数由用户定义。

面向对象程序设计教程答案

面向对象程序设计教程(C++吾言描述)题解与课程设计指导 面向对象程序设计概论 一、 名词解释 抽象封装消息 【问题解答】 面向对象方法中的抽象是指对具体问题(对象)进行概括,抽出一类对象的公 共性质并加以描述的过程。 面向对象方法中的封装就是把抽象出来的对象的属性和行为结合成一个独立的 单位,并尽可能隐蔽对象的内部细节。 消息是面向对象程序设计用来描述对象之间通信的机制。一个消息就是一个对 象要求另一个对象实施某种操作的一个请求。 二、 填空题 ( 1) 目前有面向过程的结构化程序设计方法和面向对象的程序设计方法两种 重要的程序设计方法。 (2) 结构化程序设计方法中的模块由顺序、选择和循环 3 种基本结构组成。 ( 3) 在结构化程序设计方法中,程序可表示为程序 =数据结构 +算法; 而面向 对象的程序设计方法,程序可表示为程序 =对象 +消息。 ( 4) 结构化程序设计方法中的基本模块是过程; 而面向对象程序设计方法 中的基本模块是类。 ( 5) 面向对象程序设计方法具有抽象性、封装性、继承性和多态性等特点。 三、 选择题(至少选一个,可以多选) ( 1) 面向对象程序设计着重于( B )的设计。 A. 对象 B. 类 C. 算法 D. 数据 ( 2) 面向对象程序设计中,把对象的属性和行为组织在同一个模块内的机制 叫做( C )。 A. 抽象 B. 继承 C. 封装 D. 多态 ( 3) 在面向对象程序设计中,类通过( D )与外界发生关系。 A. 对象 B. 类 C. 消息 D. 接口 ( 4) 面向对象程序设计中,对象与对象之间的通信机制是( C )。 A. 对象 B. 类 C. 消息 D. 接口 (5)关于C++与 C 语言的关系的描述中,(D )是错误的。 A. C 语言是C++勺一个子集 B. C 语言与C++是兼容的 C. C++对C 语言进行了一些改进 D. C++和C 语言都是面向对象的 【结果分析】 C 语言是面向过程的。C++吾言是一种经过改进的更为优化的 C 语言,是一种混 合型语言,既面向过程也面向对象。 ( 6) 面向对象的程序设计将数据结构与( A )放在一起,作为一个相互依 存、不可分割的整体来处理。 A. 算法 B. 信息 C. 数据隐藏 D. 数据抽象 第1

面向对象程序设计(答案)

学号:姓名: 第三章面向对象程序设计作业 一、判断题 1、一个Java源程序可有多个类,但只仅有一个public类,而且程序名与public类名相同。对 2、如果类A和类B在同一个包中,则除了私有成员外,类A可以访问类B中所有的成员。对 3、接口中的成员变量全部为常量,方法为抽象方法。对 4、抽象类可以有构造方法,可以直接实例化。错 5、对static方法的调用可以不需要类实例。对 6、包含抽象方法的类一定是抽象类。对 7、方法中的形参可以和方法所属类的属性同名。对 8、接口无构造器,不能有实例,也不能定义常量。错 9、类的实例对象的生命周括实例对象的创建、使用、废弃、垃圾的回收。对 10、Java应用程序的入口main方法只有一种定义法。对 二、选择题 1、下列答案正确的是(A ) A) 在同一个Java源文件中可以包含多个类,只能有一个被声明为public B) 在同一个Java源文件中只能包含一个类,并被声明为public C) 在同一个Java源文件中可以包含多个类,都可以被声明为public D) 在同一个Java源文件中可以包含多个类,只能有一个被声明为default 2、Java实现动态多态性是通过( B )实现的。 A) 重载B) 覆盖 C) 接口D) 抽象类 3、下列哪一个是正确的方法重载描述( A ) A) 重载方法的参数类型必须不同 B) 重载方法的参数名称必须不同 C) 返回值类型必须不同 D) 修饰词必须不同 4、final关键字不可以用来修饰( D ) A) 类B) 成员方法 C) 域D) 接口 5、接口的所有成员方法都具有( B )属性 A) private, final B) public, abstract C) static, protected D) static 6、Java的封装性是通过(A )实现的 A) 访问控制B) 设计内部类 C) 静态域和静态方法D) 包 7、下列接口或类不属于.*包的是( D ) A) Collection B)Vector C) Map D) Integer 8、下述哪一组方法,是一个类中方法重载的正确写法( A ) A) int addValue( int a, int b ){return a+b;}

《C面向对象程序设计》谭浩强版复习总结

第一章C++ 基础 endl 换行并刷新输出流 setw(n) 设置字段位数为n hex,oct,dec 十六进制,八进制,十进制表示 setfill 定义填充字符 setprecision 定义浮点数的精度 left,right 左对齐,右对齐 showpoint 强制显示小数点以及全部尾部0 C++通过给常量命名的方式定义常量: const<数据类型名><常量名>=<表达式> 用const定义的标识符常量时,一定要对其初始化。在说明时进行初始化是对这种常量置值的唯一方法,不能用赋值运算符对这种常量进行赋值。 函数声明的一般形式为 函数类型函数名(参数表) 函数模板的定义 template 函数定义 例子:template T max(T a,T b){ return(a>b)? a:b; } 定义函数模板时可以使用多个类型参数,每个类型参数前面只需加上关键字typename或class,用逗号分隔: template

例子:template T1 max(T1 a,T2 b){ return (a>b) ? a : (T1)b; } 有默认参数的函数:实参与形参的结合是从左至右进行的,因此指定默认值的参数必须放在形参列表中的最右端 引用 定义对变量起另外一个名字(别名alias),这个名字称为该变量的引用。 <类型> &<引用变量名> = <原变量名>; 其中原变量名必须是一个已定义过的变量。如: int max ; int &refmax=max; refmax并没有重新在内存中开辟单元,只是引用max的单元。max与refmax在内存中占用同一地址,即同一地址两个名字。 对引用类型的变量,说明以下几点: 1、引用在定义的时候要初始化 2、对引用的操作就是对被引用的变量的操作。 3、引用类型变量的初始化值不能是一个常数。 4、一旦引用被声明,它就不能再指向其它的变量。 5、对引用的初始化,可以用一个变量名,也可以用另一个引用。 6、引用同变量一样有地址,可以对其地址进行操作,即将其地址赋给一指针。 当&m的前面有类型符时(如int &m),它必然是对引用的声明;如果前面无类型符(如cout<<&m),则是取变量的地址。 7、对常量(用const声明)的引用使用如下方式: int i=5; const int &a=i;

c+面向对象程序设计试题和答案题目

系名___ ___ ___ ___ 班级___ ___ ___ ___姓名___ ___ ___ ___学号___ ___ ___ ___ 密 封 线 内 不 答 题 一、填空题(每空1分,共14分) 1、观看以下程序: class point{ public: void show() {cout<<”point”<

面向对象程序设计课后答案(完整版)

第二章2-4 #include using namespace std; Add(int a,int b); int main() { int x,y,sum; cout<<"please input x and y:"; cin>>x>>y; sum = add(x,y); cout < using namespace std; int main() {

int *p,*init; int countp=0; int countn=0; p = new int[20]; init = p; for(int i=0;i<20;i++) { cin>>*p; p++; } p = p-20; for( i=0;i<20;i++) { if(*p>0) countp++; if(*p<0) countn++; cout<<*p<<" "; p++; } cout<<"正数有:"< //#include using namespace std; void checkagescore(string name,int age) { if (name == "exit") throw name; if(age<0||age>50) throw age;

C面向对象程序设计教程第版陈维兴林小茶课后习题答案及解析

C++面向对象程序设计教程课后题答案 1.1 什么是面向对象程序设计? 面向对象程序设计是一种新的程序设计范型.这种范型的主要特征是: 程序=对象+消息 面向对象程序的基本元素是对象。 主要结构特点是: 第一,程序一般由类的定义和类的使用两部分组成; 第二,程序中的一切操作都是通过向对象发送消息来实现的。 1.2 什么是对象?什么是类?对象与类之间的关系是什么? 对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体。 类就是具有相同的数据和相同的操作的一组对象的集合,也就是说,类是对具有相同数据结构和相同操作的一类对象的描述。 类和对象之间的关系是抽象和具体的关系。类是多个对象进行综合抽象的结果,一个对象是类的一个实例。 1.3 现实世界中的对象有哪些特征?请举例说明。 现实世界中的对象具有以下特征: 1) 每一个对象必须有一个名字以区别于其他对象; 2) 用属性来描述对象的某些特征; 3) 有一组操作,每组操作决定对象的一种行为;

4) 对象的行为可以分为两类:一类是作用于自身的行为,另一类是作用于其他对象的行为。 例如一个教师是一个对象。每个教师对象有自己的名字来和别的教师区别。教师具有编号,姓名,年龄,职称,专业等属性。教师拥有走路,吃饭,授课等行为操作。走路,吃饭是作用于自身的行为,授课是作用于其他对象的行为。 1.4 什么是消息?消息具有什么性质? 一个对象向另一个对象发出的请求成为“消息”。 消息具有以下3个性质: 1) 同一个对象可以接收不同形式的多个消息,做出不同的相应; 2) 相同形式的消息可以传递给不同的对象,所做出的响应可以是不同的; 3) 对消息的响应并不是必须的,对象可以响应消息,也可以不响应。 1.5 什么是抽象和封装?请举例说明。 抽象是将有关事物的共性归纳、集中的过程。 例如:把所有具有大学生学籍的人归为一类,成为“大学生”,这就是一个抽象。 封装是指把数据和实现操作的代码集中起来放在对象内部,并尽可能隐藏对象的内部细节。 例如:每一台洗衣机都有出厂日期、机器编号等属性,也有启动、暂停、选择等操作。人们在使用洗衣机的时候只需要按下对应的按钮,而不用关心具体的内部实现。这就是封装。 1.6 什么是继承?请举例说明。 继承就是允许派生类使用基类的数据和操作,同时,派生类还可以增加新的操作和数据。

面向对象程序设计完整版

Object- Orien ted Programmi ng C++ 主讲成长生 东华大学计算机科学与技术学院

第一章概述 § 1.1 面向对象程序设计的基本思想 C++是基于C语言发展的,又冲破C语言局限的面向对象的程序设计语言。它与Java 语言都作为当前计算机科学的主流语言, 越来越受到用户的欢迎。 要弄清楚什么是面向对象的程序设计, 首先了解和回顾传统的 ( Pascal(或C))结构化程序设计方法及其设计思想、程序结构及特点。SP(Structure Programming)是60 年代诞生的针对当时爆发的所谓”软件危机” , 为此发展形成了现代软件工程学的基础。 SP的总的设计思想是: . 自顶向下、层次化 . 逐步求精、精细化 程序结构是按功能划分基本模块的树型结构, 使模块间的关系尽可能简单独立。因此SP的程序的基本特点是: . 按层次组织模块(战略上划分战役) . 每一模块只有一个入口, 一个出口 ?代码和数据分离(程序=数据结构+算法) 归纳得到: SP 把数据和过程(代码、函数)分离为相互独立的实体, 用数据代表问题空间中的客体借以表示实际问题中的信 息; 程序代码则用来处理加工这些数据。程序员在编程时 必须时刻考虑所要处理的数据结构和类型。对不同的数据格式即使要作同样

的处理计算, 或者要对相同的数据格式作不同的处理都必须编写不同的程序(如两个整型数和两个浮点数相加)。这样的编程方法,即传统的SP方法设计出来的程序或系统其可重用的成分很少。其次把数据和代码作为不同的分离实体时, 总存在着用错误的数据调用正确的程序模块, 或用正确的数据调用错误的程序模块的危险, 从而使数据与程序始终保持兼容, 已成为程序员 的一个沉重的负担。在开发一个大型软件课题中, 当工程进入到 后期若用户改变了方案要求, 很容易使技术人员的前期工作受到摧毁性的打击,使其前功尽弃。为克服以上的弊端或者该SP方法难以控制处理的矛盾而产生了面向对象程序设计方法, 即Object —Oriented Programming ----------- OOP从二十世纪六十年代提出对象 的雏形, 到七十年代美国国防部的专用语言Ada 语言, 直到当前国际上流行的高品味的Java 和C++(Tc++,Balandc++ 及Vc++), , 应该讲OOP方法与技术吸取了SP的一切优点,同时又正视和顺应现实世界由物质和意识二部分组成。映射到面向对象的解空间就是: 具体事物—对象; 抽象概念—类。 OOP的基本原理是用问题领域的模型来模拟大千世界,从而设计出尽可能直接、自然地表示问题求解方法的软件, 这样的软件由对象组成, 而对象则是完整反映客观世界事物具有不可分割的静态属性(”数据结构” )与动态行为(”方法” )的。而且它们是既有联系又

2016年电大面向对象程序设计技术-作业题

2015秋季学期计算机科学与技术本科 《面向对象程序设计技术》作业题 (在电大在线该课程讨论区跟帖提交,注明姓名和学号以记录成绩)选择题 1.可以在本类及派生类的成员函数中进行访问的访问控制修饰符是(B) A.private B.protected C.public 2.在IDE中将编程项目采用多文件结构下,类的定义一般放在(A) A.头文件 B.程序文件 C.主程序文件 3.内联成员函数在类外定义时要将其和类定义一起放在(A) A.头文件 B.程序文件 C.主程序文件 4.下面哪个内存区域是C++中的运行时动态内存分配区域?( D ) A.代码区 B.栈区 C.数据区 D.堆区 5.对象作为函数参数使用时,一般使用(A)形式 A.引用 B.指针 C.对象拷贝

6.同类的多个不同对象的数据成员值各有不同,但不同对象可以共享类的成员函数代码, 实际调用成员函数时,是通过(B )来区分不同对象的。 A.显式给出不同对象不同地址 B.隐含的this指针 C.引用 7.下面哪一种情况不会自动调用拷贝构造函数。(E) A.用一个对象初始化另一个对象时 B.当一个对象作为值传递给一个函数时 C.当一个对象作为值从一个函数返回之前,该对象被拷贝到栈区 D.函数调用结束后,栈区中的返回对象拷贝给主调程序的对象 E.建立指向对象的指针并初始化指针值时 8.下列哪些对象的数据成员类型可以不用初始化表的方式进行初始化(D) A.常量数据成员 B.引用数据成员 C.类中对象成员 D.一般数据成员 9.下列哪一种类设计一般无需在类中设计静态数据成员以使建立的多个对象共享静态数 据数据成员。( D ) A.一个链表类的头指针和尾指针 B.一个学生类中用于保存建立了多少个学生对象的计数器 C.银行帐号类中的年利率 D.一般只用于建立一个对象的类 10.一个类中的公有(public)性质的静态数据成员,以下哪一种访问方式是错误的(D) A.对象名.静态数据成员名 B.指向对象的指针—>静态数据成员名 C.类名::静态数据成员名 D.类名.静态数据成员名 11.下列哪一个运算符不能够被类所重载(E) A.“.”成员访问运算符 B.“*”成员指针访问运算符 C.“::”域运算符 D.“?:”条件运算符 E.“=”赋值运算符

面向对象程序设计笔记

undeclared identifier “未声明的标识符” (1) 十进制整数:在一个整型常量后面加一个字母 l 或 L,则认为是 long int 型常量? (2) 八进制整数?在常数的开头加一个数字 0,就表示这是以八进制数形 式表示的常数? (3)十六进制整数?在常数的开头加一个数字0和一个英文字母X(或x), 就表示这是以十六进制数形式表示的常数? 2. 浮点数的表示方法 如果在实数的数字之后加字母 F 或f,表示此数为单精度浮点数,如1234F,-43f,占 4 个字节?如果加字母 L 或 l,表示此数为长双精度数(long double), 在Visual C++ 6.0 中占 8 个字节. (2) 指数形式(即浮点形式):用字母 e 表示其后的数是以 10 为底的幂,如 e12 表示 1012? 1.普通的字符常量:用单撇号括起来的一个字符就是字符型常量如′a′,′ #′,′%′,′D′都是合法的字符常量,在内存中占一个字节?“cout<<′\n′; ”将输出一个换行,其作用与“cout<

《面向对象程序设计C 》期末考试试卷

《面向对象程序设计C++》期末考试试卷 一、选择题(每小题3分,共48分。) 01、下列关于C++函数的叙述中,正确的是( C )。 A)每个函数至少要具有一个参数 B)每个函数都必须返回一个值 C)函数在被调用之前必须先声明 D)函数不能自己调用自己 02、下列关于类和对象的叙述中,错误的是( A )。 A)一个类只能有一个对象 B)对象是类的具体实例 C)类是对某一类对象的抽象 D)类和对象的关系是一种数据类型与变量的关系 03、在C++中,用于实现运行时多态性的是( D )。 A)内联函数 B)重载函数 C)模板函数D)虚函数 04、下列关于运算符重载的叙述中,正确的是( B )。 A)通过运算符重载,可以定义新的运算符 B)有的运算符只能作为成员函数重载 C)若重载运算符+,则相应的运算符函数名是+ D)重载二元运算符时,必须声明两个形参 05、对于语句 cout<

相关主题
文本预览
相关文档 最新文档