330 likes | 491 Views
函数的参数与返回值. 形式参数与实在参数. … print(‘a’); … void print(char c) { cout << c << endl; }. 参数类型. 简单数据类型 指针 引用 数组 结构 对象. 参数传递中栈的变化(例). void funcAA(int paraAA) { int localAA; } int funcA(int para1, int para2) { int local1=1; funcAA(); return para1+para2+local1; }
E N D
形式参数与实在参数 … print(‘a’); … void print(char c) { cout << c << endl; }
参数类型 • 简单数据类型 • 指针 • 引用 • 数组 • 结构 • 对象
参数传递中栈的变化(例) void funcAA(int paraAA) { int localAA; } int funcA(int para1, int para2) { int local1=1; funcAA(); return para1+para2+local1; } void main() { int a=2,b=3; funcA(a,b); }
函数的参数传递 Main funcA() funcAA()
参数传递方式 • 值传递 • 简单数据类型 • 结构 • 对象 • 地址传递 • 指针 • 数组 • 引用传递 • 引用
值传递 void func1() { int i = 125; func(i); cout << i; } void func2(int inVar) { inVar = 45; } 0x3492047 125 0x3492034 125
按值传递 • 简单数据类型、结构、对象都是按值传递 float f; SomeClass aObj; SomeStruct aStruct; func(f); func(aObj); func(sStruct);
对象和结构参数 • 类的对象作为参数传递时 • 需要调用类的拷贝构造函数 • 函数执行结束时,需要释放该临时对象 • 结构和对象类似
值传递的特点 • 优点: • 对形式参数的操作不会影响实在参数 • 缺点: • 占用栈空间
地址传递(指针) 可以间接修改形式参数的值 void func1() { int i = 125; func(&i); cout << i; } void func2(int *pI) { *pI = 45; } 0x3492047 0x3492034 0x3492034 125
对象指针参数 void func1() { ClassA obj; func(&obj); } void func2(ClassA *pObj) { pObj->mem1 = 4; } 0x3492034 0x3492034 mem1 对象obj ...... other members 125
地址传递(数组) void func1() { int A[n]; func(A,n); } void func2(int A[], int size) { for(int i=0; i < size; i++) A[i] = i; } 0x3492034 0x3492034 A[0] ...... 数组A A[n-2] A[n-1] 125
地址传递(数组) • 数组参数传递时,一般需要传递数组的长度信息 • void func(int array[], int size); • 字符串作为参数时,不需要传递长度信息 • void func(char * str) • void func(char str[]) • 多维数组作为参数时,除第一维以外的所有维数都必须写出
地址传递的特点 • 好处 • 节省栈空间 • 可以通过传递的地址间接修改实在参数 • 坏处 • 可能会对实在参数产生副作用 • 通过指针传递信息和访问信息不太直接
引用传递(引用参数) void func1() { int i = 125; func(i); cout << i; } void func2(int & para) { para = 45; } 符号表 para 0x3492034 125
引用参数的特点 • 好处 • 简单、自然(调用时不需要加&) • 节省栈空间 • 通过引用参数返回函数的操作结果 • 坏处 • 可能对实在参数产生副作用(用const限制)
参数传递类型选择策略 • 通过函数返回某些信息 >>引用 • 参数类型为结构或对象类型 >>引用 • 传递给函数的简单数据类型 >>值 • 数组 >>地址 • 不希望被函数修改的参数 >>const
main()的参数 • void main(int argc, char *argv[]); • 第一个参数为程序运行时参数的个数 • 第二个参数为各个参数字符串的内容 mycopy file1 fil2 argc = 3 argv[0] = mycopy argv[1] = file1 argv[2] = file2
main()的参数 void main(int argc, char *argv[]) { for(int ix=1; ix < argc; ix++) { char *pchar = argv[ix]; progname -d filename switch(pchar[0]) progname +i parafile { case ‘-’: ... case ‘+’: ... default: ... } } }
返回值类型 • 简单数据类型 • 引用 • 指针 • 结构 • 对象 • void 数组
参数返回方式 • 值返回 • 一般数据类型 • 指针返回 Type func(......) • 引用返回 Type & func(......);
返回值 int func(...) char * func(...) ClassA func(...) ClassA * func(...) ... 注意:要保证返回的指针指向合法空间
返回引用 ClassA & func(...) int & func(...) • 注意:要保证返回的引用不是临时变量 Queue & CreateQueue() { Queue newQueue; for(int i=0; i < 10; i++) newQueue.add(i); return newQueue; }
返回引用 Queue & CreateQueue() { Queue *pNewQueue = new Queue; for(int i=0; i < 10; i++) pNewQueue->add(i); return *newQueue; }
const参数、返回值和函数 const参数:不能在函数体中对const参数做修改 int strcmp(const char *str1, const char *str2); const返回值:用于返回引用时,限定函数调用不能做左值 const int & min(int &, int &); int i = 4, j = 5; min(i,j) = 4; cout << min(i,j)
const参数 • 限制函数体对参数的重新赋值 void func1() { ClassA obj; func(&obj); } void func2(const ClassA *pObj) { pObj->mem1 = 4; } 0x3492034 0x3492034 mem1 对象obj ...... other members 125
const函数 const函数:用于类的成员函数。 class classname { public: int getMember() const; private: int member; }; classname::getmember() { member = 4; // !不能修改成员变量的值 return member; }
函数指针 sort(strings, compare) • 长度比较 sizeCompare() • 字母顺序比较 lexicoCompare() int sizeCompare(const char *, const char *); int lexicoCompare(const char *, const char *); int (*pf)(const char * , const char *);
函数指针-初始化与赋值 • 初始化 int (*pf)(const char * , const char *) = lexicoCompare; int (*pf)(const char * , const char *) = &lexicoCompare; • 赋值 pf = lexicoCompare; pf = sizeCompare; pf2 = pf; 注意:类型匹配 int (*pf1)(int, int ) = pf; //错误!!类型不匹配
函数指针--调用 int min(int array[], int size); int (*pf)(int *, int) = min; const int size = 5; int ia[size] = {1,2,3,4,5}; cout << min(ia,size); cout << pf(ia,size); cout << (*pf)(ia,size);
函数指针作为函数参数 int sort(char *strings[], int (*)(const char *, const char *)); 更好的写法: typedef int (*PFI2S)(const char *, const char *); int sort(char *strings[], PFI2S); 默认参数值 int sort(char *strings[], PFI2S compare = lexicoCompare);
函数指针作为函数参数 int sort(char *strings[], int size, PFI2S compare) { for(int i=0; i < size; i++) for(int j=i+1; j < size; j++) if (compare(strings[i], strings[j]) > 0) swap(strings[i], strings[j]); }