第八章 函数探幽
2020-02-24 10:33:47 4 举报AI智能生成
C++ plus
C++
模版推荐
作者其他创作
大纲/内容
函数重载
要求
函数的参数列表——函数特征标。即函数的参数数目和类型不同
例子
#1 void print( const char * str ,int width);<br>
#2 void print( double d ,int width);<br>
#3 void print( long l ,int width);<br>
说明
调用时,根据实参数据不同的类型 使用相应的原型。<br>print("Pancakes",15);---#1<br>print(99.0 ,15)---#2<br>print(99L,15)---#3
如果 print( 99 , 15 ) 没有匹配的函数,如果只有一个print 会强制转化<br>有函数重载时,显示错误。
编译器把<b>类型引用和类型</b>本身<b>看成为同一个特征标</b>
void cube( double x)<br>void cube( double & x) //是一样的,不能通过
void dribble( char * bits);---#1<br>void dribble(const char * bits);---#2
是函数重载,根据实参是否为const 类型匹配函数
非const 字符指针参数 可以与#1,#2匹配,这时会调用最匹配的版本。(#1)
<b>返回值不一样</b>,但函数<b>特征标一样</b>的函数<b>不是函数重载</b>
long gronk(int n , float m);<br>double gronk(int n, float m;//not allow)
什么时候使用<br>函数重载
当函数基本上执行相同的任务,但使用不通形式的数据时,采用函数重载
如果只是参数的数量不一样,其它一样,使用默认参数简单些。
名称修饰
含义
根据函数原型中制定的形参类型对每个函数名进行加密
函数模板
创建
代码+说明
template<typename AnyType>
指出创建一个函数模板,类型命名为Anytype。<br>命名可以是其它 例如T。(一般开头为大写??)
作用:告诉编译器如何定义函数。需要交换int 的函数时,编译器按模板模式<br>创建这样的函数,并用int 代替Anytype。
有些实现可以用class替换typename 。考虑兼容问题,一般用typename
void Swap(Anytype &a ,Anytype & b);<br>
如果类型命名为T,应该是void Swap(T &a ,T& b);
Swap不是叫函数,而是叫函数模板(或模板)
int main() <br>{<br>
int a=3,b=4;<br>Swap(a,b);<br>double a=3.0,b=4.0;<br>Swap(a,b);<br>....<br>}
第一个Swap()参数是int ,编译器会生成该函数的int 版本
第二个是double ,编译器生成double版本,用double替换Anytype
template<typename Anytype><br>void Swap(Anytype &a, Anytype &b )<br>{<br>Anytype temp;<br>temp =a ;<br>a=b;<br>b=temp;<br>}<br><br>
还需要在写一次template<typename Anytype>
可以template<typename T1,typename T2><br>Swap(T1,T2)
好处
并不能缩短可执行程序,因为在程序内部还是生成了int 的Swap版本和double版本
使生成多个函数定义更简单,更可靠
重载的模板
作用
不是所有类型都使用一种算法。可以使用重载模板
要求
被重载的模板函数特征标要不一样。
代码
代码
<div>// 功能:</div><div>#include<iostream><br><br></div><div>template<typename T></div><div>void Swap(T &a,T &b);</div><div><br></div><div>template<typename T></div><div>void Swap(T *a ,T *b ,int n);</div><div><br></div><div>int main()</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>using namespace std;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//swap int </div><div><span class="Apple-tab-span" style="white-space:pre"> </span>int a=3,b=4;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>Swap( a,b);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<"now a="<<a<<",b="<<b<<endl;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//swap array</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>int ar[5]={1,2,3,4,5},br[5]={6,7,8,9,10};</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>Swap(ar,br,5);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<"now a[5]=";</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>for(int i=0;i<5;i++)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<ar[i]<<" ";</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<",b[5]=";</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>for(int i=0;i<5;i++)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<br[i]<<" ";</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>return 0;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div>}</div><div>template<typename T></div><div>void Swap(T & a,T & b)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>T temp;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>temp = a ;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>a = b;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>b = temp;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div>}</div><div><br></div><div>template<typename T></div><div>void Swap(T * a,T * b,int n)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>T temp[n];</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>for(int i=0;i<n;i++)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>temp[i]=a[i];</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>a[i]=b[i];</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>b[i]=temp[i];</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>}</div>
说明
第一个模板交换基本类型<br>第二个模板交换数组。
并非所有的模板参数都必须是模板参数类型,第二个模板中,最后一个参数为int
T 就是表明了int ,double ,不能int & ,int *???int &,不可以,int * 可以
template<typename T><br>void Swap(T a, T b)<br>....<br>int main()<br>{<br>int a[],b[];<br>Swap(a,b);<br>....<br>}<br>//T 就是 int * 类型了。
模板局限性
问题
编写的模板可能不适用于一些类型,无法处理某些类型
eg: a = b;如果 a,b为数组则不可以
解决方案
重载运算符
为特定类型提供具体化的模板定义
显式具体化
无法解决的问题
<div>template<typename T></div><div>void Swap(T & a,T & b)<br>当a,b为结构的时候,要交换结构中某一个成员如num,不交换name。<br>参数类型一样,因此无法使用重载模板</div>
原则
一样的函数名,可以有<b>非模板函数、模板函数和显式具体化模板函数</b>以及他们的重载版本
显式具体化的原型和定义以template<>打头,通过名称指定类型
具体化优先于常规模板,非模板函数优先于具体化和常规模板
原型格式
struct job {<br>char name[40];<br>double salary;<br>int floor;<br><br>}
非模板函数
void Swap(job & ,job &);
模板函数
template<typename T><br>void Swap(T&,T&);
具体化
<b>原型</b>声明
template<>void Swap<job>(job &,job &);<br>tempalte<>void Swap(job &,job &);//simple one
子主题
定义
template<>void Swap<job>(job & j1 , job & j2)<div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>double t1;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>t1=j1.salary;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>j1.salary = j2.salary;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>j2.salary = t1;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div>}</div>
例子
template<typename T><br>void Swap(T&,T&);<br><br>tempalte<>void Swap(job &,job &);<br><br>int main()<br>{<br> int a,b;<br> Swap(a,b);//using void Swap(int & ,int &)第一个<br> ....<br><br><br> job Sue={...};<br> job John={...};<br> Swap(Sue,John);//using void Swap(job &,job &)第二个<br>}
实例化和具体化
实例化
含义
代码中包括函数模板本身不会生成函数定义。可以使用模板为特定类型生成函数定义。<br>编译器使用模板为特定类型生成函数定义——得到模版实例。这就是模板实例化
实例化类型
隐身实例化
程序调用Swap()函数时提供了int 参数,编译器才进行函数定义
显式实例化
直接命令编译器创建特定的实例
隐式实例化,显式实例化,显式具体化都称为具体化
如果在一个文件中使用一种类型的显式实例和显式具体化会出错
显式实例化
创建实例化
声明创建
template void Swap<int >(int ,int)
使用Swap()模板创建int类型的函数定义
使用函数创建
Add<double>(m,x);
template<typename T><br>double Add(T a,T b)<br>{<br> return a+b<br>}<br>int m= 6;<br>double x=10.2;<br>double y=Add<double>(m,x);
说明
m的类型是int ,直接Add(x,y)会出错的。
Add<double>()创建一个double类型实例化,将参数m强制转<br>化为double类型(??m实际上类型不改变?创建的是临时变量??)。
但是如果对<br>int m=5;<br>double x=14.3;<br>Swap<doubel>(m,x);<br>//不可以因为 形参是double&,不能只想int 变量m
概念对比
代码
....<br><div>template<typename T></div><div>void Swap(T& ,T &);</div><div><br></div><div>template<>void Swap<job>(job &,job &);</div><div><br></div><div>int main()</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>tempalte void Swap<char>(char & ,char &);//声明的意思:使用Swap()模板生成int类型的函数定义 </div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>short a,b;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>...</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>Swap(a,b);//使用隐式实例化 </div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>job m,n;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>...</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>Swap(m,n);//使用显示具体化 </div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>char g,h;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>Swap(g.h);//使用显示实例化,使用处理显示实例化时生成的模板具体化 </div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>...</div><div>}</div>
对比
显式具体化:<br>template<>void Swap(job &,job &);<br>显式实例化:<br>template void Swap<char>(char &,char &)
编译器选择使用哪个函数版本
书p289-未看
模板函数发展
decltype
作用
template<typename T1,typename T2><br>void....{....<br>T1 x;<br>T2 y;<br>?type xpy =x+y;//type未知
格式
decltype(x+y) xpy
说明
含义是把x+y类型给xpy
decltype(x+y) xpy;<br>xpy = x+y;<br><br>decltype(x+y) xpy = x+y;
经常使用decltype(x+y)可以:<br>typedef decltype(x+y) xytype;<br>xytype spy;<br>xytype arr[10];
double x =5.5;<br>const double &rx=x;<br>decltype(rx) y=x
rx类型给y,包括限定符const ,因为rx是引用,所以y要初始化
遍历核对表
书p296
后置返回类型
作用
template<class T1,class T2><br>?type? gt(T1 x,T2 y)<br>{<br> .....<br> retuen x+y;<br>}
说明
decltype(x+y)不可以因为x+y后面才出现
格式
double h(int x ,int y)<br>auto h(int x,inty) ->double;
auto gt(T1 x,T2 y)->decltype( x+y )
内联函数
原理
常规函数调用时,程序来回在跳跃地址,产生的时间长
内联函数,编译器使用相应的函数代码替换函数调用,使函数的编译代码与其它程序内联起来。<br>
优缺点
提高程序运行速度,但是相对的
如果内联的代码执行时间比函数调用机制长(代码长),不要使用
内联代码(代码短)执行时间短,就可以节省很多时间。
内联函数可以应用于代码短,经常使用的函数。
需要占用更多的内存
程序在10个不同的地方调用同一个内联函数,程序包括10个副本
使用格式
函数声明前加上inline关键字
在函数定义前加上inline 关键字
说明
两个条件之一
通常格式
省略原型,把整个定义放在本应提供原型的地方
代码
include<iostream><br>include<example.h>//需要头文件?<br>inline double square(double x) {return x*x}
说明
内联函数也是按值传递给内联函数的。//如果在主函数中,<br>这个内存将会一直在?
区别宏
#define double(X) X*X
可能会出现错误,改进:#define double(X) ((X)*(X))
宏是文本替换,不是值传递
如果C语言中的宏执行了类似函数的功能,考虑转换为C++内联函数
引用变量
概念
引用是已定义变量的别名。
作用
用作函数的参数,函数可以使用原始数据,不是副本。
创建
int rats;<br>int & rodents =rats;
说明
&不是地址运算符,是类型标识符的一部分,类似于*。
int & 是指向int 的引用
rats , rodents 可以互换,指向相同的值和内存单元
int rats=1;<br>int & radents = rats;<br>radents ++;<br>cout<<rats<<endl;<br>cout<<radents<<endl;
结果: 2<br> 2
必须在声明引用时初始化。
int & rodnets;<br>rodents = rats;//invalid
int & rodents = rats ;<br>int * const pr = &rats;
实际上,上代码是下代码的伪装,<br>引用rodents 扮演的角色与表达式 *pr相同<br>
int bunnies=50;<br>rodents=bunnies;
结果:rats,rodents 的地址不改变,值都变为了50.
这也是不能够不初始化rodents的原因
引用作为函数参数
作用
传递是按引用传递,允许<br>被调用函数访问调用函数的变量
格式
原型:void sum(int &);<br>调用:sum(a);<br>定义:void sum(int & x)
说明
a,x是一个变量,两个名称
可以用于数组吗??没什么特别意义??数组只能是指针,不能引用
传递引用,如果ra是一个变量的别名,则实参应该是该变量。
refcube( <b>x+3.0</b>);<br>int refcube(int &a)//invalid
但是早期的C++允许这样做
临时变量、引用参数和const
临时变量
早期
情况
实参与引用形参不匹配。(类型、变量)<br>eg:refcube(x+3);<br>int refcube(int & ra);<br>程序创建一个临时的无名变量,并初始化为x+3,ra为临时<br>变量的引用。<br>临时变量在函数调用后没有了。ra呢??应该也没有了
修改原因
long a=3,b=4;<br>swapr(a ,b);<br><br>void swapr(int & a,int & b)<br>类型不匹配,创建临时变量,初始化为3,4,交换将临时变量交换<br>实际上,a,b没有交换没有意义。
现在
情况//??
<span>对于引用参数,什么情况下会产生临时变量了?有两种情况:</span><br>但注意:当参数为const 引用时,才允许创建临时变量的情况
1.实参类型正确,不是左值。eg:a+b
左值
左值参数是可被引用的数据对象。eg:变量,数组元素,结构成员,引用和解除引用的指针。<br>不是左值:字面常量(“”的字符串除外),包含多项的表达式。
2.实参类型不正确,可以转换为正确的类型
满足1或2条件,且为const变量。
修改原因
使用const 就表示传递的是值,不修改它们。<br>临时变量不会造成影响,反而时可处理的参数种类更加广泛
不会造成影响是 :不会达不到本来的意图
这样子跟不传递引用差不多。???//为什么说尽量用const 引用?,<br>难道用引用会更加省内存??
右值引用
例子
double &&rref = std::sqrt(36.00);<br>double j =15;<br>double && jref = 2.0* j +18.5;
目的
让库设计人员能够提供有些操作更加有效
引用用于结构
作用
引用主要用于结构和类,<br>就算只是使用值,不用创建副本,可以节省内存和时间
使用方式
和基本变量一样
声明定义
void sum_stu( student & ftu);<br>sum_stu(stu);<br>void sum_stu( student & ftu);<br>
使用
ftu.name
返回结构引用
作用
原型:student & accumulate(student &,student &);<br>dup = accumulate(team,five) <br>accumulate()中修改team ,返回team
如果返回是结构,不是结构的引用,把整个结构<br>复制到一个临时位置,在将这个拷贝复制给 dup。<br>
返回结构引用,直接复制team给dup。<br>此时dup不是team的别名,两者不一样。<br>
格式
student & sum_stu(....);
返回的结构引用<br>可以作左值
如上accumulate(team,five) = dup; //valid
相当于 team = dup,没有用函数修改team的必要
避免这种当左值不报错的情况,最好用const 返回
注意
const student & clone2(student &ft)<br>{<br> student new_guy;<br> new_guy = ft;<br> return new_guy;<br>}<br>不要返回临时变量(new_guy)的引用。(返回类型是引用时)<br>//不要返回指向临时变量的指针。(返回类型是指针时)<br>因为new_guy 执行完程序后不存在。程序不能执行(改成返回结构就能执行)<br>避免这种情况,应返回作为形参的引用。或用new分配新的内存空间.(指针应用多)
临时变量????
临时变量的生成时机通常是在函数参数传递时发生类型转换,以及函数返回值时被创建<br>
<div>const student & copy(student & ftu)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>student *pt;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>pt = &ftu ;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>return *pt;</div><div>}//可以</div>
书中说是可以的,<br><div>const student & copy(student & ftu)</div><div>{</div><div><span class="Apple-tab-span" style="white-space: pre;"> </span>student *pt;</div><div><span class="Apple-tab-span" style="white-space: pre;"> </span>*pt = ftu ;</div><div><span class="Apple-tab-span" style="white-space: pre;"> </span>return *pt;</div><div>}<br>但是我试了,好像不可以。..</div>
引用用于类对象
子主题
可以通过引用,函数把类string,ostream,istream,ifstream等类对象作为参数
用法
与上同 ,把类型变成string 就可以
返回类对象引用
ditto
注意
c-风格字符串用作string对象引用参数
string input;<br>version(input,"***")<br>string & version(string & s1,<b>const string &s2</b>)
1.string 类定义了一种 char * 到 string 的转换功能,使c-风格字符串可以初始化为string对象
2.<b>const 可以创建一个临时变量,传递一个指向临时变量的引用</b>
<b>所以 形参类型为const string & ,使用的实参可以是引号字符串字面值,以空字符结尾的char <br>数组,指向char 的指针变量</b>
对象、继承、引用
继承
继承含义
将特性从一个类传递到另一个类的语言特性
eg:ofstream对象可以使用ostream的方法
ostream是基类,fstream是派生类。派生类继承基类的方法
继承特征
基类引用可以指向派生类对象,<br>无需进行强制类型转换
调用函数实参——ostream \ ofstream 对象<br>定义函数形参—— ostream 对象
代码
代码
<div>// 功能:把数组输入到文件中和显示到屏幕中 </div><div>#include<iostream></div><div>#include<fstream></div><div>#include<stdlib.h></div><div>using namespace std;</div><div><br></div><div>void file_in(ostream & os , int eps[] ,int n);</div><div>const int LIMIT = 5;</div><div>int main()</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>int eps[LIMIT]={1,2,3,4,5};</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>ofstream fout;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>fout.open("output.txt");</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>if(<b> !fout.is_open()</b>)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>cout<<"open error!"<<endl;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>exit(EXIT_FAILURE);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>file_in (fout,eps,LIMIT);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>file_in(cout,eps,LIMIT);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>fout.close();</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>return 0;</div><div>}</div><div>void file_in(ostream & os , int eps[] ,int n)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>int i;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>for(i=0;i<n;i++)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>os.width(8);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>os<<eps[i];</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>}</div>
<span>exit(0);表示在正常下结束程序 </span><br><span>exit(1);表示强制结束程序 </span><br><span>这在Win32下正确.</span><br><span>不过为了可移植性好,</span><br><span>最好按照ISO2003标准写成:</span><br><span>exit( EXIT_SUCCESS );</span><br><span>exit( EXIT_FAILURE );</span><br><span>其中EXIT_SUCCESS和EXIT_FAILURE是在</span><br><span>cstdlib中定义的.</span>
说明
<div>file_in (fout,eps,LIMIT);</div><div>file_in(std::cout,eps,LIMIT);<br>void file_in(std::ostream & os , int eps[] ,int n)<br></div>
os 代替 cout 和 fout ofstream对象
os.width(8);——字段宽度,只能用于下一个(一个!)输出
os.precision(2);——后显示两个小数点
os.setf(ios::showpoint)——显示小数点模式,即使是整数。
ios_base::fmtflags initial;<br>initial = os.set(ios_base:: fixed);//save initial formatting state<br>.......<br>os.setf(initial);//restore initial formatting state
作用
每个对象都存储了自己的格式化设置<br>当cout被引用时候,中间的os。setf(....) 设置了cout 的格式化。<br>需要在函数结束时回复cout原来的格式。不要会一直存储着
恢复类对象格式
ios_base::fmtflags initial;<br>initial = os.set(ios_base:: fixed);//save initial formatting state<br>.......<br>os.setf(initial);//restore initial formatting state
使用
使用引用参数原因
修改调用函数中的数据对象
通过传递引用不是整个数据对象,提高程序的运行效率
指导原则
传递值而不作修改
按值传递
数据对象小,eg内置数据类型、小型结构
指针
数据对象是数组,指针声明为const 的指针
数组只能使用指针
数据对象是较大的结构 ,const 指针
引用
数据对象是较大的结构 ,const 引用
节省复制结构所需要的时间和空间
数据对象是类对象,用const引用
<b>传递类对象的标准方式是按引用传递</b>
修改调用函数中的数据
指针
数据对象是内置数据类型
数据对象是数组,只能使用指针
结构
引用
结构
类对象
修改是修改类对象的格式把。注意复原
默认参数
含义
函数调用时候省略了实参
好处
提高了使用函数的灵活度
定义方法
int harpo(int n, int m =4 ,int j =5);<br>harpo(2);<br>int harpo(int n,int m,int j)
说明
要在函数原型中设置,函数定义与没有默认参数时完全一样
harpo(2) //same as harpo(2,4,5)<br>harpo(2,6)//same ad harpo(2,6,5)
设置失效的情况
int harpo(int n=1 ,int m ,int j =5)// invaild
原因
实参从左到右传递参数,不允许逃过任何参数<br>harpo(2,,5)是不要可以de
要求
必须从右到左添加默认值
其它
传递数组(形参是指针) —— 不可以用sizeof()确定数组的长度,<br>但是形参是字符串指针的时候,可以用strlen()确定字符串的长度
自由主题
评论
0 条评论
下一页