【例6.7】下面是求最大值函數,主函數中初始化「c=0」是否是必需的?這個程序是否能完成預定功能?
#include <stdio.h> void max (double ,double ,double ); int main ( ) { double x , y ,c=0 ; scanf ( "%lf %lf" , &x , &y ); max (x ,y ,c ); x=2* (x+y )-c ; printf ("x=%lf\n" ,x ); max (x ,c ,c ); printf ("c=%lf\n" ,c ); return 0 ; } void max ( double a , double b ,double c ) { if (a>b ) c=a ; else c=b ; }
【解答】是必需的。如果不給它初始值,編譯系統在編譯scanf語句時,只會通過鍵盤給變量x和y賦值。在掃瞄到函數調用時,max的參數c沒有賦值,就會給出警告信息。當然,第2次掃瞄時,能產生正確的執行文件。但產生警告信息,總不是件好事情。
設計的max函數是將最大值賦給變量c,但c是傳值形式,在max函數內,它是最大值。一旦離開max函數,就恢復為原來的c值。
因為x和y都需要繼續使用,不能改變它們的值,所以只能設計第3個參數返回最大值。這時需要採用傳地址值的方式。修改後的程序如下所示:
#include <stdio.h> void max (double ,double ,double * ); int main ( ) { double x , y ,c=0 ; scanf ( "%lf %lf" , &x , &y ); max (x ,y ,&c ); x=2* (x+y )-c ; printf ("x=%lf\n" ,x ); max (x ,c ,&c ); printf ("c=%lf\n" ,c ); return 0 ; } void max ( double a , double b ,double *c ) { if (a>b ) *c=a ; else *c=b ; }
運行示範如下:
2.5 -3.2 x=-3.900000 c=2.500000
注意到主程序並不需要聲明指針,直接使用「&c」傳遞就可以了。有人喜歡一定要一一對應,認為聲明的參數是指針類型,一定要轉化一個指針參數,即使用一個
double *p=&c ;
定義的指針,然後使用max(x,y,p)才能放心,其實是多餘的。p是地址,&c也是地址,而且是同一個地址。下面的主程序演示分別使用這兩種方法的例子。
#include <stdio.h> void max (double ,double ,double * ); int main ( ) { double x , y ,c=0 ,*p=&c ; scanf ( "%lf %lf" , &x , &y ); max (x ,y ,&c ); // 使用c 的地址 x=2* (x+y )-c ; printf ("x=%lf\n" ,x ); max (x ,c ,p ); // 使用指向c 的指針 printf ("c=%lf\n" ,c ); return 0 ; }
結論:不要教條!