通過計算圓的面積熟悉函數的寫法,我們知道圓的面積公式如下

或者f(r) = PI * r*r
則C++函數就能實現數學的函數計算功能,下面的計算圓的面積的函數:
#include <iostream> using namespace std; #define PI 3.14159265358979323846 double circle_area(double r) { return PI*r*r; } int main()
{double s = circle_area(10.0); cout << "area = " << s << "\n"; return 0; }
PI定義的小數點越多,計算的面積越准確
C++函數有多個參數,返回一個值,注意如果返回多個值,可以用引用,例如下面計算圓的面積對半徑范圍有要求,比如
如果半徑大於1e6, 則返回false, 面積為-1, 說明半徑太大了,否則返回true及計算的面積
則實現為
#include <iostream> using namespace std; #define PI 3.14159265358979323846 bool circle_area(double r, double& s) { if (r > 1e6 || r < 0.0) { s = -1.0; return false; } else { s = PI*r*r; return true; } } int main()
{double s = 0.0; bool res = circle_area(10000000.0, s); if (res == true) { cout << "area = " << s << "\n"; } else { cout << "r range should be [0.0, 1000000.0]" << "\n"; } return 0; }
很顯然,這個版本的函數對輸入參數有檢查,實際的參數是有范圍和特殊要求的,所以更程序化而不是只是數學公式的C語言描述
參數引用一般講的是傳地址,所以s在函數內被賦值,其實是函數外面的s在內存里被修改, 非引用則是拷貝,例如第一個參數,其實有個 把10000000.0這個常數參數賦值到函數參數
r的隱藏的過程,我們可以看到(腦補)這個過程:
內存上一個double類型的內存塊拷貝到r這個double類型的內存塊
所以如果參數是個很大的類,比如std::vector<double>, 這個vector的double又非常多,那這個拷貝過程就很耗時,所以要小心,改為傳地址的引用或者指針來改善。
對於函數如果特別長,而且內部能有些部分計算是重復的,那就要把整個函數拆出子函數,俗稱模塊化的,數學公式上也是這樣的,比如
有三種硬幣,每種硬幣的數量半徑和高度已知,求這些硬幣的體積總和
那我們先有個硬幣參數的信息結構體
struct tipinfo
{
int type; ///<類型
double r; ///<半徑
double h; ///<高度
};
計算硬幣體積
double tip_vol(tipinfo& tip)
{
return circle_area(tip.r) * tip.h;
}
下面的map是類型表,作為全局表
std::map<int, tipinfo> tipTypeInfoMap;
下面的參數是每個類型的tip數量表
std::map<int, int> tipTypeNumbererMap;
計算體積和的函數為
double tips_volumn_sum()
{
double sum = 0.0;
for (std::map<int, int>::iterator i = tipTypeNumbererMap.begin(); i != tipTypeNumbererMap.end(); i++)
// c++11 的for可以簡化為
// for(auto& i : tipTypeNumbererMap)
{
int n = tipTypeInfoMap[i->first];
double v = n * tip_vol(tipTypeInfoMap[[i->first]);
sum += v;
}
return sum;
}
寫成一個double tips_volumn_sum函數肯定能編譯過,但是調試及維護難度加大,什么意思,就是幾個月后不要說別人你自己都看不懂了,所以雖然程序是一段文字
一個長的字符串,其實程序就像小說,是有構造的, 看的時候是動態的,浮想連篇的,好的代碼和好的小說一樣是有世界感的有故事的,啊這篇隨筆,明說了,要睡覺了,
所以后面的代碼就沒在http://www.dooccn.com/中編譯通過了,只是手打的。
