1、二级 C+-25及答案解析(总分:85.50,做题时间:90 分钟)一、B选择题/B(总题数:35,分数:59.50)1.对下面的程序,正确的说法是U /U。main() int a,b=1,c=2;a=b+c,a+b,c+3;c=(c)? a+:b-;cout a+b,c; A. 无错误 B. 第三行有错误 C. 第四行有错误 D. 第五行有错误(分数:2.00)A.B.C.D.2.下面程序的运行结果是U /U。#includeiostream.hint x=5;int fun(int a)int c;C=X*a;retum c;void main()int x=3,a=4;x=x+fun(
2、a);cout“x“”Xendl; A.x=15 B.x=17 C.x=23 D.x=25(分数:2.00)A.B.C.D.3.关于 this指针的说明不正确的是 A. 不能在程序中修改 this指针 B. this指针可以给其他指针赋值,但不能修改 this指针 C. 静态成员函数中没有 this指针 D. this指针可以被赋值(分数:2.00)A.B.C.D.4.下列程序中,划线处正确的语句是U /U。#includeiostream.hClass BasePublic:Void fun()cout“Base:fun“endl;Class Derived:public Basevoid
3、fun()_ /显示调用基类的函数 fun()Cout“Derived:fun“endl; A.fun() B.Base.fun() C.Base:fun() D.Base-fun(); (分数:1.00)A.B.C.D.5.若有以下程序:#includeiostreamusingnamespacestd;voidsub(intx,inty,int*2)*z=y+x;int main()int a,b,C;sub(8,4,那么下列语句中错误的是U /U。 A.int*p=newlongn; B.int pn; C.int*p=newlong(n); D.int p10;(分数:2.00)A.B
4、.C.D.15.MyClock为一个类,则指向“MyClock a,* p;”语句时,调用该类构造函数U /U次。 A. 1 B. 2 C. 3 D. 4(分数:2.00)A.B.C.D.16.不能作为重载函数的调用的依据是 A.参数个数 B.参数类型 C.函数类型 D.函数名称 (分数:1.00)A.B.C.D.17.有如下程序:#include iostreamvoid fun(intx=y;y=t;int main ()int a2=23,42;fun(a1,a0);std:couta0“,“a1std:endl;return 0;执行后的输出结果是 A. 42,42 B. 23,23
5、C. 23,42 D. 42,23(分数:2.00)A.B.C.D.18.在一个单链表中,若 p所指结点不是最后结点,则删除 p所指结点的后继结点的正确操作是 _。 A. p=pnext B. pnextpnext C. p-next=pnext-next D. p-next=p(分数:2.00)A.B.C.D.19.下列字符串中可以用作 C+语言标识符的是_。 A._1234 B.foobar C.virtual D.34var(分数:2.50)A.B.C.D.20.某二叉树共有 7个结点,其中叶子结点只有 1个,则该二叉树的深度为(假设根结点在第 1层)U /U。 A.3 B.4 C.6
6、D.7(分数:2.00)A.B.C.D.21.假定 int类型变量占用两个字节,其有定义 int x 10;0,2,4;,则数组 x在内存中所占字节数是 A.3 B.6 C.10 D.20(分数:1.00)A.B.C.D.22.关于二义性的描述错误的是 A. 一个子类的两个父类中都有某个同名成员,在子类中对该成员访问可能出现二义性 B. 解决二义性可以用对成员名的限定法 C. 父类和子类中同时出现同名函数,也可能存在二义性 D. 一个子类是从两个父类派生出来的,而这两个父类又有一个共同的父类,对该父类成员进行访问时,可能出现二义性(分数:1.00)A.B.C.D.23.以下非法的赋值表达式是
7、A. n(i2,+i); B. j+; C. +(i+1); D. xj0;(分数:2.00)A.B.C.D.24.下面的语句中错误的是U /U。 A.int a=5;int xa; B.constint a=5;int xa; C.int n=5;int *p=new intn; D.const int n=5;int *p=new inta;(分数:2.00)A.B.C.D.25.有下列二叉树,对此二叉树前序遍历的结果为U /U。(分数:2.00)A.B.C.D.26.数据库、数据库系统和数据库管理系统之间的关系是U /U。 A.数据库包括数据库系统和数据库管理系统 B.数据库系统包括数据
8、库和数据库管理系统 C.数据库管理系统包括数据库和数据库系统 D.3者没有明显的包含关系 (分数:1.00)A.B.C.D.27.执行下列语句后,输出结果为cout.put(s);coutca; A. ca B. sea C. s D. a(分数:2.00)A.B.C.D.28.若调用一个函数,且此函数中没有 return语句,则正确的说法是该函数 A. 没有返回值 B. 返回若干个系统默认值 C. 有返回值,但返回一个不确定的值 D. 能返回一个用户所希望的函数值 (分数:1.00)A.B.C.D.29.设有下列程序段:char s20=“Beijing“,*p;p=s;则执行“p=s;”语
9、句后,下列叙述正确的是U /U。 A.可以用*p 表示 s0 B.s数组中元素的个数和 p所指字符串长度相等 C.s和 p都是指针变量 D.数组 s中的内容和指针变量 p中的内容相同(分数:2.00)A.B.C.D.30.程序中有如下语句 for(int i=0;i5;i+)cout*(p+i)“,“;能够依次输出 int型一维数组 a的前 5个元素。由此可知,变量 P的定义及初始化语句是U /U。 A. int*p=a; B. int p=a; C. *p=a; D. p=a;(分数:2.00)A.B.C.D.31.如果关系模式 R为 1NF,且每个非主属性都完全函数依赖于 R的候选码,则称
10、 R属于 _。 A. 2NF B. 3NF C. BCNF D. 4NF(分数:2.00)A.B.C.D.32.已知 n是一个 int 型变量,下列语句中错误的是_ 。 A. long *p=new long n; B. long pn; C. long *p=new long (n); D. long p10(分数:2.00)A.B.C.D.33.若有如下语句#includeiostream.hvoid main()int x=3;dox=x-2coutx;while (! (- -x);则上面程序段U /U A.输出的是 1 B.输出的是 1和一 2 C.输出的是 3和 0 D.是死循环(
11、分数:1.00)A.B.C.D.34.详细设计的结果基本决定了程序最终的 A. 代码的规模 B. 运行速度 C. 代码质量 D. 可维护性(分数:2.00)A.B.C.D.35.下面程序的运行结果是 _。#includeiostream.hclass Apublicvirtual、() cout”call A: A()”end1;class B:public AB(int i)p=new chari:-B()delete)p;Cout”call B: B()”;;void main() A*a=new B(8);Delete a; A. call B: B() B. call B: B() C
12、. call A:A() D. call A:A()(分数:2.00)A.B.C.D.二、B填空题/B(总题数:15,分数:26.00)36.表达式 operator(x, y) 还可以表示为U /U。(分数:2.00)填空项 1:_37.若有以下程序: #include iostream using namespace std; class Base public: void who() cout“class Base“end1; ; class Derivedl : public Base public: void who() cout“class Derivedl“end1; ; cla
13、ss Derived2 : public Base public: void who() cout“class Derived2“end1; ; int main() Base *p; Derivedl obj1; Derived2 obi2; p= p= p-who ( ); return 0; 则该程序运行后的输出结果是U U /U /U。(分数:1.00)填空项 1:_38.以下程序的输出结果是U /U。 #includeiostream.h void fun( ) static int a0; a2; cout a “ “; void main( ) int cc; for(cc1;c
14、c4;cc) fun( ) ; cout endl;(分数:2.00)填空项 1:_39.按照软件测试的一般步骤,集成测试应在 1 测试之后进行。(分数:2.00)填空项 1:_40.若表达式(x+(y-z)*(m/n)+3 中的变量均为 double型,则表达式值的类型为 1。(分数:2.00)填空项 1:_41.结构化程序设计的三种基本结构分别是顺序、选择和 1。(分数:2.00)填空项 1:_42.若有以下程序: #include iostream using namespace std; class Base public: void who() cout“Base“end1; ; c
15、lass Derivedl: public Base public: void who() cout“Derived“end1; ; int main() Base *p; Derived1 obj1; p= p-who(); return 0; 则该程序运行后的输出结果是U U /U /U。(分数:2.00)填空项 1:_43.在有理数类 Rational中重载插入运算符,以便按 a/q形式输出。请将运算符函数的定义补充完整。 class Rational public: Rational(int aa,int qq):a(aa),q(qq) friend_operator(ostreamo
16、ut,Rationalx) return(outx.a/x.q); private: int a,q; ;(分数:2.00)填空项 1:_44.关系操作的特点是U /U操作。(分数:2.00)填空项 1:_45.C+在重载运算将中,如用成员函数重载一元运算符参数表中需要 _ 个参数,如用友元函数重载一元运算符参数表中需要 _ 个参数。(分数:1.00)填空项 1:_46.用链表表示线性表的突出优点是 1。(分数:2.00)填空项 1:_47.软件维护活动包括以下几类:改正性维护、适应性维护、预防性维护和 1 维护。(分数:2.00)填空项 1:_48.下面程序的输出结果是U U /U /U。
17、#includeiostream.h #includemath.h class point double x; double y; public: point(doublea,d double B) x=a; y=b; friend double distance (point a,point B) ; ; double distance (point a,point B) return sqrt(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); void main() point p1(1,2); point p2(5,2); coutdistance(p1,p
18、2)end1; (分数:1.00)填空项 1:_49.在一个容量为 24的循环队列中,若头指针 front=8,尾指针 rear=3,则该循环队列中共有 1 个元素。(分数:2.00)填空项 1:_50.流操作子 1 可跳过输入流中的前导空白字符。(分数:1.00)填空项 1:_二级 C+-25答案解析(总分:85.50,做题时间:90 分钟)一、B选择题/B(总题数:35,分数:59.50)1.对下面的程序,正确的说法是U /U。main() int a,b=1,c=2;a=b+c,a+b,c+3;c=(c)? a+:b-;cout a+b,c; A. 无错误 B. 第三行有错误 C. 第四
19、行有错误 D. 第五行有错误(分数:2.00)A. B.C.D.解析:解析 第三行是由逗号表达式组成的语句,第四行是由条件表达式组成的语句,第五行 printf语句的输出项为逗号表达式,本题没有语法错误。2.下面程序的运行结果是U /U。#includeiostream.hint x=5;int fun(int a)int c;C=X*a;retum c;void main()int x=3,a=4;x=x+fun(a);cout“x“”Xendl; A.x=15 B.x=17 C.x=23 D.x=25(分数:2.00)A.B.C. D.解析:3.关于 this指针的说明不正确的是 A. 不
20、能在程序中修改 this指针 B. this指针可以给其他指针赋值,但不能修改 this指针 C. 静态成员函数中没有 this指针 D. this指针可以被赋值(分数:2.00)A.B.C.D. 解析:解析 C的 this指针是系统默认产生的一个指针,它是 const的,所以是不能够被改变,不能够被赋值的。4.下列程序中,划线处正确的语句是U /U。#includeiostream.hClass BasePublic:Void fun()cout“Base:fun“endl;Class Derived:public Basevoid fun()_ /显示调用基类的函数 fun()Cout“D
21、erived:fun“endl; A.fun() B.Base.fun() C.Base:fun() D.Base-fun(); (分数:1.00)A.B.C. D.解析:5.若有以下程序:#includeiostreamusingnamespacestd;voidsub(intx,inty,int*2)*z=y+x;int main()int a,b,C;sub(8,4,那么下列语句中错误的是U /U。 A.int*p=newlongn; B.int pn; C.int*p=newlong(n); D.int p10;(分数:2.00)A.B. C.D.解析:15.MyClock为一个类,则
22、指向“MyClock a,* p;”语句时,调用该类构造函数U /U次。 A. 1 B. 2 C. 3 D. 4(分数:2.00)A. B.C.D.解析:解析 *p 不调用类的构造函数,*p 并不定义类对象,而是定义了一个指针指向一个 MyClock 的对象。16.不能作为重载函数的调用的依据是 A.参数个数 B.参数类型 C.函数类型 D.函数名称 (分数:1.00)A.B.C.D. 解析:解析:所谓重载函数是指同一个函数名可以对应多个函数的实现,编译器会根据参数个数、参数类型和函数返回值类型不同而自动调用相应的函数。17.有如下程序:#include iostreamvoid fun(in
23、tx=y;y=t;int main ()int a2=23,42;fun(a1,a0);std:couta0“,“a1std:endl;return 0;执行后的输出结果是 A. 42,42 B. 23,23 C. 23,42 D. 42,23(分数:2.00)A.B. C.D.解析:解析 本题考核函数的调用以及参数值的传递。函数 fun中的第一个参数采用引用传值方式,函数中对形参值的改变同样作用于实参上;第二个参数采用按值传值方式,函数中对形参的操作不会影响到实参。所以 main函数中调用 fun函数后,a1的值被修改为 a0的值,而 a0的值没有改变。18.在一个单链表中,若 p所指结点不
24、是最后结点,则删除 p所指结点的后继结点的正确操作是 _。 A. p=pnext B. pnextpnext C. p-next=pnext-next D. p-next=p(分数:2.00)A.B.C. D.解析:19.下列字符串中可以用作 C+语言标识符的是_。 A._1234 B.foobar C.virtual D.34var(分数:2.50)A. B.C.D.解析:解析 C+语言标识符只能由数字、字母和下画线组成,并且只能以字母和下画线为开头。20.某二叉树共有 7个结点,其中叶子结点只有 1个,则该二叉树的深度为(假设根结点在第 1层)U /U。 A.3 B.4 C.6 D.7(分
25、数:2.00)A.B.C.D. 解析:解析 对于任意一棵二叉树 T,如果叶子结点数为 n0,度为 2的结点数为 n2,二者之间的关系是n0=n2+1,该题中度为 2的结点数为 0,且只有一个叶子结点,因此,树中度为 1的结点有 6个,很容易想到树的高度为 7。21.假定 int类型变量占用两个字节,其有定义 int x 10;0,2,4;,则数组 x在内存中所占字节数是 A.3 B.6 C.10 D.20(分数:1.00)A.B.C.D. 解析:解析 x 数组共有 10个元素,在花括弧内只提供 3个初值,这表示只给前面的 3个成员赋值,后7个元素的值为 0,所以,一共有 20个字节。22.关于
26、二义性的描述错误的是 A. 一个子类的两个父类中都有某个同名成员,在子类中对该成员访问可能出现二义性 B. 解决二义性可以用对成员名的限定法 C. 父类和子类中同时出现同名函数,也可能存在二义性 D. 一个子类是从两个父类派生出来的,而这两个父类又有一个共同的父类,对该父类成员进行访问时,可能出现二义性(分数:1.00)A.B.C. D.解析:解析 基类和其继承类同时出现同名函数,则在继承类中实现对象中调用该函数是使用继承类中的定义,这种情况下是不会产生二义性的。23.以下非法的赋值表达式是 A. n(i2,+i); B. j+; C. +(i+1); D. xj0;(分数:2.00)A.B.
27、C. D.解析:解析 对于任何一种赋值运算,其赋值号或复合赋值号左边必须是一个左值。左值是指具有对应的可由用户访问的存储单元,并且能够由用户改变其值的量。而在 C选项中赋值号对应的是表达式“i+1”,不是一个左值,因此是非法的赋值表达式。24.下面的语句中错误的是U /U。 A.int a=5;int xa; B.constint a=5;int xa; C.int n=5;int *p=new intn; D.const int n=5;int *p=new inta;(分数:2.00)A. B.C.D.解析:25.有下列二叉树,对此二叉树前序遍历的结果为U /U。(分数:2.00)A.B.
28、 C.D.解析:解析 对二叉树的前序遍历是指先访问根结点,然后访问左子树,最后访问右子树,并且在访问左、右子树时,先访问根结点,再依次访问其左、右子树。26.数据库、数据库系统和数据库管理系统之间的关系是U /U。 A.数据库包括数据库系统和数据库管理系统 B.数据库系统包括数据库和数据库管理系统 C.数据库管理系统包括数据库和数据库系统 D.3者没有明显的包含关系 (分数:1.00)A.B. C.D.解析:27.执行下列语句后,输出结果为cout.put(s);coutca; A. ca B. sea C. s D. a(分数:2.00)A.B. C.D.解析:解析 本题很简单,考查 cou
29、t对象的成员函数 put方法和操作符的使用方法。28.若调用一个函数,且此函数中没有 return语句,则正确的说法是该函数 A. 没有返回值 B. 返回若干个系统默认值 C. 有返回值,但返回一个不确定的值 D. 能返回一个用户所希望的函数值 (分数:1.00)A.B.C. D.解析:解析 return 语句的意义和用法。 【解题要点】在 C+语言函数调用中,如果被调用函数中没有retnrn语句,并不带回一个确定的、用户所希望得到的函数值,而是带回的是一个不确定的值。 【考点链接】为了明确表示“不带回值”,可以用 void定义无类型(或称空类型),这时,系统就保证不使函数带回任何值。29.设
30、有下列程序段:char s20=“Beijing“,*p;p=s;则执行“p=s;”语句后,下列叙述正确的是U /U。 A.可以用*p 表示 s0 B.s数组中元素的个数和 p所指字符串长度相等 C.s和 p都是指针变量 D.数组 s中的内容和指针变量 p中的内容相同(分数:2.00)A. B.C.D.解析:解析 程序定义了字符数组 s和字符型指针变量 p,并且使 p指向数组 s的首地址,执行 p=s语句后,*p 表示 s0;s 数组中元素的个数和 p所指字符串长度不相等,s 数细中包括字符串结束标志“/0”,而 p所指字符串不包括“/0”,数组 s中的内容和指针变量 p中的内容不相同,数组中
31、存放的是字符串,而指针变量 p存放的是数组的首地址。30.程序中有如下语句 for(int i=0;i5;i+)cout*(p+i)“,“;能够依次输出 int型一维数组 a的前 5个元素。由此可知,变量 P的定义及初始化语句是U /U。 A. int*p=a; B. int p=a; C. *p=a; D. p=a;(分数:2.00)A. B.C.D.解析:解析 从循环语句中可以看出,是在 04 的循环中输出数组 a中的前,5 个元素,输出的值为*(p+i),即为指针 p向后移动指向的元素。所以初始化要将指针 p指向数组 a,即 int*P=a;。31.如果关系模式 R为 1NF,且每个非主
32、属性都完全函数依赖于 R的候选码,则称 R属于 _。 A. 2NF B. 3NF C. BCNF D. 4NF(分数:2.00)A. B.C.D.解析:32.已知 n是一个 int 型变量,下列语句中错误的是_ 。 A. long *p=new long n; B. long pn; C. long *p=new long (n); D. long p10(分数:2.00)A.B. C.D.解析:解析 静态数组的大小应确定。33.若有如下语句#includeiostream.hvoid main()int x=3;dox=x-2coutx;while (! (- -x);则上面程序段U /U
33、A.输出的是 1 B.输出的是 1和一 2 C.输出的是 3和 0 D.是死循环(分数:1.00)A.B. C.D.解析:34.详细设计的结果基本决定了程序最终的 A. 代码的规模 B. 运行速度 C. 代码质量 D. 可维护性(分数:2.00)A.B.C. D.解析:解析 详细设计阶段的根本目标是确定应该怎样具体的实现所要求的系统,但详细设计阶段的任务还不是具体的编写程序,而是要设计出程序的“蓝图“,以后程序员将根据这个蓝图写出实际的程序代码,因此,详细设计阶段的结果基本上就决定了最终的程序代码的质量。35.下面程序的运行结果是 _。#includeiostream.hclass Apubl
34、icvirtual、() cout”call A: A()”end1;class B:public AB(int i)p=new chari:-B()delete)p;Cout”call B: B()”;;void main() A*a=new B(8);Delete a; A. call B: B() B. call B: B() C. call A:A() D. call A:A()(分数:2.00)A. B.C.D.解析:二、B填空题/B(总题数:15,分数:26.00)36.表达式 operator(x, y) 还可以表示为U /U。(分数:2.00)填空项 1:_ (正确答案:xy)
35、解析:解析 本题考查的是运算符函数的调用,可以像一般函数那样用函数名进行调用,也可通过运算符构成表达式的形式进行调用。37.若有以下程序: #include iostream using namespace std; class Base public: void who() cout“class Base“end1; ; class Derivedl : public Base public: void who() cout“class Derivedl“end1; ; class Derived2 : public Base public: void who() cout“class De
36、rived2“end1; ; int main() Base *p; Derivedl obj1; Derived2 obi2; p= p= p-who ( ); return 0; 则该程序运行后的输出结果是U U /U /U。(分数:1.00)填空项 1:_ (正确答案:class Derived2)解析:解析 本题考核对象指针的应用。主函数中定义了一个 Base类对象指针 p,然后逐步被赋值为obj1和 obj2,最后通过对象指针 p调用函数 who(),也即调用 Derived2中的函数 who(),输出 class Derived2。38.以下程序的输出结果是U /U。 #inclu
37、deiostream.h void fun( ) static int a0; a2; cout a “ “; void main( ) int cc; for(cc1;cc4;cc) fun( ) ; cout endl;(分数:2.00)填空项 1:_ (正确答案:2 4 6)解析:解析 本题考查静态局部变量的使用。用关键字 static 声明的局部变量为“静态局部变量”,其值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次调用该函数时,该变量已有值,就是上一次函数调用结束时的值。39.按照软件测试的一般步骤,集成测试应在 1 测试之后进行。(分数:2.00)填空项 1
38、:_ (正确答案:单元)解析:解析 软件测试过程分 4个步骤进行,单元测试、集成测试、验收测试和系统测试,由此可看出集成测试在单元测试之后进行。40.若表达式(x+(y-z)*(m/n)+3 中的变量均为 double型,则表达式值的类型为 1。(分数:2.00)填空项 1:_ (正确答案:double)解析:解析 表达式左边为 double型,右边为整型,double 型和整型相加仍为 double型。41.结构化程序设计的三种基本结构分别是顺序、选择和 1。(分数:2.00)填空项 1:_ (正确答案:重复(或循环))解析:解析 结构化程序设计包括 3种基本的结构:顺序结构、选择结构和重复
39、结构(循环结构)。利用这 3种结构就足以表达出各种其他结构形式的程序设计方法,其中利用循环结构,可以简化大量的程序执行。42.若有以下程序: #include iostream using namespace std; class Base public: void who() cout“Base“end1; ; class Derivedl: public Base public: void who() cout“Derived“end1; ; int main() Base *p; Derived1 obj1; p= p-who(); return 0; 则该程序运行后的输出结果是U U
40、/U /U。(分数:2.00)填空项 1:_ (正确答案:Derived)解析:43.在有理数类 Rational中重载插入运算符,以便按 a/q形式输出。请将运算符函数的定义补充完整。 class Rational public: Rational(int aa,int qq):a(aa),q(qq) friend_operator(ostreamout,Rationalx) return(outx.a/x.q); private: int a,q; ;(分数:2.00)填空项 1:_ (正确答案:ostream)解析:解析 此题为重载操作符,返回一个输入输出类型。44.关系操作的特点是U
41、/U操作。(分数:2.00)填空项 1:_ (正确答案:集合)解析:解析 在关系操作中,所有操作对象与操作结果都是关系。而关系定义为元数相同的元组的集合。因此,关系操作的特点是集合操作。45.C+在重载运算将中,如用成员函数重载一元运算符参数表中需要 _ 个参数,如用友元函数重载一元运算符参数表中需要 _ 个参数。(分数:1.00)填空项 1:_ (正确答案:0 1)解析:46.用链表表示线性表的突出优点是 1。(分数:2.00)填空项 1:_ (正确答案:便于插入和删除操作)解析:解析 为了克服顺序表中插入和删除时需要移动大量数据元素的缺点,引入了链式存储结构。链表表示线性表的突出优点是插入
42、和删除操作方便,不必移动数据元素,执行效率高。47.软件维护活动包括以下几类:改正性维护、适应性维护、预防性维护和 1 维护。(分数:2.00)填空项 1:_ (正确答案:完善性)解析:解析 软件维护活动包括以下几类:改正性维护、适应性维护、完善性维护和预防性维护。48.下面程序的输出结果是U U /U /U。 #includeiostream.h #includemath.h class point double x; double y; public: point(doublea,d double B) x=a; y=b; friend double distance (point a,p
43、oint B) ; ; double distance (point a,point B) return sqrt(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); void main() point p1(1,2); point p2(5,2); coutdistance(p1,p2)end1; (分数:1.00)填空项 1:_ (正确答案:4)解析:解析 本题考核友元函数的应用。分析程序:类 point中定义了两个私有成员 x和 y,以及一个友元函数 distance。从而,函数 distance可以访问类 point中的任何成员。在函数 distance中,返回值为 sqrt