bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

C語言入門知識——(1)函數基礎-創新互聯

1、什么是函數

在數學函數是一種對應關系,C語言里的函數和數學中的函數還是極其相似的

專注于為中小企業提供成都網站制作、網站建設、外貿網站建設服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業潼關免費做網站提供優質的服務。我們立足成都,凝聚了一批互聯網行業人才,有力地推動了超過千家企業的穩健成長,幫助中小企業通過網站建設實現規模擴充和轉變。(1)維基百科對函數的定義

在這里插入圖片描述
①維基百科:子程序 - 維基百科,自由的百科全書 (shenyinjise.icu)
②子程序。是大型程序中的某部分代碼,由一個或多個語句組成。負責完成某項特定的任務,而且相較于其他代碼具有相對的獨立性。

(2)另外的補充說明

C語言中的函數,一般會有輸入參數并由返回值,提供對過程的封裝和細節的隱藏,這些代碼通常集成為一個軟件庫。

2、C語言中函數的分類(“庫函數”和“自定義函數”) (1)庫函數

①C語言自帶的函數,可以直接使用,方便程序員進行軟件開發
可以在這個網站里面查找: https://cplusplus.com/
或者C/C++官網: cppreference.com(中文版: cppreference.com)
或者使用工具MSDN,可以離線查看,但是更新度不夠
②使用庫函數,需要包含#include對應的頭文件
③常用的庫文件如下:

  • IO函數
  • 字符串操作函數
  • 字符處理函數
  • 內存操作函數
  • 時間/日期函數
  • 數學函數
  • 錯誤消息
  • 功能函數
  • windows
  • 其他庫函數<……>
(2)自定義函數

不可能所有的庫函數都符合我們的需求,因此我們還需要自己寫符合自己需求的函數,所以學會寫自定義函數是最為重要的!
①函數必須有這些構成:函數的返回類型(注意這不是函數的類型)、函數名、函數參數列表、函數體
②偽代碼:函數的結構

返回類型 函數名(參數列表)//注意返回指和參數列表可以是“空”,即void的情況
{函數體(具體代碼);
}//如果忘記寫返回類型,則默認返回一個整數,但不寫返回類型是一個壞習慣!

③一些例子
例子1:比大小的函數

int MAX(int x, int y)//自定義“相加”函數
{return (x>y)?(x):(y);//使用了三目操作符
}
int main()//主體函數
{int num_1 = 10;
    int num_2 = 100;
    int max = MAX(num_1, num_2);
    printf("max = %d\n",max);
    return 0;
}

例子2:查找閏年

int is_leap_year(int y)//自定義“判斷是否為閏年”函數
{return ((y % 4 == 0) && (y % 100 != 0)) || y % 400 == 0;
}

int main()//主體函數
{int y = 0;
    for (y = 1000; y<= 2000; y++)
    {//判斷y是否為閏年
        //如果是閏年返回1 
        //如果不是閏年返回0
        if (is_leap_year(y))
        {printf("%d ", y);
        }
    }
    return 0;
}

④一般來說要先在主函數(主程序)里面寫如何去用、在哪里用這個函數,再去寫自定義函數的具體實現會比較好一點。(這其實是TDD思想,TDD指“測試驅動開發(Test-Driven Development)”)

3、函數的參數 (1)實際參數(實參)

真實傳給函數的參數,實參可以是:常量、變量、表達式、函數等。
實參在進行函數調用的時候,必須有確定的值,然后傳值給形參使用。

(2)形式參數(形參)

①簡單來講就是函數定義后,函數名后面括號的內容中的變量,只有在函數被調用的時候,實參傳值給形參時,形參才會有值(即“才會實例化“,“才會分配內存單元”,因此就是形式上的參數)。
②更簡單理解就是,“形參”是“實參”的臨時拷貝,對形參的改動和修改是不會影響到實參的。
③如果需要通過形參來改動實參,則不能只是傳遞值,而是應該傳遞地址!
④另外形式參數在函數調用完后就自動銷毀了,因此形式參數只有在函數內部才是有效的
⑤函數中的形式參數是在棧中開辟空間的

(3)有關函數參數易錯題
int founction((a1, a2), (a3, a4), a5, a6);//函數有幾個參數呢?

實際上應該是4個參數,(a1, a2)和(a3, a4)是逗號表達式,他們都各有一個結果,分別為a2和a4,故實際上函數的參數為a2,a4,a5,a6四個參數

(4)函數參數個數設置得越少越好

不然用戶使用的時候,還得搞清楚每個參數的意義,并且還要輸入很多參數才能使用

4、函數的調用(使用函數交換兩個數字) (1)傳值調用

函數的形參和實參分別占有不同的內存,對形參的修改不會影響實參。
如果寫成下面這個代碼就會交換失?。ū举|就是形參和實參的問題)

//一個典型的例子(寫一個錯誤交換兩個數的函數)
void function(int a, int b)//這里自定義函數只是臨時拷貝(傳過來)num_1和num_2兩個數的值,所以下面只是x和y的值交換了,而num_1和num_2卻沒有進行實際上的交換
{int t = 0;
    t = a;
    a = b;
    b = t;
}

int main()
{int num_1 = 1;
    int num_2 = 2;
    printf("%d %d\n",num_1, num_2);
    
    function(num_1, num_2);//使用交換函數
    printf("%d %d\n", num_1, num_2);
    return 0;
}//這個函數通過編譯器的調試功能會更加清晰看到
(2)傳址調用
//一個典型的例子(寫一個正確交換兩個數的函數)
void function(int *pa, int *pb)
{int t = 0;
    t = *pa;
    *pa = *pb;
    *pb = t;
}
int main()
{int num_1 = 1;
    int num_2 = 2;
    printf("%d %d\n", num_1, num_2);
    
    function(&num_1, &num_2);//使用交換函數
    printf("%d %d\n", num_1, num_2);
    return 0;
}

總之函數的調用無論是傳值還是傳址都有利弊,看情況選擇傳值方式。從功能上傳址調用比較強大,但是容易出現更多問題。

(3)高內聚低耦合

函數設計應該追求“高內聚低耦合”:在函數體內實現修改,盡量不要對外部產生影響,否則代碼不便修改

5、函數的“嵌套調用”和“鏈式訪問” (1)嵌套調用(在一個函數里調用了另一個函數)
#includevoid function_1()
{printf("aaaaa\n");
}
void function_2()
{int i = 0;
    for(i=0; i<3; i++)
    {function_1();//調用了另外一個函數
    }
}
int main()
{function_2();
    return 0;
}

注意:函數可以嵌套調用但是不能嵌套定義(一個A函數里面又定義了一個B函數,但是可以在A定義里面調用一個已經定義好的函數B(或者B定義里面調用一個已經定義好的函數A))

//以下“嵌套定義”是不被允許的!
返回類型 f1(參數列表)
{//一些代碼
    返回類型 f2(參數列表)
    {//一些代碼    
    }
    //一些代碼
}
(2)鏈式訪問(把一個函數的返回值作為另一個函數的參數)
//鏈式訪問例子1
#include#includeint main()
{printf("%d\n", strlen("abcd"));
    return 0;
}
//鏈式訪問例子2
#includeint main()
{printf("%d",printf("%d",printf("%d",43)));//printf返回值是讀取到字符的個數
    return 0;
}//結果為4321這四個字符,注意不是四千三百二十一,只是單純的輸出4、3、2、1這四個字符
6、函數的聲明和定義
//實際上函數的聲明和變量的聲明很像
#includeint a;變量的聲明
int main()
{printf("%d\n",a);//變量的使用
    return 0;
}
int a = 10;//變量的定義
//這種寫法也是可以正常打印出來10的
(1)函數的聲明

①是為了告訴編譯器存在一個自定義的函數,需要聲明函數的結構
(函數名字、函數參數、返回類型)
②一般在使用函數之前聲明函數
③函數的聲明一般放在頭文件中

(2)函數的定義

交代函數的具體實現方式

(3)教科書里常見函數聲明的使用:
#includeint Add(int x, int y);//函數的聲明

int main()
{int a = 1, b = 2;
    printf("%d", Add(a, b));//函數的使用
    return 0;
}

int Add(int x, int y)//函數的定義
{return x + y;
}
//這種寫法雖然對,但是實際情況一般不會這么寫,函數的聲明一般放在頭文件中,函數的實現則放到另外一個專門用來自定義函數的源文件中
(4)實際上的工程里常見的,函數聲明較多的寫法是:
//頭文件add.h中
#ifndef __ADD_H__
#define __ADD_H__

int Add(int x, int y);//函數的聲明

#endif
//函數定義源文件add.h
int Add(int x, int y)//函數的定義
{return x + y;
}
//程序主體文件main.h
#include#include "Add.h"
int main()//主函數
{int a = 1,b = 2;
    printf("%d", Add(a, b));//函數的使用
    return 0;
}
(5)一是適合分工、二是有保密措施(靜態庫.lib的使用)

①總不可能一堆程序員擠在一個電腦屏幕上寫代碼吧?多文件使得有程序員得以有效分工,每一個程序員寫各種工作的頭文件和源文件,最后再開始整合比較好
②使用VS產生靜態庫詳細步驟,見我另外一篇博客:VS靜態庫的產生和使用

7、函數遞歸(遞推與回歸)

遞歸適當使用會大大減少代碼量

(1)什么是遞歸

函數“直接”或者“間接”調用自己的一種編程技巧,它通常把一件“大事”化成“小事”來進行求解,函數不斷遞推出去,然后再不斷地回歸,組合成“遞歸”一詞。
①最簡單的遞歸

//最簡單的遞歸,main函數自己調用自己
#includeint main()
{printf("abcd\n");
    main();
}//不斷打印abcd此時main將不斷消耗棧區的空間,最后棧溢出,程序崩潰

②按照順序打印一個數的每一位數字字符

#includemy_printf(unsigned int x)
{if(x >9)
    {my_printf(x / 10);
        printf("%u ", x % 10);
    }
    else
    {printf("%d ", x);
    }
}
//大事化小
//my_printf(1234)
//my_printf(123)4
//my_printf(12)34
//my_printf(1)234
int main()
{unsigned int number = 0;
    scanf("%u",&number);
    my_printf(number);
    return 0;
}

理解遞歸函數可以像上面一樣大事化小,或者是畫多個圖來理解
③自定義一個函數,實現和strlen函數一樣的功能

#includemy_strlen(const char *str)
{if(*str == '\0')
    {return 0;
    }
    else
    {return (1 + my_strlen(str+1));
    }
}

int main()
{char arr[10] = "abcdef";
    printf("%d", my_strlen(arr));

    return 0;
}

④第n個斐波那契數列(不考慮溢出的情況)

#includeint fun(int n)
{if (n<= 2)
        return 1;
    else
        return fun(n - 1) + fun(n - 2);
}
int main()
{int n = 0;
    while (scanf("%d", &n) == 1)
    {printf("第%d個斐波那契數列為%d\n", n, fun(n));
    }
    return 0;
}

⑤階乘的實現(不考慮溢出的情況)

#includeint fun(int n)
{if (n<= 1)
    {return 1;
    }
    else
    {return n * fun(n - 1);
    }
}
int main()
{int n = 0;
    scanf("%d", &n);
    printf("%d", fun(n));
    return 0;
}
(2)遞歸的必要條件

①存在限制條件(不能像上面main自己調用自己一樣,否則遲早棧溢出(stack overflow))讓遞歸停下
②每次遞歸都要接近這個條件,不能原封不動
遞歸有可能大量消耗??臻g,計算量極大,有的時候反而效率低,例如:求斐波那契數列的時候求第50個數就會很吃力了,運算時間很久

(3)迭代(循環)方式代替遞歸,斐波那契數列的另外一種寫法
#includeint function(int n)//用遞歸的方法求斐波那契數列
{int a=1;
    int b=1;
    int c=1;
    while(n >= 3)
    {c = a + b;
        a = b;
        b = c;
        n--;
    }
        return c;
}
int main()
{return 0;
}
#includeint function(int n)
{int a = 1;
    while(n >1)
    {a *= n;
        n--;    
    }
    return a;
}
int main()//利用迭代求n的階乘
{int n = 0;
    scanf("%d", &n);
    printf("%d", function(n));
    return 0;
}
(4)何時選遞歸

看情況,那種方便少缺陷就選哪種,沒必要一定要寫出遞歸(當然遞歸能大大減少代碼量)。況且迭代(循環)的方法會更加清晰。

8、函數如何返回多個值

(1)使用多個全局變量,在函數內部改變,則相當于函數返回了多個值
(2)返回一個數組指針,就可以通過數組返回多個值
(3)形參使用多個指針變量,在函數體內部解引用,改變指針指向的值
唯獨不能單用return,只能返回一個值,即一個函數只能返回單個結果,不能是多個

你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧

當前名稱:C語言入門知識——(1)函數基礎-創新互聯
網站路徑:http://vcdvsql.cn/article6/dijhog.html

成都網站建設公司_創新互聯,為您提供關鍵詞優化、外貿網站建設商城網站、網頁設計公司網站收錄、網站排名

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網頁設計公司