|
} return語句可以向調用函數返回值, 但這種方法只能返回一個參數, 在許多情況下要返回多個參數, 這是用return語句就不能 滿足要求。Turob C2.0提供了另一種參數傳遞的方法, 就是調用函數向被調用函數傳遞的形式參數不是傳遞變量本身, 而是傳遞變 量的地址, 當子函數中向相應的地址寫入不同的數值之后, 也就改變了調用函數中相應變量的值, 從而達到了返回多個變量的目的。 例4: #include<stdio.h> void subfun(int *m, int *n); /*說明子函數*/ int main() { int i, j; printf("i, j=?\n"); scanf("%d, %d", &i, &j); /*從鍵盤輸入2個整數*/ printf("In main before calling\n", /*輸出此2數及其乘積*/ "i=%-4d j=%-4d i*j=%-4d\n", i, j, i*j); subfun(&i, &j); /*以傳送地址的方式調用子函數*/ printf("In main after calling\n", /*調用子函數后輸出變量值*/ "i=%-4d j=%-4d i*j=%-4d\n", i, j, i*j); getch(); return 0; } void subfun(int *m, int *n) { *m=*m+2; *j=*i-*j; printf("In subfun after calling\n", /*子函數中輸出變量值*/ "i=%-4d j=%-4d i*j=%-4d\n", *i, *j, *i**j); }
上例中, *i**j表示指針i和j所指的兩個整型數*i和*j之乘積。 另外, return語句也可以返回一個指針, 舉例如下。 下例中先等待輸入一字符串, 再等待輸入要查找的字符, 然后調用match() 函數在字符串中查找該字符。若有相同字符, 則返 回一個指向該字符串中這一位置的指針, 如果沒有找到,則返回一個空(NULL)指針。 例5: #include<stdio.h> char *match(char c, char *s); int main() { char s[40], c, *str; str=malloc(40); /*為字符串指什分配內存空間*/ printf("Please input character string:"); gets(s); /*鍵盤輸入字符串*/ printf("Please input one character:"); c=getche(); /*鍵盤輸入字符*/ str=match(c, s); /*調用子函數*/ putchar(''\n''); puts(str); /*輸出子函數返回的指針所指的字符串*/ getch(); return 0; } char *match(char c, char *s) { int i=0; while(c!=s[i]&&s[i]!=''\n'') /*找字符串中指定的字符*/ i++; return(&s[i]); /*返回所找字符的地址*/ }
三、用全程變量實現參數互傳 以上兩種辦法可以在調用函數和被調用函數間傳遞參數, 但使用不太方便。如果將所要傳遞的參數定義為全程變量, 可使變量 在整個程序中對所有函數都可見。 這樣相當于在調用函數和被調用函數之間實現了參數的傳遞和返回。這也是實際中經常使用的方 法, 但定義全程變量勢必長久地占用了內存。因此, 全程變量的數目受到限制, 特別對于較大的數組更是如此。當然對于絕大多數 程序內存都是夠用的。 例6: #incluide<stdio.h> void disp(void); int m[10]; /*定義全程變量*/ int main() { int i; printf("In main before calling\n"); for(i=0; i<10; i++){ m[i]=i; printf("%3d", m[i]); /*輸出調用子函數前數組的值*/ } disp(); /*調用子函數*/ printf("\nIn main after calling\n"); for(i=0; i<10; i++) printf("%3d", m[i]); /*輸出調用子函數后數組的值*/ getch(); return 0; } void disp(void) { int j; printf("In subfunc after calling\n"); /*子函數中輸出數組的值*/ for (j=0; i<10; j++){ m[j]=m[j]*10; printf("%3d", m[i]); } }
2.3 函數的遞歸調用 Turbo C2.0允許函數自己調用自己, 即函數的遞歸調用, 遞歸調用可以使程序簡潔、代碼緊湊, 但要犧牲內存空間作處理時的 堆棧。 如要求一個n!(n的階乘)的值可用下面遞歸調用:
例8: #include<stdio.h> unsigned ling mul(int n); int main() { int m; puts("Calculate n! n=?\n"); scanf("%d", &m); /*鍵盤輸入數據*/ printf("%d!=%ld\n", m, mul(m)); /*調用子程序計算并輸出*/ getch(); retun 0; } unsigned long mul(int n) { unsigned long p; if(n>1) p=n*mul(n-1); /*遞歸調用計算n!*/ else p=1L; return(p); /*返回結果*/ }
運行結果: calculate n! n=?
輸入5時結果為: 5!=120
3. 函數作用范圍
Turbo C2.0中每個函數都是獨立的代碼塊, 函數代碼歸該函數所有, 除了對函數的調用以外, 其它任何函數中的任何語句都不 能訪問它。例如使用跳轉語句goto 就不能從一個函數跳進其它函數內部。除非使用全程變量, 否則一個函數內部定義的程序代碼和 數據, 不會與另一個函數內的程序代碼和數據相互影響。 Turbo C2.0中所有函數的作用域都處于同一嵌套程度, 即不能在一個函數內再說明或定義另一個函數。 Turbo C2.0中一個函數對其它子函數的調用是全程的, 即是函數在不同的文件中, 也不必附加任何說明語句而被另一函數調用, 也就是說一個函數對于整個程序都是可見的。
4. 函數的變量作用域 在Turbo C2.0中, 變是可以在各個層次的子程序中加以說明, 也就是說, 在任何函數中, 變量說明有只允許在一個函數體的開 頭處說明, 而且允許變量的說明( 包括初始化 )跟在一個復合語句的左花括號的后面, 直到配對的右花括號為止。它的作用域僅在 這對花括號內, 當程序執行到出花括號時, 它將不復存在。當然, 內層中的變量即使與外層中的變量名字相同, 它們之間也是沒有 關系的。
例9. #include<stdio.h> int i=10; int main() { int i=1; printf("%d\t, i); { int i=2; pritnf("%d\t", i); { extern i; i+=1; printf("%d\t", i); } printf("%d\t", ++i); } printf("%d\n", ++i); return 0; }
運行結果為 1 2 11 3 2
從程序運行的結果不難看出程序中各變量之間的關系, 以及各個變量的作用域。
|