// 第五章 程序结构.cpp: 主项目文件。 #include "stdafx.h" #include <iostream> using namespace std; using namespace System; /*double power (double, int); int main(array<System::String ^> ^args) { 如何声明并编写自己的C++函数 函数参数的定义和使用方法 如何传递进出函数的数组 按值传递的意义 如何给函数传递指针 如何使用引用作为函数参数,按引用传递的意义 const修饰行对函数的参数影响 如何从函数中返回值 递归的使用方法 ///////////////////////////////// 5.1 理解函数 5.1.1 需要函数的原因 5.1.2 函数结构 1: 函数头 double power(double x, int n); 返回回值类型 函数名 圆括弧包围的函数形参 注意: 函数头的包围函数体的闭大括号后面都不需要分号 2: 函数体 在函数内声明的变量,其作用域的确定方法与前面曾经讨论过的相同,变量产生定义它的位置,在包含它的代码块结束时不复存在,有一类变量不适用这条原则,即被声明为static的变量, 3:return 语句 return 语句将result的值返回到调用函数的位置,return语句通式如下 5.1.3 使用函数 cout<<"power(3.0, 3):"<<power(3.0, 3)<<endl; system("pause"); return 0; } double power (double x, int n) { double val = 1.0; for(int i=0; i<n; i++) { val = val * x; } return val; }*/ /* double power(double, int); int main(array<System::String ^> ^args) { int index = 3; double x = 3.0; double y = 0.0; y = power(5.0,3); cout<<"5.0:"<<y<<endl; cout<<"3.0:"<<power(3.0,index)<<endl; //“参数”: 从“double”转换到“int”,可能丢失数据 //这里因为第二个参数需要的是int型,而返回的是double,系统自动显示转了 //该语句涉及两次编译器插入的从double到int型的隐式类型转换,从duble转换为int类型. //时有可能丢失数据,因此编译器在这种情况下将发出警告消息,即使转换操作就是编译器自己插入的也一样,通常 //依赖可能造成数据丢失的自动转换是一种凶险的编程习惯,而从代码中根本看不出这种转换在计划之中,需要时在代码中显式使用static_cast运算符要好得多 //x = power(x, power(2.0,2.0)); x = power(x,static_cast<int>(power(2.0,2.0))); cout<<"x:"<<x<<endl; system("pause"); return 0; } double power(double x, int n) { double val=1.0; for(int i=0; i<n; i++){ val *= x; } return val; }*/ //5.2 给函数传递实参 //5.2.1 按传传递机制 /*int incr10(int); int main(array<System::String ^> ^args) { int num = 3; cout<<"incr10(num) = "<<incr10(num)<<endl; //13 cout<<"num:"<<num<<endl; system("pause"); return 0; } int incr10(int num) { num += 10; return num; }*/ //5.2.2 给函数传递指针实参 //当我们使用指针作为实参时,按值传递机制仍然像以前一样工作,但指针是另一个变量的地址,如果创建该地址的副本,则副本仍然指向相同的变量,以指针作为形参可以使函数处理调用者传递的实参,道理就在于此 /*int incr10(int*); int main(array<System::String ^> ^args) { int num = 3; int* pnum = # cout<<"incr10(&num) = "<<incr10(pnum)<<endl; //13 cout<<"num:"<<num<<endl; //13 cout<<"incr10(&num) = "<<incr10(pnum)<<endl; system("pause"); return 0; } int incr10(int* num) { (*num) += 10; return *num; }*/ //在重写的incr10()函数版本中,使传递给函数的值加10的语句和return语句现在都要取消对指针的引用,以使用指针指向的地址存储的数值 //5.2.3 给函数传递数组 //我们还可以给函数传递数组,但这种情况下即使仍然使用按值传递的实参,系统也不会复制被传递的数组,编译器将数组转换为指针,指向数组头部的指针副本通过按值传递机制被传递给函数,这是十分有利的,因为复制大型数组非常耗时,但有一点您可能已经想到了,那就是在函数内可以修改数组的元素,困上数组是唯一不能按值传递机制保护的类 /*double average(double ar[], int count); int main(array<System::String ^> ^args) { double values[] ={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0}; cout<<"age: "<<average(values, sizeof(values) / sizeof(values[0]))<<endl; system("pause"); return 0; } double average(double ar[], int count) { double sum=0.0; for(int i=0; i<count; i++) { sum += ar[i]; } return sum / count; }*/ //传递数组时使用指针符号 /*double average(double* ar, int count); int main(array<System::String ^> ^args) { double values[] ={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0}; cout<<"age: "<<average(values, sizeof(values) / sizeof(values[0]))<<endl; system("pause"); return 0; } double average(double *ar, int count) { double sum=0.0; for(int i=0; i<count; i++) { //sum += ar[i]; sum += *(ar+i); //sum += *ar++; } return sum / count; }*/ //给函数传递多维数组 //您可能想知道,编译器如何得知我们是在定义维数如上所示的数组而非单个数组元素作为实参, //答案很简单:虽然我们调用函数时可以传递数组元素作为实参,但是不能在函数定义或原型中写上单个数组元素作为形参, //接受单个数组元素实参的形参,将只有一个变量名,而接受数组的形参则不同 //double yield(double beans[][4], int index) //在这里,第二个形参将提供关于第一维的必要信息,该函数可以处理第一维由第二个参数指定的,第二维是四的二维数组 /*double yield(double ar[][4], int n); double yieldNew(double ar[][]); int main(array<System::String ^> ^args) { double beans[3][4] = {{1.0,2.0,3.0,4.0}, {5.0,6.0,7.0,8.0}, {9.0,10.0,11.0,12.0}}; cout<<"sum:"<<yield(beans, sizeof(beans) / sizeof(beans[0]))<<endl; //yieldNew(beans); system("pause"); return 0; } double yield(double ar[][4], int n) { double sum = 0; for(int i=0; i<n; i++){ for(int j=0; j<4; j++){ sum += ar[i][j]; } } return sum; } //想法很天真 double yieldNew(double ar[][]) { double sum = 0; for(int i=0; i<(sizeof(ar)/sizeof(ar[0])); i++){ //for(int j=0; j<4; j++){ //sum += ar[i][j]; //} } return sum; }*/