天天看点

C++ 回忆录5

1. 函数定义中的返回值不能缺少,

test();//在早期的C++ standar 这个是可以的,因为会隐隐式假定返回int. but  now ,can not .

2.函数可以返回built-in type like int,double. class type,compound type such as :int &,string * and void.

但却不可以返回另外的函数,或者数组, 如果有这需要,可以用函数指针,或者数组的指针.

int * fool(){.............} ,返回指向数组的第一元素的地址..

3.函数在调用时候, 起参数列表才会初始会,这个普通变量是一样的,如果不是应用类型, 则是用传给函数的argument 去初始化(copy  方式,即传值)这些参数,然后作为函数的local varible 使用,如果是reference type,则只是传的argument 的另外一个引用,不会copy.,,

就算传指针,也做copy.

int testfunction(int b,int & c,int * k); //c,k 都会改变传递的argument 值,除非定义成const

int arg=10;

const int arg2=10;  //arg2 的地址是不能传给k的. 因为const int * 不能转成int *. ,当然可以传递给 b,因为可以copy 10去初始化b.

testfunction(arg,arg,&arg); b- copy, c, not copy, k, 会copy arg 的地址给k,初始化

k的改变会影响到arg 的值.

*k=20;// 此时arg=20;

k=0;//k的地址置空了,但不会影响到arg  的地址. but can not delete K, or else *k will be deleted

如果不想在函数内部把arg的值改变,则可以这样定义:

int testfunction(int b,int & c,const int * k); 把这个指针定义成const

此时arg2 也可以传递给k 了.

所以const int *  好..

copy 的方式去初始化,还是有limitation 的,比如大对象的时候...这时候传递地址,或引用,,多快,,

int testfunction(int b,const int & c,const int * k);这样c,k都不可以改变argument 的值了... c 没有copy initilize , k 需要copy 一个地址..

如果想让指针也不copy ,有办法reference

int testfunction(int b,const int & c,const int *  &k);  这样k也不copy initilize 了.

4 使用数组作为参数

void testArray1(int k[])

{

  cout<<"testArray1"<<k[0]<<endl;

}

void testArray2(int k[10])

{

 cout<<"testArray2"<<k[0]<<endl;

}

void testArray3(int * k)

{

 cout<<"testArray3"<<k[0]<<endl;

}

void testArray4(int (&k)[10])

{

 cout<<"testArray4"<<k[0]<<endl;

}

void testArray5(const int k[])

{

  cout<<"testArray5"<<k[0]<<endl;

}

void testArray6(const int (&k)[10])

{

 cout<<"testArray6"<<k[0]<<endl;

}

void testArray7(const int (*k)[10])

{

 cout<<"testArray6"<<k[0][0]<<endl;

}

1,2,3 是等价的

4,是为了指定数组的维度

5.不改变数组的内容

6 不改变数组的内容 指定数组的维度  ,注意括号不能少

7 多维数组

如何管理数组的长度,有三中办法

a.象字符数组那样,给一个结束标志 char * str="adfasfsaf";//  null结尾,我们可以在函数中检查这个标志

b.传递 数组的开始,结束+1 的地址

void printValue(const int * begin,const int * end)

{

   while(begin!=end)

  {

 cout<<*begin++<<endl;

}

}

int a[2]={1,3};

printValue(a,a+2);

3. C,pre-stadandar C++ 的做法,多传递一个数组长度的参数,main 就就是个很好的例子

void printValue(int  [] a, size_t len)................

5. 可省略可参数

void foo(para_list,...)

void foo(...);

没有type checking for ellipsis parameter.

6 关于返回值

6.1 return NONReference  ,函数会在最后返回的时候,返回值copy 一份给调用者

string makString()

{

 return string("abcd");

}

即使是类对象也是一样copy的.

string k=makString();//ok.

6.2 return Reference ,返回引用的话,no copy to caller. 但是,不能返回local Object

const string & shortString(const string & s1,const string & s2)  返回值加上const ,是使返回值不可以被改变. 因为返回值是Lvalue.

{

  return s1.size()<s2.size()?s1:s2;  //ok.

  string a2;

  if(s1.size()<s2.size())

  a2=s1;

else

a2=s2;

return a2;// 不能返回local Object

}

6.3 return Pointer, copy 一个地址,但是,不能返回local Object Pointer

7 函数的声明可以是多次,但定义只能是一次..

8.参数默认值.

void kkkk(int a,int b=10)

kkk(5);//ok ,equal kkk(5,10);

如果函数的定义中声明了参数的默认值,那么声明里就不用了,反之亦然.

fff.h

void kkkk(int a,int b=10);

fff.c

void kkkk(int a,int b=10)  //error....

{

.................

}

9 static local Object

函数中定义的对象是local scope,will destroy after call end.

but if we define it as static ,then will exit even thoug the call end.

10 inline function

函数的调用是要做很多工作的,如保存和恢复寄存器,copy argument,ect. 如果我们的函数只是少数几个statment,no for,那我们可以用inline function

inline function will ben expand during compilation. ie:

inline string getshortStr(const string  & s1,const string & s2)

{

 return  s1.size()<s2.size()? s1:s2;

}

cout <<getshortStr(s1,s2)<<end;

while compile ,will expand like this below:

cout <<s1.size()<s2.size()? s1:s2 <<end;

if we use this will save the function invocatino

注意inline function 只能定义在.h 文件中.

11 类成语函数后面的const

class A

{

 public :

 double var1;

 double getVar1() const   //类中的成员函数后面加上const ,意思是这个 隐藏的this 指针是const ,那么就是说, 通过这个指针你不能改变其成语var1 的值.

 {

this.var1=10;// error .

 return this.var1;

}

};