溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義

發(fā)布時(shí)間:2021-09-07 13:57:07 來(lái)源:億速云 閱讀:333 作者:chen 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要講解了“C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義”吧!

目錄
  • 本章目標(biāo)

  • 函數(shù)是什么

    • C語(yǔ)言中函數(shù)的分類(lèi)

  • 庫(kù)函數(shù)

    • 如何學(xué)會(huì)使用庫(kù)函數(shù)?

  • 自定義函數(shù)

    • 函數(shù)的參數(shù)

      • 函數(shù)的調(diào)用:

        • 函數(shù)的嵌套調(diào)用和鏈?zhǔn)皆L(fǎng)問(wèn)

          • 嵌套調(diào)用

          • 鏈?zhǔn)皆L(fǎng)問(wèn)

        • 函數(shù)的聲明和定義

          • 函數(shù)遞歸

            • 什么是遞歸?

            • 遞歸的兩個(gè)必要條件

            • 遞歸與迭代

          • 總結(jié)

            本章目標(biāo)

            禿頭俠們好呀,今天我們一起學(xué)習(xí)函數(shù)!

            目標(biāo): 本章主要掌握函數(shù)的基本使用和遞歸

            函數(shù)是什么

            數(shù)學(xué)中我們常見(jiàn)到函數(shù)的概念。但是你了解C語(yǔ)言中的函數(shù)嗎? 維基百科中對(duì)函數(shù)的定義:子程序

            在計(jì)算機(jī)科學(xué)中,子程序(英語(yǔ):Subroutine, procedure, function, routine, method,subprogram, callable unit),是一個(gè)大型程序中的某部分代碼, 由一個(gè)或多個(gè)語(yǔ)句塊組成。它負(fù)責(zé)完成某項(xiàng)特定任務(wù),而且相較于其他代 碼,具備相對(duì)的獨(dú)立性。
            一般會(huì)有輸入?yún)?shù)并有返回值,提供對(duì)過(guò)程的封裝和細(xì)節(jié)的隱藏。這些代碼通常被集成為軟件庫(kù)。

            C語(yǔ)言中函數(shù)的分類(lèi)

            1.庫(kù)函數(shù)

            2.自定義函數(shù)

            庫(kù)函數(shù)

            為什么會(huì)有庫(kù)函數(shù)?

            1.我們知道在我們學(xué)習(xí)C語(yǔ)言編程的時(shí)候,總是在一個(gè)代碼編寫(xiě)完成之后迫不及待的想知道結(jié)果,想把這個(gè)結(jié)果打印到我們的屏幕上看看。這個(gè)時(shí)候我們會(huì)頻繁的使用一個(gè)功能:將信息按照一定的格式打印到屏幕上(printf)。

            2.在編程的過(guò)程中我們會(huì)頻繁的做一些字符串的拷貝工作(strcpy)。

            3.在編程是我們也計(jì)算,總是會(huì)計(jì)算n的k次方這樣的運(yùn)算(pow)。

            像上面我們描述的基礎(chǔ)功能,它們不是業(yè)務(wù)性的代碼。我們?cè)陂_(kāi)發(fā)的過(guò)程中每個(gè)程序員都可能用的到,為了支持可移植性和提高程序的效率,所以C語(yǔ)言的基礎(chǔ)庫(kù)中提供了一系列類(lèi)似的庫(kù)函數(shù),方便程序員進(jìn)行軟件開(kāi)發(fā)。

            那怎么學(xué)習(xí)庫(kù)函數(shù)呢?

            這里我們簡(jiǎn)單的看看:https://www.cplusplus.com

            C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義

            簡(jiǎn)單的總結(jié),C語(yǔ)言常用的庫(kù)函數(shù)都有:

            • IO函數(shù)

            • 字符串操作函數(shù)

            • 字符操作函數(shù)

            • 內(nèi)存操作函數(shù)

            • 時(shí)間/日期函數(shù)

            • 數(shù)學(xué)函數(shù)

            • 其他庫(kù)函數(shù)

            注: 但是庫(kù)函數(shù)必須知道的一個(gè)秘密就是:使用庫(kù)函數(shù),必須包含 #include 對(duì)應(yīng)的頭文件。

            如何學(xué)會(huì)使用庫(kù)函數(shù)?

            庫(kù)函數(shù)不用全部記憶,需要的時(shí)候在此網(wǎng)址查找即可https://www.cplusplus.com

            (所以看懂英文很重要,當(dāng)然你也可以選擇翻譯軟件)

            自定義函數(shù)

            如果庫(kù)函數(shù)能干所有的事情,那還要程序員干什么?

            所以更加重要的是自定義函數(shù)。

            自定義函數(shù)和庫(kù)函數(shù)一樣,有函數(shù)名,返回值類(lèi)型和函數(shù)參數(shù)。 但是不一樣的是這些都是我們自己來(lái)設(shè) 計(jì)。這給程序員一個(gè)很大的發(fā)揮空間

            函數(shù)的組成:

            ret_type fun_name(para1, * )
            {
            statement;//語(yǔ)句項(xiàng)
            }
            ret_type 返回類(lèi)型
            fun_name 函數(shù)名
            para1 函數(shù)參數(shù)

            這里我們來(lái)舉一個(gè)例子:

            寫(xiě)一個(gè)函數(shù)可以找出兩個(gè)整數(shù)中的最大值

            #include <stdio.h>
            //get_max函數(shù)的設(shè)計(jì)
            int get_max(int x, int y)
            {
            return (x>y)?(x):(y);
            }
            int main()
            {
            int num1 = 10;
            int num2 = 20;
            int max = get_max(num1, num2);
            printf("max = %d\n", max);
            return 0;
            }

            return (x>y)?(x):(y);此語(yǔ)句的意思是判斷X是否大于Y,如果X>Y則選擇:左邊的X值,否則選擇:右邊的Y值。

            函數(shù)的參數(shù)

            實(shí)際參數(shù)(實(shí)參):

            真實(shí)傳給函數(shù)的參數(shù),叫實(shí)參。實(shí)參可以是:常量、變量、表達(dá)式、函數(shù)等。無(wú)論實(shí)參是何種類(lèi)型的量,在進(jìn)行函數(shù)調(diào)用時(shí),它們都必須有確定的值,以便把這些值傳送給形參。

            形式參數(shù)(形參):

            形式參數(shù)是指函數(shù)名后括號(hào)中的變量,因?yàn)樾问絽?shù)只有在函數(shù)被調(diào)用的過(guò)程中才實(shí)例化(分配內(nèi)存單元),所以叫形式參數(shù)。形式參數(shù)當(dāng)函數(shù)調(diào)用完成之后就自動(dòng)銷(xiāo)毀了。因此形式參數(shù)只在函數(shù)中有效。

            寫(xiě)一個(gè)函數(shù)可以交換兩個(gè)整形變量的內(nèi)容

            #include <stdio.h>
            void Swap1(int x, int y)
            {
            int tmp = 0;
            tmp = x;
            x = y;
            y = tmp;
            }
            void Swap2(int *px, int *py)
            {
            int tmp = 0;
            tmp = *px;
            *px = *py;
            *py = tmp;
            }
            int main()
            {
            int num1 = 1;
            int num2 = 2;
            Swap1(num1, num2);
            printf("Swap1::num1 = %d num2 = %d\n", num1, num2);
            Swap2(&num1, &num2);
            printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
            return 0;
            }

            上面代碼Swap1Swap2函數(shù)中的參數(shù) x,y,px,py 都是形式參數(shù)。在main函數(shù)中傳給Swap1num1,num2和傳給Swap2函數(shù)的&num1,&num2是實(shí)際參數(shù)。

            經(jīng)分析:

            C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義

            C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義

            這里可看到Swap1函數(shù)在調(diào)用時(shí),x,y擁有自己的空間,同時(shí)擁有了和實(shí)參一樣的內(nèi)容。所以我們可以簡(jiǎn)單的認(rèn)為:形參實(shí)例化之后其實(shí)相當(dāng)于實(shí)參的一份臨時(shí)拷貝

            Swap2函數(shù)在調(diào)用時(shí),px,py沒(méi)有再開(kāi)辟空間,而就是num1,num2的地址。

            函數(shù)的調(diào)用:

            傳值調(diào)用

            函數(shù)的形參和實(shí)參分別占有不同內(nèi)存塊,對(duì)形參的修改不會(huì)影響實(shí)參。

            傳址調(diào)用

            傳址調(diào)用是把函數(shù)外部創(chuàng)建變量的內(nèi)存地址傳遞給函數(shù)參數(shù)的一種調(diào)用函數(shù)的方式。
            這種傳參方式可以讓函數(shù)和函數(shù)外邊的變量建立起正真的聯(lián)系,也就是函數(shù)內(nèi)部可以直接操作函數(shù)外部的變量

            函數(shù)的嵌套調(diào)用和鏈?zhǔn)皆L(fǎng)問(wèn)

            函數(shù)和函數(shù)之間可以有機(jī)的組合的。

            嵌套調(diào)用

            #include <stdio.h>
            void new_line()
            {
            printf("hehe\n");
            }
            void three_line()
            {
            int i = 0;
            for(i=0; i<3; i++)
            	{
            new_line();
            	}
            }
            int main()
            {
            three_line();
            return 0;
            }

            鏈?zhǔn)皆L(fǎng)問(wèn)

            把一個(gè)函數(shù)的返回值作為另外一個(gè)函數(shù)的參數(shù)

            #include<stdio.h>
            #include<string.h>
            int main()
            {
            	char arr[20] = "hello";
            	int ret = strlen(strcat(arr, "bit"));
            	printf("%d\n", ret);
            	return 0;
            }

            自己按照前面說(shuō)的網(wǎng)址去學(xué)習(xí)一下 strlen和 strcat 看看這題答案是多少

            C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義

            這個(gè)結(jié)果又是多少呢?

            #include <stdio.h>
            int main()
            {
            printf("%d", printf("%d", printf("%d", 43)));
            return 0;
            }

            這里需要知道printf函數(shù)的返回值是多少

            printf函數(shù)的返回值是打印的字符數(shù)

            此題從最里面一層看printf("%d", 43)先打印出來(lái)43

            因?yàn)槭?個(gè)字符,所以返回值為2,

            printf("%d", printf("%d", 43))相當(dāng)于printf("%d", 2)

            然后打印2,因?yàn)槭?個(gè)字符,所以返回1

            printf("%d", printf("%d", printf("%d", 43)))相當(dāng)于printf("%d", 1)

            所以最終打印4321

            C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義

            函數(shù)的聲明和定義

            函數(shù)聲明:

            告訴編譯器有一個(gè)函數(shù)叫什么,參數(shù)是什么,返回類(lèi)型是什么。但是具體是不是存在,無(wú)關(guān)緊要。函數(shù)的聲明一般出現(xiàn)在函數(shù)的使用之前。要滿(mǎn)足先聲明后使用。函數(shù)的聲明一般要放在頭文件中的。

            函數(shù)定義:

            函數(shù)的定義是指函數(shù)的具體實(shí)現(xiàn),交待函數(shù)的功能實(shí)現(xiàn)。

            所以可以在比如test.h里放函數(shù)的聲明
            在test.c中放函數(shù)的定義實(shí)現(xiàn)

            函數(shù)遞歸

            什么是遞歸?

            程序調(diào)用自身的編程技巧稱(chēng)為遞歸( recursion)。 遞歸做為一種算法在程序設(shè)計(jì)語(yǔ)言中廣泛應(yīng)用。一個(gè)過(guò)程或函數(shù)在其定義或說(shuō)明中有直接或間接調(diào)用自身的一種方法,它通常把一個(gè)大型復(fù)雜的問(wèn)題層層轉(zhuǎn)化為一個(gè)與原問(wèn)題相似的規(guī)模較小的問(wèn)題來(lái)求解,遞歸策略只需少量的程序就可描述出解題過(guò)程所需要的多次重復(fù)計(jì)算,大大地減少了程序的代碼量。 遞歸的主要思考方式在于:把大事化小

            遞歸的兩個(gè)必要條件

            • 存在限制條件,當(dāng)滿(mǎn)足這個(gè)限制條件的時(shí)候,遞歸便不再繼續(xù)。

            • 每次遞歸調(diào)用之后越來(lái)越接近這個(gè)限制條件

            接受一個(gè)整型值(無(wú)符號(hào)),按照順序打印它的每一位。 例如: 輸入:1234,輸出 1 2 3 4

            #include<stdio.h>
            #include<string.h>
            void print(int n)
            {
            	if (n > 9)
            	{
            		print(n / 10);
            	}
            	printf("%d ", n % 10);
            }
            int main()
            {
            	int num = 1234;
            	print(num);
            	return 0;
            }

            編寫(xiě)函數(shù)不允許創(chuàng)建臨時(shí)變量,求字符串的長(zhǎng)度。

            #include <stdio.h>
            int Strlen(const char* str)
            {
            	if (*str == '\0')
            		return 0;
            	else return 1 + Strlen(str + 1);
            }
            int main()
            {
            	char* p = "abcdef";
            	int len = Strlen(p);
            	printf("%d\n", len);
            	return 0;
            }

            以上兩個(gè)代碼,都是對(duì)函數(shù)遞歸的使用

            遞歸與迭代

            求n的階乘。(不考慮溢出)

            int factorial(int n)
            {
            	if (n <= 1)
            		return 1;
            	else
            		return n * factorial(n - 1);
            }
            int main()
            {
            	int n = 0;
            	scanf("%d", &n);
            	int ret = factorial(n);
            	printf("%d\n", ret);
            	return 0;
            }

            求第n個(gè)斐波那契數(shù)。(不考慮溢出)

            首先什么是斐波那契數(shù)?

            就是前兩數(shù)之和等于第三個(gè)數(shù)

            int fib(int n)
            {
            if (n <= 2)
            return 1;
            else
            return fib(n - 1) + fib(n - 2);
            }

            運(yùn)行結(jié)果需要很長(zhǎng)時(shí)間才顯示出來(lái)為什么?

            我們發(fā)現(xiàn)出現(xiàn)了問(wèn)題

            • 在使用 fib 這個(gè)函數(shù)的時(shí)候如果我們要計(jì)算第50個(gè)斐波那契數(shù)字的時(shí)候特別耗費(fèi)時(shí)間。

            • 使用factorial函數(shù)求10000的階乘(不考慮結(jié)果的正確性),程序會(huì)崩潰

            我們發(fā)現(xiàn) fib 函數(shù)在調(diào)用的過(guò)程中很多計(jì)算其實(shí)在一直重復(fù)

            int count = 0;//全局變量
            int fib(int n)
            {
            if(n == 3)
            count++;
            if (n <= 2)
            return 1;
            else
            return fib(n - 1) + fib(n - 2);
            }

            我們用一段代碼來(lái)看一下,結(jié)果發(fā)現(xiàn)count是一個(gè)很大的值,說(shuō)明代碼重復(fù)計(jì)算了很多次

            在調(diào)試 factorial 函數(shù)的時(shí)候,如果你的參數(shù)比較大,那就會(huì)報(bào)錯(cuò): stack overflow(棧溢出) 這樣的信息。 系統(tǒng)分配給程序的??臻g是有限的,但是如果出現(xiàn)了死循環(huán),或者(死遞歸),這樣有可能導(dǎo)致一直開(kāi)辟??臻g,最終產(chǎn)生??臻g耗盡的情況,這樣的現(xiàn)象我們稱(chēng)為棧溢出。

            所以有時(shí)使用遞歸可以簡(jiǎn)化問(wèn)題,有時(shí)反而把問(wèn)題復(fù)雜了

            調(diào)整后:

            //求n的階乘
            int factorial(int n)
            {
            	int tmp = 1;
            	while (n > 1)
            	{
            		tmp *= n;
            		n -= 1;
            	}
            	return tmp;
            }
            //求第n個(gè)斐波那契數(shù)
            #include<stdio.h>
            int Fib(int n)
            {
            	int a = 1, b = 1, c = 1;
            	while (n > 2)
            	{
            		c = a + b;
            		a = b;
            		b = c;
            		n--;
            	}
            	return c;
            }
            int main()
            {
            	int n = 0;
            	scanf("%d", &n);
            	int ret = Fib(n);
            	printf("%d\n", ret);
            	return 0;
            }

            所以要根據(jù)不同的情況使用不同的方法,才能使得問(wèn)題更高效地解決!

            感謝各位的閱讀,以上就是“C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)C語(yǔ)言函數(shù)的基本使用以及函數(shù)的聲明與定義這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

            向AI問(wèn)一下細(xì)節(jié)

            免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

            AI