C语言程序设计课件 第6章_第1页
C语言程序设计课件 第6章_第2页
C语言程序设计课件 第6章_第3页
C语言程序设计课件 第6章_第4页
C语言程序设计课件 第6章_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章函数6.1函数定义和声明6.2函数调用过程6.3函数的递归与嵌套调用6.4作用域与存储类型6.5函数与数组6.6函数的综合示例本章小结

6.1函数定义和声明

6.1.1函数定义的一般形式

函数定义的一般形式为函数类型说明函数名(形参说明表){说明部分;执行部分;}

6.1.2函数定义的要点

1.函数类型的说明

如上所述,函数类型指函数返回值的数据类型。函数返回时可能得到0个数据、1个数据或多个数据。

1)函数无返回值

如果函数没有返回值,则一般在定义函数时把函数类型写为void。例如:

voidPRINT()

{

printf("Test\n");

}

2)函数有1个返回值

如果函数有1个返回值,则在被调用函数的函数体中有return语句。此时函数类型的定义应根据return语句后的表达式的数据类型来定义。例如:

intmax(inta,intb)

{

returna>b?a:b;

}

3)函数有多个返回值

如果函数有多个返回值,则在被调函数的函数体中一般无return语句。多个值的返回是通过全局变量、数组或指针来实现的,这将在后面的章节中进行介绍。

2.函数的命名

函数名是函数的标识,函数的命名规则与变量命名规则相同。通过引用函数名,可调用该函数。

3.形参表及形参的说明

1)形式参数

在函数定义中写在圆括号中的参数称为形式参数(简称形参)。不带形参的函数其形参表有两种表现形式:一是形参表空着,二是在形参表中写上“void”以确定没有形参。例如:

voidPRINT(void)

{

printf("Thisisaexample\n");

}

两种表现形式的区别:若形参表空着,则在函数调用时,给一个或多个实在参数(简称实参),编译器不会提示有错误或警告;若形参表中写“void”,在函数调用时,给一个或多个实参,则编译器会给出警告“warningC4087:'PRINT':declaredwith'void'parameterlist”。

有形参函数的形参表由一个或多个形参组成,各参数间用逗号分隔,且必须给出每个参数的数据类型。

2)函数间利用参数传递数据

函数间通过参数传递数据,是指将调用函数中的实参向被调用函数中的形参按从右向左顺序依次传递。

实参向形参传递数据是指实参将值单向传递给形参,形参值的变化不传递给实参。其原因在于每次调用函数,都必须给形参分配新的空间,而不是复用原来实参空间,

因此修改形参不会影响实参。

例如:

即实参a、b两个变量的值没有得到交换。这里用图6-1来表示swap()函数调用开始时和结束后各参数的值。

图6-1swap函数调用过程中各参数的变化

5.主函数的定义

本书采用VisualC++2010Express作为集成开发环境。对于main()函数的定义特进行如下说明:

(1)同样的main()函数定义和源码,源文件的扩展名为“.c”时的编译结果与扩展名为“.cpp”时的编译结果可能不同,建议扩展名用“.c”,以确定采用C语言(而不是C++语言)的语法规则编译程序。

(2)对于C语言主函数的定义,在C99中规定了如下两种标准格式。

① intmain(void)

② intmain(intargc,char*argv[])

(3) VisualC++2010Express主要是用于C++程序开发的,对于C语言,兼容C89标准,因此,本书有些C程序中的main()函数仍然定义成main(){……}这种简单的形式。

(4)虽然VisualC++2010Express允许voidmain()的定义,但也要少用。因为这种用法不符合C99标准,很多编译器不支持。

(5) main()函数的返回值用于说明程序的退出状态。

综上所述,我们可以得出如下结论:

(1)如果C程序单纯只考虑能在VisualC++2010Express中编译通过,则主函数的定义形式几乎不受限制,可以定义成main(){……}这种简单的形式,也可以定义成voidmain(){……}。

(2)如果C程序要考虑可移植性,则要遵循主流标准。调试C/C++程序,符合C99标准及C++98标准的主函数定义形式为

6.1.3函数的声明

定义好的函数需要调用时,一般应在主调函数中对被调函数进行声明,即向编译系统声明将要调用此函数,并将有关信息(如被调用函数名、函数类型、形参的个数及类型等)通知编译系统。

函数声明的格式如下:

函数类型说明函数名(形参及其类型);

函数声明又称为函数接口(Interface)或接口说明,这种格式很像函数的定义,初学者很容易混淆。其实,它们的区别是很明显的:函数定义具有函数体,且在源程序中只能定义一次;函数声明没有函数体,且在不同的主调函数中可多次出现。

函数从来源上分,有系统库函数和用户自定义函数两种。

对于库函数的接口说明,系统按功能不同组成相应的头文件,如所有数学函数接口说明头文件为“math.h”,标准输入/输出库函数接口说明头文件为“stdio.h”。如果调用系统库函数,必须用预编译命令“#include”把相应的头文件包含在源程序的首部,之后就不必再进行接口说明了。例如,在某函数中调用数学函数sqrt(),则在源程序的开头加命令:

#include<math.h>

对于用户自定义函数,若被调函数定义在主调函数之前,可缺省函数接口声明;若被调函数定义在主调函数之后,则一定要进行函数接口声明。

6.2函数调用过程6.2.1函数调用的一般形式一个C程序是由一个或多个独立的函数组成的,在一个函数中引用另一个函数,称为函数的调用。其中引用另一个函数的函数,称为主调函数,被引用的函数,称为被调用函数。主调函数中的参数,称为实在参数,而被调用函数中的参数称为形式参数。一般地,主函数main()只能被操作系统调用,不能被其他函数调用;主函数main()可以调用库函数或其他函数;除主函数main()外,其他函数之间可以互相调用。

在一个程序中,通过函数调用将各函数联系在一起,程序总是从main()函数开始执行并调用所需要的函数,完成所调用函数的功能后,返回到main()函数继续执行,最后当main()函数执行完毕,整个程序运行结束。假设有main()函数和fun()函数,它们的调用过程如图6-2所示。图6-2函数调用执行过程示意图

一般函数的调用执行过程归纳如下:

(1)为被调用函数的所有形式参数分配内存,并将实在参数的值,按从右向左的方式一一对应地赋给相应的形式参数(对于无参函数,不做此工作)。

(2)程序控制由主调函数进入被调函数的函数体,之后依次执行被调用函数中变量定义部分,为局部变量分配存储空间,执行函数体中的可执行语句。

(3)当执行到“return”语句时,计算返回值(如果是无返回值的函数,不做这项工作),之后释放本函数中定义的局部变量和形式参数所占用的存储空间(对于static类型变量,其空间不释放),最后返回主调函数继续执行其他语句。

例6-4从键盘输入两个整数,求较大的整数。

程序执行的简单过程如下:①程序从main()函数开始执行,当执行到main()函数体第三行“c=max(a,b);”时,调用max()函数,把实在参数b、a的值传递给函数max()的形式参数y、x,并在主函数的该处设置函数断点,然后系统转去执行函数max()的函数体;②max()函数比较由主函数传递来的两个整数,然后执行return语句返回到主调函数的断点处,并将函数的返回值也传送给主调函数;③main()函数将max()函数的返回值赋给主调函数的内部变量c,程序继续往下执行,输出较大数,此时主函数执行完毕,整个程序运行结束。

6.2.2函数调用的参数传递

对带有参数的函数进行调用时,存在着如何将实参传递给形参的问题。根据实参传递给形参值的不同,参数传递通常有值传递方式和地址传递方式两种。

1.值传递方式

所谓值传递方式是指函数调用时,为形参分配内存单元,并将实参的值复制到形参中,当调用结束后,形参所占内存单元被释放,实参的内存单元仍保留并维持原值。

例6-5函数参数的值传递方式示例。

该程序首先在main()函数中定义了两个整型变量x和y,其初始值分别为7和11,然后调用swap()自定义函数试图交换x、y的值,可结果是,调用函数swap()以后,x和y的值并没有交换,x仍然是7,y仍然是11。为什么会出现这种情况呢?

这是因为实参x和y对应的内存单元与形参a和b所对应的内存单元是各不相同的,在函数调用时,只是将x的值7传递给形参a,y的值11传递给形参b,在swap()函数体内只是将a和b的值交换了,即a的值变为11,b的值变为7,当函数返回时,a和b的内存单元就释放了,x和y所对应的内存单元并没有进行任何的改变。这就好像是我复印一份文件给你,在你的文件上修改都不会改变我的文件一样。该程序函数参数调用的过程如图6-3所示。图6-3函数参数值传递方式示意图

2.地址传递方式

所谓地址传递方式是指,函数调用时将实参数据的存储地址作为参数传递给形参。其特点是形参与实参占用同样的内存单元,函数中对形参值的改变也会改变实参的值。因此函数参数的地址传递方式可实现调用函数与被调函数之间的双向数据传递。注意,实参和形参必须是地址常量或变量。

6.3函数的递归与嵌套调用

6.3.1函数的递归调用C语言中除允许一个函数调用其他函数外,还允许函数自己调用自己,这种函数称为递归函数。

1.递归概念

函数的递归调用是指一个函数在它的函数体内直接或间接地调用它自身。因此,递归调用有两种方式:直接递归和间接递归。直接递归指的是函数直接调用自身的过程,如图6-4(a)所示;间接递归指的是一个函数通过其他函数调用自身的过程,如图6-4(b)所示,函数1调用函数2,函数2又调用函数1。

图6-4两种递归调用示意图

例如:

fact(intn) /*fact函数定义*/

{

t=n*fact(n-1);

}

上述函数fact()中,函数fact()又要调用函数本身,它是直接递归。而递归函数怎么定义呢?以fact(n)=n!为例。因为

由①、②两式可得fact(n) = n × fact(n - 1)。假设想求fact(5)的值,则必须先求得fact(4)的值,同理想求fact(4)的值,则必须求fact(3)……,因而会无限地往下递归,程序无法得到终止。在调用过程中假设fact(1)=1,将值回代,则可得fact(2)的值,同理可得fact(3)、fact(4)的值,最后将其值回代得到fact(5)的值。因此,函数递归调用一定要有递归终止的条件,即当传递过去某个值时,函数值不再调用函数本身,而是一个确定值或过程。这也说明,递归函数的定义应包括两部分:函数的递归关系和函数递归终止条件。

2.递归举例

例6-6用递归法求fact(n) = n!。

计算阶乘可用如下形式描述:

它的递归调用和值的回代过程(设n = 5)如图6-5所示。主函数对fact(5)进行0级调用时,n=5,不满足n==1的条件,此时必须进行1级调用,得到fact(4)的值后,才能得出“fact(5)=5*fact(4)”。同样,计算fact(4)时需进行2级调用,即调用fact(3)。计算fact(3)要进行3级调用,即调用fact(2)。计算fact(2)需进行4级调用,即调用fact(1),此时n=1,满足条件n==1,得到p=1。返回p=1,即fact(1)返回至上层调用函数fact(2)处,得到“p=2*1=2”。

返回p=2,即fact(2)返回至上层调用函数fact(3)处,得到“p=3*2=6”。返回p=6,即fact(3)返回至上层调用函数fact(4)处,得到“p=4*6=24”。返回p=24,即fact(4)返回至上层调用函数fact(5)处,得到“p=5*24=120”。返回p=120,即fact(5)返回至上层调用函数main()处,输出运算结果。

图6-5递归调用和值的回代

例6-8汉诺塔问题。

有3个塔,每个都可以堆放若干个盘子。开始时,所有盘子均在塔A上,并且,盘从上到下,按直径增大的次序放置(如图6-6所示)。设计一个移动盘子的程序,使得塔A上的所有盘子借助于塔B移到塔C上。这里有两个限制条件:一是一次只能搬动一个盘子,二是任何时候不能把大盘子放在比它小的盘子的上面。图6-6汉诺塔问题示意图

解题思路要移动这n个盘子,可以定义一个函数:

move(n,a,b,c)

其中,字符型变量a、b、c分别表示A、B、C3个塔,函数move(n,a,b,c)表示将n个盘子从塔A(借助于塔B)移到塔C上。这个问题可以使用递归调用方法解决,在n > 0的前提下,函数move(n,a,b,c)通过下列3步实现移动。

(1)调用move(n-1,a,c,b),即将n-1个盘子从塔A(借助于塔C)移到塔B上。目的是让塔A上的第n个盘子(最下面的盘子)上无其他盘子。

(2)将底下的第n个盘子从A塔移到C塔。

(3)调用move(n-1,b,a,c),即将n - 1个叠放在塔B上的盘子(借助于塔A)移到C塔。

6.3.2函数的嵌套调用

将孤立的函数堆砌在一起并不能建立关系,实现程序的功能。程序中的函数需要通过相互调用建立关系。C语言规定,在一个函数内部不允许再定义函数,即函数不可嵌套定义,但是允许一个函数调用另外一个函数,这个被调用的函数还可以调用其他的函数,以形成任意深度的调用层次。这就是函数的嵌套调用。图6-7给出了函数嵌套调用的示意图。

图6-7函数嵌套调用的示意图

例6-9计算s = 2²! + 3²!。

解题思路本题可编写两个函数,一个是用来计算平方值的函数f1,另一个是用来计算阶乘值的函数f2。主函数先调f1计算出平方值,再在f1中以平方值为实参,调用f2计算其阶乘值,之后返回f1,最后返回主函数,在循环程序中计算累加和。

6.4作用域与存储类型

6.4.1作用域与生存期1.作用域所谓变量的作用域,就是指某个变量在其生存期内可被使用的范围。C语言中有两种变量:一种变量只能在所定义的模块内部有效,称为局部变量或内部变量;另一种变量从定义点开始至整个源程序结束都有效,称为全局变量或外部变量。

1)局部变量

局部变量指在函数或复合语句中定义的变量,只在本函数或复合语句范围内有效(从定义点开始到函数或复合语句结束),即只有在本函数或复合语句内才能使用它们,在此函数或复合语句以外是不能使用它们。

注意:

(1)主函数中定义的变量也只在主函数中有效,而不因为是在主函数中定义的而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。

(2)不同函数中可以使用相同名称的变量,它们代表不同的对象,互不干扰。例如,在f1函数中定义了变量b和c,倘若在f2函数中也定义变量b和c,它们在内存中占不同的单元。

(3)形式参数也是局部变量。在函数中可以使用本函数声明的形参,在函数外则不能引用。

(4)在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效。

2)全局变量

局变量指在函数之外定义的变量。全局变量的有效范围为从定义点开始到本源程序结束。在此范围内它可以被本程序中所有函数所使用。在一个函数中既可以使用本函数中的局部变量,又可以使用有效的全局变量。

2.生存期

所谓变量的生存期,就是变量存活的周期。程序中的变量都要占用一定的内存空间,但并不是所有的变量在程序开始执行时就占用内存。为了节省内存,避免变量互相干扰,不可能让所有的变量始终存在,因此只有在必要时才为变量分配内存。当变量占用内存时,变量就生成了。当变量不再有用时,程序将释放变量所占用的内存,变量就撤销了。变量从被生成到被撤销的这段时间称为变量的生存期。它实际上就是变量占用内存的时间。

6.4.2变量的存储类型

由变量的生存期可知,有的变量在程序运行的整个过程都是存在的,而有的变量则是在调用其所在的函数时才临时分配内存单元,而在函数调用结束后就马上释放了,变量也不再存在了。因此变量的存储有两种情况:一是变量从定义点开始就被分配内存单元(即产生),直到程序运行结束才释放内存,这种方式称为静态存储方式;二是变量带有临时性,随调用的模块(如文件、函数或复合语句)分配内存单元,模块调用结束,释放内存,这种方式称为动态存储方式。

全局变量采用静态存储方式,程序开始执行时给全局变量分配内存空间,程序执行完毕释放。在程序执行过程中它们占据固定的存储单元,而不是动态地进行内存分配和释放。在函数中定义的变量,在函数调用开始时分配动态存储空间,函数结束时释放这些空间。在程序执行过程中,这种分配和释放是动态的。

C语言中变量的定义有两个属性:一是定义变量的数据类型;另一个是定义变量的存储类型。变量的数据类型规定了变量的存储空间大小和取值范围,变量的存储类型规定了变量的生存期和作用域。因此,定义一个变量的一般形式为

[存储类型]数据类型变量标识符表;

其中[]内为可选项。

不同存储类型的变量在计算机内部的存放位置是不同的。不同的存放位置决定了变量的存储类型,这也就决定了变量的生存期和作用域。变量可以存放在内存中的动态数据存储区或静态数据存储区中,也可以存储在CPU的寄存器中。

变量的存储类型有4种,分别是自动型、寄存器型、外部型和静态型,其说明符分别是auto、register、extern和static。下面结合程序示例,分别说明它们各自的生存期和作用域。

1.自动型(auto)

在各个函数或复合语句内定义的变量,也称为自动变量。自动变量用关键字“auto”进行标识,可缺省。

例如,在例6-4中的程序中,主函数main()的函数体中定义了3个自动变量a、b、c;在max()函中定义了1个自动变量z(形参也为自动变量)。当程序运行main()函数时,系统为a、b、c变量分别分配内存单元;在调用max()函数时,系统为max()函数的形参x、y和自动变量z分配内存单元,即生命开始,调用结束释放x、y、z的空间,即生命结束,其寿命为函数调用开始到结束期间,称为局部寿命。x、y、z的使用也只能在max()函数内部,这称为局部可用。

2.寄存器型(register)

如果有一些变量使用频繁(例如,在一个函数中执行1000000次循环,每次循环中都要引用某局部变量),则要为存取该变量的值花不少时间。为提高执行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要用时直接对寄存器读写数据。存储类型为寄存器型的变量称为寄存器变量。由于CPU的通用寄存器数量有限,在程序中允许定义的寄存器变量一般以少于8个为宜。如果定义为寄存器变量的数目超过系统所提供的寄存器数目,编译系统自动将超出的变量设为自动型存储类型。由于在计算机中对寄存器的读写速度远远高于对内存的读写速度,因此这样可以提高执行效率。寄存器变量用关键字register声明。

3.外部型(extern)

定义在所有函数(包括主函数)外部的变量称为外部变量。外部变量是一种全局变量。

1)外部变量的特性

对于外部变量,系统在编译时是将外部变量的内存单元分配在数据存储区,在整个程序文件运行结束后系统才收回其存储单元。因此外部变量的作用域是从外部变量定义点开始到源程序运行结束,即外部变量的寿命是全局的。在定义点之后的所有函数,都可以使用外部变量,也就是说其作用域也是全局的。

例6-12求ax2 + bx + c = 0(a ≠ 0)的根。

解题思路在a≠0的情况下。根据b2 - 4ac的不同值,方程分别有两个不等的实根、两个相等的实根和两个共轭的虚根。如果传递方程的3个系数a、b、c给函数,分别求出方程的根,则上述3种情况都需要返回两个数据,由于这里通过return语句无法实现,因此可借用外部变量实现。

程序开头的语句“floatx1,x2;”定义的是两个外部变量x1、x2,编译时分配x1、x2的存储空间,程序运行期间其空间一直存在。在其后定义的f1()函数、f2()函数、f3()函数和main()函数都可以引用变量x1、x2,也就是说在f1()函数、f2()函数、f3()函数中改写x1、x2值,就可以在main()函数中输出对应x1、x2值。这实现了不同函数之间的数据共享或通信。

2)外部变量的引用

外部变量的作用域是定义点开始到源程序的结束。若在定义点之前或别的源程序中要引用外部变量,则在引用该变量之前,需进行外部变量的引用说明。

外部变量的引用说明的一般形式为

extern外部变量数据类型外部变量名表;

一个C程序可以由很多个程序文件组成,每个文件称为一个编译单位。外部变量主要用于在多个编译单位间传递数据。若两个编译单位A和B需要交换信息,可在编译单位A中定义一个外部变量A,并把信息存放在其中,编译单位B要引用该变量需把该变量说明为外部型,告诉系统该变量在其他编译单位中已经定义了。

4.静态型(static)

静态变量是分配在内存中的。它们在程序开始运行时就分配了固定的存储单元,在程序运行过程中不释放,直到程序运行结束才释放它所占的存储空间。如果用static说明外部变量为静态型,则该外部变量只能在本程序中使用。

1)静态局部变量

静态局部变量是定义在函数体的复合语句中,用关键字“static”进行标识的变量。静态局部变量定义的一般形式为

static变量数据类型变量名表;

对于静态局部变量,系统在编译时将其内存单元分配在静态数据存储区,直到程序运行结束,对应的内存单元才释放。静态局部变量只有在编译时可以赋初值,以后每次调用时不再分配内存单元和初始化,只是引用上一次函数调用结束时的值。其作用域只限于其所定义的函数或复合语句中。因此静态局部变量是一种具有全局寿命、局部可用的变量。

2)静态全局变量

定义在所有函数(包括主函数)之外,用关键字“static”标识的变量,称为静态全局变量。静态全局变量和外部变量有共同点:都具有全局寿命,即在整个程序运行期间都存在。但二者在使用上有区别:静态全局变量只能在所定义的文件中使用,具有对文件的局部可见性;而一般的外部变量可以在所有文件中使用。

6.5函数与数组

6.5.1函数和一维数组1.一维数组元素作为函数的实参由于数组元素与相同类型的简单变量地位完全一样,因此,数组元素作为函数参数也和简单变量一样,采用值的单向传递方式。

例6-17用一维数组score存放一学生6门课程的成绩,并将成绩依次输出。

2.数组名作为实参、形参

前面已经介绍过,在一维数组中,用“数组名[下标]”表示的数组元素相当于一个普通变量;而不带下标的数组名代表一批变量,也可以把它看成一个特殊的变量,因为它存

放该数组的首地址(即数组首元素的地址)。

在函数中,直接用数组名作为参数时,则传送的是地址值,即把实参数组的首地址传

递给形参数组,而不是将全部数组元素都复制到函数中去。地址传递后,实参数组、形参数组地址相同,共享相同的内存单元,也就是说形参数组和实参数组其实就是同一个数组,只是它们的生存期与作用域不同而已。

例6-18有一个一维数组score,存放一个学生6门课程的成绩,求平均成绩。

在本例中,实参数组名为score,形参数组名为array。在主程序的函数调用average(score)时,实参数组score[6]通过数组名score把首地址传给array后,则array和score共享实参数组所占用的内存空间,也就是说形参数组array和实参数组score其实就是同一个数组,只不过是有两个名字而已,如图6-9所示。

图6-9数组array和数组score共享相同的内存空间

编译系统对形参数组大小不进行检查,因此形参数组可以不指定大小,在数组名后跟一对空的方括号即可,即其大小由相应的实参数组决定。在调用时将实参数组的首地址传给形参数组,也就是说,形参数组并不在内存中重新申请数组的空间,而是和实参数组共享存储单元。但要注意,实参数组和形参数组类型应保持一致。如在上例中,实参数组score和形参数组array的元素类型都为float类型。

例6-19从键盘输入一字符串,判断字符串长度并输出(不使用strlen()函数)。

例6-20把一个数字字符串转换成长整型数(不使用atol()函数)。

本节在分析函数调用过程的参数传递问题时,特别强调要区分实参向形参传递的是“值”还是“地址”。严格说来,“地址”也是值(地址值),但通过前面两个例子的分析可以看出,它们有一个显著的区别:即“值传递”在实参将“值”传递给形参后,对形参的修改不会影响到对应的实参,这可以理解为实参和形参各自占用不同的存储空间,实参在将“值”传递给形参后,二者就脱离关系了;而“地址传递”在实参将“地址”值传递给形参后,形参就和实参共享同一存储区,而不另外分配存储空间,这可以理解为形参名和实参名只是同一存储单元的两个不同名称而已,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论