115.C語言_函數

第六章 函數node

  • 6.2 函數定義的通常形式
    • 函數的定義
      • C語言中函數定義的通常形式以下:
        • 函數返回值的類型名  函數名(類型名  形式參數1,類型名  形式參數2, … )
        • {
        • 說明部分;
        • 語句部分;
        • }
    • 說明:
      • 函數名和各個形式參數都是由用戶命名的合法標識符,與普通變量名的定義規則相同。在同一程序中,函數名必須惟一,不能出現重名的狀況。形式參數名只要在同一函數中惟一便可,因爲形式參數的做用域不相同,所以形式參數名能夠與其餘函數中的變量名同名。C語言規定,不能在一個函數內部再定義函數,也就是說函數不能嵌套定義。
      • 若在函數的首部省略了函數返回值的類型名,能夠把函數首部寫成:
        • 函數名(類型名形式參數1 ,類型名 形式參數2 ,…,類型名 形式參數n)
      • 緊跟在函數名以後的圓括號中的內容是形式參數和類型說明表,在每一個形參以前都要有類型名,以標識形式參數的類型。各形參的定義之間用逗號分隔。
        • 例如,求兩整數和的函數:
          • int  add(int a ,int b)
          • {
          • intt;       /* 函數體中聲明部分 */
          • t=a+b;
          • return t;
          • }
      • 若所定義的函數沒有形參,函數名後的一對圓括號依然不能省略。本例中函數體中的語句是用來完成求和的功能。在某些狀況下,函數體能夠是空的,例如:
        • fun()
        • {  }
        • 該函數中沒有任何語句,什麼工做也不作,沒有任何實際做用。之因此要在主調函數上這樣寫,是爲了代表此處要調用一個函數,而如今這個函數的具體功能可能尚未設計好,沒有起做用,等之後擴充函數功能時補充上便可。
      • 在函數體中,除形參外,用到的其餘變量必須在說明部分進行定義,這些變量(包括形參)只在函數被調用時才被臨時分配內存單元,當退出函數時,這些臨時開闢的存儲單元所有被釋放掉,即在該函數體內部定義的變量都將不存在。所以,這些變量只在函數體內部起做用,與其餘函數體內的變量並不相關。
  • 6.3 函數參數和函數返回值
    • 6.3.1 形式參數和實際參數
      • 定義
        • 在程序中調用函數時,絕大多數狀況下,主調函數和被調函數之間會發生數據傳遞關係,這就要用到前面提到的有參函數。在定義函數時,函數名後面括號中的變量稱爲「形式參數「(簡稱「形參「);在主調函數中,函數名後面括號中的參數(能夠是一個表達式)稱爲「實際參數「(簡稱「實參「)。
      • 說明:
        • (1)實參能夠是常量、變量或表達式。
        • (2)在被定義的函數中必須指定形參類型。
        • (3)實參與形參的類型應相同或賦值相兼容。
        • (4)C語言規定,實參變量對形參變量的數據傳遞是「值傳遞「,即單向傳遞。只能由實參傳給形參,而不能由形參返回來給實參。在內存中,實參單元與形參單元是不一樣的單元。
        • (5)在調用函數時,給形參分配存儲單元,並將實參對應的值傳遞給形參。調用結束後,形參單元被釋放,實參單元仍保留並維持原值。
        • (6)必定要注意參數之間的傳遞,實參和形參之間 傳數值,和傳地址的差異。傳數值的話,形參的變化不會改變實參的變化。傳地址的話,形參的變化就會有可能改變實參的變化。
    • 6.3.2 函數的返回值
      • 函數的返回值就是經過函數調用使主調函數能獲得一個肯定的值。函數的值經過return語句返回,return語句的形式以下:
        • return 表達式;
        • 或return(表達式);
        • 或return;
      • return 語句中的表達式的值就是所求的函數值。此表達式值的類型必須與函數首部所說明的類型一致。若類型不一致,則以函數值的類型爲準,由系統自動進行轉換。
        • 例如 經過函數調用的方法求1到天然數n(n>1)天然數的和,有程序段以下
          • #include<stdio.h>
          • ints(int n)
          • {
          • int i,sum=0;
          • for(i=1;i<=n;i++)
          • sum+=i;
          • return sum;
          • }
          • main()
          • {
          • int n;
          • printf("input number\n");
          • scanf("%d",&n);
          • n=s(n);
          • printf("1到n的和爲:%d\n",n);
          • }
  • 6.4 函數的調用
    • 6.4.1 函數調用的通常形式
      • 函數名(實參表列);
      • 函數的調用能夠分爲調用無參函數和調用有參函數兩種,若是是調用無參函數,則不用「實參表列「,但括號不能省略。在調用有參函數時,若實參列表中有多個實參,各參數間用逗號隔開。實參與形參要求類型一致。
    • 6.4.2 函數調用的方式
      • (1)函數語句。把函數調用作爲一個語句,這時該函數只須要完成必定的操做而沒必要有返回值。
      • (2)函數表達式。當一個函數出如今一個表達式中,該表達式就被稱爲函數表達式。由於要參與表達式中的計算,因此要求該函數有一個肯定的返回值提供給表達式。
      • (3)函數參數。函數調用作爲一個函數的實參。
    • 6.4.3 C語言中,調用函數和被調用函數之間的數據可經過3種方式進行傳遞。
      • (1)實參與形參之間進行數據傳遞。
      • (2)經過return語句把函數值返回到主調用函數中。
      • (3)經過全局變量。
    • 6.4.3  函數的遞歸調用
    • 函數的遞歸調用必定要記得有結束的條件
    • 在調用一個函數的過程當中又出現直接或間接地調用該函數自己,稱爲函數的遞歸調用。容許函數的遞歸調用是C語言的特色之一。
    • 當一個問題在採用遞歸法解決時,必須符合如下3個條件:
    • (1)能夠把要解決的問題轉化爲一個新的問題。而這個新的問題的解決方法仍與原來的解決方法相同,只是所處理的對象有規律地遞增或遞減。
    • (2)能夠應用這個轉化過程使問題獲得解決。
    • (3)必需要有一個明確的結束遞歸的條件。
    • 當函數本身調用本身時,系統將自動把函數中當前的變量和形參暫時保留起來,在新一輪的調用過程當中,系統將爲本次調用的函數所用到的變量和形參,開闢新的存儲單元。所以,遞歸調用的層次越多,同名變量所佔的存儲單元也就越多。當本次調用的函數運行結束時,系統將釋放本次調用所佔的存儲單元。當程序執行的流程返回到上一層的調用點時,同時取用進入該層函數中的變量和形參所佔用的存儲單元中的數據。
  • 6.5 函數的說明
    • 6.5.1  形式
      • 概念
        • C語言中,除了主函數外,對於用戶定義的函數要遵循先定義後使用的規則。把函數的定義放在調用以後,應該在調用以前對函數進行說明(或函數原型說明)。
      • 函數說明的通常形式以下:
        • 類型名 函數名(參數類型1 ,參數類型2 ,…,參數類型n);
            • intadd(int  ,int  );
        • 類型名 函數名(參數類型1 參數名1,參數類型2 參數名2 ,…,參數類型n  參數名n);
          • 此處的參數名徹底是虛設的,它們能夠是任意的用戶標識符,既沒必要與函數首部中的形參名一致,又能夠與程序中的任意用戶標識符同名,實際上參數名經常省略。函數說明語句中的類型名必須與函數返回值的類型一致。
      • 函數說明能夠是一條獨立的語句。對函數進行說明,能使C語言的編譯程序在編譯時進行有效的類型檢查。當調用函數時,若實參的類型與形參的類型不能賦值兼容而進行非法轉換,C編譯程序將會發現錯誤並報錯;當實參的個數與形參的個數不一樣時,編譯程序也將報錯。
    • 6.5.2函數說明的位置
      • 一個函數在全部函數的外部,如在被調用以前說明,則在說明後的全部位置上均可以對該函數進行調用。如在main()函數內部進行說明,則只能在main()函數內部才能識別。
      • 例如 調用求和函數輸出1到n的和值,程序段以下:
        • #include<stdio.h>
        • main()
        • {
        • int n;
        • int s(int n);
        • printf("input number\n");
        • scanf("%d",&n);
        • s(n);
        • printf("n=%d\n",n);
        • }
        • ints(int n)
        • {
        • int i,sum=0;
        • for(i=1;i<=n;i++)
        • sum+=i;
        • printf("1到n的和值爲:%d\n",n);
        • }
    • 必定要有:函數名,函數的返回類型,函數的參數類型。不必定要有:形參的名稱。
  • 6.6 經常使用函數
    • 6.6.1  字符串 <string.h>
      • 6.6.1.1  strlen 計算長度
      • 6.6.1.2  strcmp 比較
      • 6.6.1.3  strcpy 複製 (不安全,越界)
      • 6.6.1.4  strcat 追加 (不安全,越界)
    • 6.6.2  數學函數<math.h>
      • 6.6.2.1   向上,向下取整
        • 函數名: ceil
          • 功能:向上取整
          • 用法: double ceil(double x);
        • 函數名: floor
          • 功能:向下取整
          • 用法: double floor(double x);
      • 6.6.2.2  取絕對值
        • 函數名:abs
          • 功能:返回整型數的絕對值.
          • 用法:abs(number)
          • number 參數能夠是任意有效的數值表達式。若是 number 包含 Null,則返回Null;若是是未初始化變量,則返回 0.
        • 函數名:fabs
          • 功能:求浮點數x的絕對值.
          • 用法:fabs  (double x);
      • 6.6.2.3  平方根
        • 函數名:sqrt
          • 功能:返回指定數字的平方根.
          • 用法:sqrt  (double x);
      • 6.6.2.4  求冪
        • 函數名:exp
          • 功能:返回 e 的 n 次冪.
          • 用法:exp  (double x);
        • 函數名:pow
          • 功能:返回指定數字的指定次冪.
          • 用法:pow   (double x, double y);(將返回x的y次冪)
      • 6.6.2.5  取餘
        • 函數名: fmod
          • 功  能: 計算x對y的模, 即x/y的餘數
          • 用  法:double fmod(double x, double y);
      • 6.6.2.6  對數
        • 函數名:log
          • 功能: 天然對數函數ln(x)
          • 用法: double log(double x);
        • 函數名:log10
          • 功能:返回以 10 爲底的對數.
          • 用法:log10(double x);
      • 6.6.2.7  三角函數:(全部參數必須爲弧度)
        • sin
          • 函數聲明:sin  (double x);
          • 用途:用來返回給定的 X 的正弦值。
        • cos
          • 函數聲明:cos  (double x);
          • 用途:用來返回給定的 X 的餘弦值。
        • tan
          • 函數聲明:tan   (double x);
          • 用途:用來返回給定的 X 的正切值。
      • 6.6.2.8  反三角函數
        • acos
          • 函數申明:acos  (double x);
          • 用途:用來返回給定的 X 的反餘弦函數。
        • asin
          • 函數申明:asin  (double x);
          • 用途:用來返回給定的 X 的反正弦函數。
        • atan
          • 函數申明:atan  (double x);
          • 用途:用來返回給定的 X 的反正切函數。
        • atan2
          • 函數聲明:atan2 (double y, double x);
          • 用途:返回給定的 X 及 Y 座標值的反正切值
      • 6.6.2.9  雙曲函數
        • 函數名:cosh
          • 功能:返回指定角度的雙曲餘弦值.
          • 用法:Double Cosh(double x(以弧度計量的角度)) ;
        • 函數名:sinh
          • 功能:返回指定角度的雙曲正弦值。
          • 用法:sinh (double x);(其中參數x必須爲弧度制)
        • 函數名:tanh
          • 功能:回指定角度的雙曲正切值.
          • 用法:tanh  (double x);
      • 6.6.2.10  實型數分整數和小數
        • 函數名:modf
          • 功  能: 把數分爲整數部分和小數部分
          • 用  法: double modf(doublevalue, double *iptr);
          • eg
            • 1.  #include<math.h>
            • 2.
            • 3.  #include<stdio.h>
            • 4.
            • 5.  int main(void)
            • 6.
            • 7.  {
            • 8.
            • 9.  double fraction,integer;
            • 10.
            • 11. double number =100000.567;
            • 12.
            • 13. fraction =modf(number, &integer);
            • 14.
            • 15. printf("Thewhole and fractional parts of %lf are %lf and %lf\n",
            • 16.
            • 17. number, integer,fraction);
            • 18.
            • 19. return 0;
            • 20.
            • 21. }
            • The whole andfractional parts of 100000.567000 are 100000.000000 and 0.567000
      • 6.6.2.11  隨機數
        • 在編程的時候須要電腦來獲取一些隨機的反應,這個時候咱們可使用隨機數,比較常見的是 rand() 函數,它能夠隨機的產生 0 ~rand_max 的隨機數。rand_max 是一個很大的數字,具體關係到IDE和數據類型,咱們通常的須要不可能超出它的範圍
        • C語言中還有一個 random() 函數能夠獲取隨機數,可是 random() 函數不是ANSI C標準,不能在VC等編譯器經過,因此比較少用。
        • eg
          • int a=rand()%10; //產生0~9的隨機數,注意10會被整除
          • int a=rand()%51+13; //產生13~63的隨機數
          • 產生 13~63 範圍內隨機數的完整代碼:
            • 1.      #include <stdio.h>
            • 2.      #include <stdlib.h>
            • 3.      #include <time.h>
            • 4.      int main(){
            • 5.      int a;
            • 6.      srand((unsigned)time(NULL));
            • 7.      a=rand()%51+13;
            • 8.      printf("%d\n",a);
            • 9.      return 0;
            • 10.  }
          • 下面是一個實例:
            • 1.      #include <stdio.h>
            • 2.      #include <stdlib.h>
            • 3.      int main(){
            • 4.      int a=rand();
            • 5.      printf("%d\n",a);
            • 6.      return 0;
            • 7.      }
            • 編譯後再運行幾回,你會發現產生的隨機數是相同的。實際上,rand() 函數產生的隨機數是僞隨機數,是根據一個數按照某個公式推算出來的,這個數咱們稱之爲「種子」,可是這個種子在系統啓動以後就是一個定值,咱們須要用 srand() 來進行播種,即在int a前加一句:
              • 1.      srand((unsigned)time(NULL)); //這裏利用時間進行播種,須要time.h
      • sqrt( ) fabs( )  pow( )  sin( )
    • 6.6.3 malloc
      • malloc的返回類型是 void *
        • int  *p;
        • p = (int *)malloc(2);
        • p = (int *)malloc(sizeof(int));以上兩個等價

 

 

 

相關文章
相關標籤/搜索