您好,登錄后才能下訂單哦!
這篇文章主要介紹“C語言函數(shù)的知識點(diǎn)有哪些”,在日常操作中,相信很多人在C語言函數(shù)的知識點(diǎn)有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C語言函數(shù)的知識點(diǎn)有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
函數(shù)的概念
函數(shù)是具有特定功能的程序部件(可當(dāng)黑盒使用)
函數(shù)有明確的使用方式(固定輸入對應(yīng)固定輸出)
函數(shù)在程序中可重復(fù)使用(程序中的工具)
函數(shù)的類型
數(shù)據(jù)處理(數(shù)據(jù)→數(shù)據(jù))
通過某種規(guī)則將 x處理成 y,如: y = 2x +1
過程定義(數(shù)據(jù)→功能)
(根據(jù)數(shù)據(jù))執(zhí)行一系列動作,進(jìn)而完成某種功能,如:屏幕打印
C語言中函數(shù)的組成部分
函數(shù)名:函數(shù)的唯一標(biāo)識
函數(shù)參數(shù)定義:數(shù)據(jù)輸入(數(shù)據(jù)→數(shù)據(jù),數(shù)據(jù)→動作)
函數(shù)返回類型:
數(shù)據(jù)輸出(數(shù)據(jù)→數(shù)據(jù))
無返回值(數(shù)據(jù)→動作)
廣義函數(shù)示例:
返回類型 函數(shù)名(參數(shù)1,參數(shù)2)
{
程序語句1;
程序語句2;
......;
程序語句n;
}
C語言中的函數(shù)示例
函數(shù)的調(diào)用
通過函數(shù)名調(diào)用已經(jīng)定義好的函數(shù)
函數(shù)調(diào)用時需要依次指定函數(shù)參數(shù)的具體值
函數(shù)調(diào)用的結(jié)果(返回值)可保存在同類型的變量中
下面看一段函數(shù)調(diào)用的代碼:
#include <stdio.h> int func_demo( int x ) { int y = 0; y = 2 * x - 1; return y; } int main() { int r1 = func_demo(1); int r2 = func_demo(5); int r3 = func_demo(10); printf("r1 = %d\n", r1); printf("r2 = %d\n", r2); printf("r3 = %d\n", r3); return 0; }
下面為輸出結(jié)果:
下面再看一段編寫函數(shù)計算累加和的代碼:
#include <stdio.h> int sum (int n) { int r = 0; int i = 0; for(i=1; i<=n; i++) { r += i; } return r; } int main() { int o[10] = {10, 20, 30, 40, 50, 100}; int r[10]; int i = 0; for(i=0; i<10; i++) { r[i] = sum(o[i]); } for(i=0; i<10; i++) { printf("sum(%d) = %d\n", o[i], r[i]); } return 0; }
下面為輸出結(jié)果:
采用數(shù)組可以便捷的求出從1加到指定的數(shù)。
小結(jié)
函數(shù)是具有特定功能的程序部件
函數(shù)由函數(shù)名,參數(shù),返回類型以及函數(shù)體組成
通過函數(shù)名調(diào)用已經(jīng)定義好的函數(shù),并同時傳入?yún)?shù)值
函數(shù)的本質(zhì)就是可重復(fù)利用的代碼段
再論C語言程序的入口
一般情況下,C語言程序從main()開始執(zhí)行
深入理解main()
main() 是應(yīng)用程序與操作系統(tǒng)的一個“約定”
當(dāng)操作系統(tǒng)運(yùn)行應(yīng)用程序時,首先調(diào)用的就是 main() 函數(shù)
應(yīng)用程序必須運(yùn)行于操作系統(tǒng),接受操作系統(tǒng)管理
應(yīng)用程序的運(yùn)行
應(yīng)用程序運(yùn)行流程
下面看一段代碼,實(shí)際感受一下吧:
#include<stdio.h> #include<stdlib.h> int main() { printf("Hello World!\n"); system("pause"); return 0; }
沒錯,就是這個簡單的不能再簡單的代碼,打開Test.exe,得到下圖:
下面來證明一下 返回值 0 是返回給操作系統(tǒng),首先打開命令提示符,如下:
然后在命令提示符上切換到這個目錄,采用 cd 命令,如下:
然后運(yùn)行 Test.exe,如下:
按下回車,輸入echo %errorlevel%
,如下:
可以看到輸出 0 ,這是 main 函數(shù)中的返回值。如果把 return 0那里換成 return 666,那么運(yùn)行 echo %errorlevel% 會輸出 666。這就說明返回值成功返回給操作系統(tǒng)。
核心本質(zhì)
C程序由一系列不同功能的函數(shù)構(gòu)成
函數(shù)之間通過相互調(diào)用組合“小功能”構(gòu)成“大功能”
整個C程序的功能由函數(shù)的組合調(diào)用完成
工具包的本質(zhì)
工具包就是函數(shù)集,包含了一系列定義好的函數(shù)
#include 語句用于聲明需要使用工具包中的函數(shù)
工具包中的函數(shù)由其它開發(fā)者通過C語言編寫
也可根據(jù)項目需要自行編寫私有工具包
小結(jié)
main() 是C程序中的入口函數(shù)(第一個被調(diào)用的函數(shù))
main() 函數(shù)被操作系統(tǒng)調(diào)用(返回值也傳給操作系統(tǒng))
工具包的本質(zhì)是一個函數(shù)集合
可以根據(jù)需要自行定義工具包(函數(shù)集)
函數(shù)定義與函數(shù)調(diào)用
函數(shù)在被調(diào)用前必須完整定義
函數(shù)可以先被聲明,再被定義
聲明時,必須給出函數(shù)三要素(函數(shù)名,參數(shù)列表,返回類型)
定義時,必須完整給出函數(shù)體定義
特殊的基礎(chǔ)類型
C語言中存在空類型(void),這種類型表示“空”
void 不能用于定義具體變量(沒有任何數(shù)據(jù)屬于空類型)
void 常用于函數(shù)定義,表示無返回值或無參數(shù)
void 深入理解
void 是基礎(chǔ)類型,但不是基礎(chǔ)數(shù)據(jù)類型,無法定義變量
void可用于函數(shù)參數(shù),表示函數(shù)無參數(shù)
void 可用于函數(shù)返回類型,表示函數(shù)無返回值
所以說,下面程序的寫法就是錯誤的。
#include <stdio.h> void demo(void i) { return i; } int main() { void v; void x = v; demo(x); return 0; }
注意事項
C語言中的函數(shù)如果確定不需要參數(shù),那么用 void 定義參數(shù),而不是不寫參數(shù)。
#include <stdio.h> void f( ) { printf("void f() \n"); } void g(void) { printf("void g() \n"); } int main() { f(); f(1, 2); g(); // g(1); // ERROR return 0; }
下面為輸出結(jié)果:
可以看出,f 函數(shù)的輸入?yún)?shù)是沒有限制的,而g 函數(shù)沒有輸入?yún)?shù),這點(diǎn)要特別注意。
關(guān)于函數(shù)返回
return 語句直接返回主調(diào)函數(shù),后續(xù)代碼不再執(zhí)行
對于無返回值函數(shù)
return 可以直接使用,無需跟上返回值
當(dāng)函數(shù)體中沒有 return 語句時,最后一條語句執(zhí)行后自動返回
對于有返回值的函數(shù)
return 必須跟上一個合法返回值,所有執(zhí)行分支都必須顯示返回值
return 語句必須出現(xiàn)在函數(shù)體中,并且必須被執(zhí)行
小結(jié)
函數(shù)可以先被聲明,再被定義(調(diào)用前必須給出完整定義)
C語言中存在空類型(void) ,這種類型表示“空”
void是基礎(chǔ)類型,但不是基礎(chǔ)數(shù)據(jù)類型
return語句直接返回主調(diào)函數(shù),后續(xù)代碼不再執(zhí)行
函數(shù)中的所有執(zhí)行分支必須存在return語句
深入函數(shù)參數(shù)
函數(shù)參數(shù)在函數(shù)定義時并沒有確定的值(形參)
函數(shù)參數(shù)的具體值在函數(shù)調(diào)用時指定(實(shí)參)
函數(shù)參數(shù)的本質(zhì)是變量
函數(shù)調(diào)用時指定的實(shí)參用于對形參進(jìn)行初始化,初始化之后形參在函數(shù)內(nèi)部等同于普通變量。
下面看一段代碼:
#include <stdio.h> int test(int n); int main() { int i = 3; int j = test(i); printf("i = %d, j = %d\n", i, j); return 0; } int test(int n) { n = n * 10; return n; }
下面為輸出結(jié)果:
特殊的數(shù)組參數(shù)
可以在定義函數(shù)時使用數(shù)組形參(如: int f( int a[5] );)
數(shù)組形參需要使用同類型數(shù)組作為實(shí)參
在C語言中,數(shù)組作為函數(shù)參數(shù)傳遞時大小信息丟失
在函數(shù)內(nèi)部修改數(shù)組形參,將影響數(shù)組實(shí)參
注意事項
數(shù)組形參已經(jīng)發(fā)生退化,不包含數(shù)組大小信息
示例:void func (int a[ ])
等價于void func (int a[1])
等價于void func (int a[10])
等價于void func (int a[100])
下面看一段代碼,加深印象:
#include <stdio.h> void demo(int a[3]) { a[0] = 50; } int sum(int a[], int len) { int ret = 0; int i = 0; while( i < len ) { ret += a[i]; i++; } return ret; } int main() { int arr1[5] = {0, 1, 2, 3, 4}; // arr1[0] -> 0 int arr2[10] = {0, 10, 20, 30, 40}; // arr2[0] -> 0 demo(arr1); demo(arr2); printf("arr1[0] = %d\n", arr1[0]); printf("arr2[0] = %d\n", arr2[0]); printf("sum(arr1) = %d\n", sum(arr1, 5)); printf("sum(arr2) = %d\n", sum(arr2, 10)); return 0; }
下面為輸出結(jié)果:
這里注意一下這句話:在函數(shù)內(nèi)部修改數(shù)組形參,將影響數(shù)組實(shí)參,所以當(dāng)調(diào)用 demo 函數(shù)后,實(shí)參的 arr1[0] 和 arr2[0] 都變成了50。
小結(jié)
函數(shù)定義時參數(shù)沒有具體值,函數(shù)調(diào)用時指定參數(shù)初始值
函數(shù)參數(shù)在函數(shù)內(nèi)部等同于普通變量
在C語言中,數(shù)組作為函數(shù)參數(shù)傳遞時大小信息丟失
在函數(shù)內(nèi)部修改數(shù)組形參,將影響數(shù)組實(shí)參
在C語言中,數(shù)組作為函數(shù)參數(shù)傳遞時大小信息丟失在函數(shù)內(nèi)部修改數(shù)組形參,將影響數(shù)組實(shí)參
排序的一般定義
排序是計算機(jī)內(nèi)經(jīng)常進(jìn)行的一種操作,其目的是將一組“無序”的數(shù)據(jù)元素調(diào)整為“有序”的數(shù)據(jù)元素。
排序中的關(guān)鍵操作
比較
任意兩個數(shù)據(jù)元素通過比較操作確定先后次序
交換
數(shù)據(jù)元素之間需要交換才能得到預(yù)期結(jié)果
核心思想
每次(例如第i次,i = O,1,..., n-2) 從后面 n-i 個待排的數(shù)據(jù)元素中選出最小元素,作為第 i 個元素。
解決方案
編寫函數(shù) int Min(int a[], int b, int e) 選擇最小元素
功能定義:在數(shù)組 a 的 b ...e ] 范圍尋找最小元素
返回值:最小元素在數(shù)組中的下標(biāo)
循環(huán)遍歷數(shù)組,將每次找到的最小元素交換就位
下面看一下示例代碼:
#include <stdio.h> int Min(int a[], int b, int e) { int r = b; int i = 0; for(i=b; i<=e; i++) if( a[r] > a[i] ) r = i; return r; } void Sort(int a[], int n) { int i = 0; int j = 0; int k = 0; for(i=0; i<n; i++) { j = Min(a, i, n-1); if( i != j ) { k = a[i]; a[i] = a[j]; a[j] = k; } } } void Print(int a[], int n) { int i = 0; while( i < n ) printf("%d ", a[i++]); printf("\n"); } int main() { int a[5] = {20, 30, 10, 40, 50}; printf("Origin: \n"); Print(a, 5); Sort(a, 5); printf("After: \n"); Print(a, 5); return 0; }
下面為輸出結(jié)果:
小結(jié)
排序是將一組“無序”的數(shù)據(jù)調(diào)整為“有序”的數(shù)據(jù)
排序中的關(guān)鍵操作為比較和交換
排序時每次選擇未排序數(shù)據(jù)中的最小值,并交換就位
每次選擇交換使得數(shù)據(jù)逐漸有序,最終完全有序
C語言中變量的分類
局部變量
函數(shù)內(nèi)部定義的變量(隸屬于當(dāng)前函數(shù))
只能在當(dāng)前函數(shù)中訪問使用
全局變量
全局范圍內(nèi)的變量(不特定隸屬于任意一個函數(shù))
可以在任意函數(shù)中訪問使用
同名變量的問題
不同函數(shù)中的局部變量可以同名(不會產(chǎn)生沖突)
全局變量不能同名(會產(chǎn)生命名沖突)
當(dāng)局部變量和全局變量同名時,優(yōu)先使用局部變量
同名變量規(guī)則
存在多個同名變量時,優(yōu)先使用最近定義的變量。
下面看一段代碼,感受一下:
#include <stdio.h> int var = 100; // 全局變量 void f(int var) // var <==> 局部變量 { var++; printf("var = %d\n", var); } int main() { int var = 10; // 局部變量 f(var); // f(10); printf("var = %d\n", var); // var = 10; return 0; }
下面為輸出結(jié)果:
變量的作用域
變量的作用域指的是變量定義后的可訪問范圍
不同變量的作用域可以有重疊
不同名變量在重疊作用域內(nèi)可分別訪問
在重疊作用域內(nèi),只可訪問最近定義的同名變量
局部變量的作用域
代碼塊:從 { 開始到 } 結(jié)束的一段代碼
變量只能定義在代碼塊的開始處,即: { 之后,執(zhí)行語句之前
變量的作用域從定義開始到當(dāng)前代碼塊結(jié)束
當(dāng)變量的作用域結(jié)束后,變量不可用 (無法直接訪問)
全局變量的作用域
全局作用域:可在程序的各個角落訪問并使用
文件作用域:只能在當(dāng)前代碼文件中訪問并使用
全局作用域:可在程序的各個角落訪問并使用一文件作用域:只能在當(dāng)前代碼文件中訪問并使用
工程開發(fā)中,全局變量通常以 g_ 作為前綴命名(工程約定)
下面看一段代碼,感受一下:
#include <stdio.h> int var = 100; // 全局變量 int main() { int var = 10; // 局部變量 { int var = 1; // 局部變量 printf("var = %d\n", var); } printf("var = %d\n", var); // var = 10; return 0; }
下面為輸出結(jié)果:
注意:存在多個同名變量時,優(yōu)先使用最近定義的變量
小結(jié)
局部變量只能在當(dāng)前函數(shù)中使用,全局變量可在任何地方使用
當(dāng)局部變量和全局變量同名時,優(yōu)先使用局部變量
變量的作用域可重疊,內(nèi)層作用域覆蓋外層作用域
離開作用域后變量不可訪問(無法繼續(xù)使用)
不同變量的物理存儲區(qū)域
在現(xiàn)代計算機(jī)系統(tǒng)中,物理內(nèi)存被分為不同區(qū)域
區(qū)域不同,用途不同,不同種類的變量位于不同區(qū)域
全局?jǐn)?shù)據(jù)區(qū):存放全局變量,靜態(tài)變量
??臻g:存放函數(shù)參數(shù),局部變量
堆空間:用于動態(tài)創(chuàng)建變量
生命期:變量從創(chuàng)建到銷毀的時間(即:合法可用的時間)
不同變量的生命期
全局?jǐn)?shù)據(jù)區(qū)中的變量
程序開始運(yùn)行時創(chuàng)建,程序結(jié)束時被銷毀,整個程序運(yùn)行期合法可用
棧空間中的變量
進(jìn)入作用域時創(chuàng)建,離開作用域時銷毀(自動銷毀)
局部變量在函數(shù)調(diào)用返回后銷毀
下面看一段代碼,感受一下變量生命期:
#include <stdio.h> int var = 1; void func() { printf("var = %d\n", var); } int main() { int var = 2; int i = 0; for(i=0; i<5; i++) { int var = 4; var += i; printf("var = %d\n", var); } func(); printf("var = %d\n", var); return 0; }
下面為輸出結(jié)果:
這個例子充分展示了變量的生命周期,值得仔細(xì)體會。
作用域與生命期無本質(zhì)聯(lián)系
作用域規(guī)則是語法層面對變量是否可訪問的規(guī)定
生命期是二進(jìn)制層面上變量存在于內(nèi)存中的時間
可能的情況
作用域外無法訪問的變量,可能在其生命期中(靜態(tài)局部變量)
作用域內(nèi)可訪問的變量,可能已經(jīng)被銷毀(堆變量)
生命期中的變量,可能無法訪問(文件作用域全局變量)
靜態(tài)變量
static 是C語言中的關(guān)鍵字
static 修飾的局部變量創(chuàng)建于全局?jǐn)?shù)據(jù)區(qū)(擁有程序生命期)
static 修飾的全局變量只有文件作用域(文件之外無法訪問)
static 局部變量只會初始化一次,作用域與普通變量無異
變量的生命期由變量存儲位置決定
static 將變量存儲于全局?jǐn)?shù)據(jù)區(qū),默認(rèn)初始化為0
auto 將變量存儲于棧空間,默認(rèn)初始化為隨機(jī)值
register 將變量存儲于寄存器,默認(rèn)初始化為隨機(jī)值
不同類型變量示例
#include <stdio.h> int g_var = 1; static int g_sVar = 2; int main() { static int s_var = 3; auto int v = 4; register int rv = 5; printf("g_var = %d\n", g_var); printf("g_sVar = %d\n", g_sVar); printf("s_var = %d\n", s_var); printf("v = %d\n", v); printf("rv = %d\n", rv); return 0; }
下面為輸出結(jié)果:
下面看一段代碼,感受一下 static 關(guān)鍵詞:
#include <stdio.h> int global; int func(int x) { static int s_var; // 全局?jǐn)?shù)據(jù)區(qū)中的變量,默認(rèn)初始化為 0 // 并且,只做一次初始化 s_var += x; return s_var; } int main() { int i = 0; for(i=1; i<=5; i++) { printf("func(%d) = %d\n", i, func(i)); } printf("func(0) = %d\n", func(0)); printf("global = %d\n", global); return 0; }
下面為輸出結(jié)果:
這里注意:全局?jǐn)?shù)據(jù)區(qū)中的變量,默認(rèn)初始化為 0 ,并且,只做一次初始化
小結(jié)
變量生命期指變量合法可用的時間
生命期是變量存在于內(nèi)存中的時間
作用域與生命期無本質(zhì)聯(lián)系
作用域和生命期用于判斷變量是否可訪問
static | auto(默認(rèn)) | register | |
局部變量 | 全局?jǐn)?shù)據(jù)區(qū) | ??臻g | 寄存器(可能) |
全局變量 | 全局?jǐn)?shù)據(jù)區(qū) | --- | --- |
題目:編寫函數(shù),將字符串轉(zhuǎn)換為整型數(shù)
函數(shù)原型:int str2int(char s[]);
參數(shù):可以代表整型數(shù)的字符串
返回值:整型值
注意事項:
整型數(shù)可以存在符號位,如: "-12345"
字符串本身可能不是一個合法整型數(shù),如:"123xyz45"
算法流程
上代碼:
#include <stdio.h> int getNumber(char c) { int ret = -1; if( ('0' <= c) && (c <= '9') ) ret = c - '0'; return ret; } int str2int(char str[]) { int ret = 0; int sign = 0; int i = 0; if( getNumber(str[0]) != -1 ) { sign = 1; i = 0; } else if( str[0] == '+' ) { sign = 1; i = 1; } else if( str[0] == '-' ) { sign = -1; i = 1; } while( sign && str[i] ) { int n = getNumber(str[i]); if( n != -1 ) ret = ret * 10 + n; else break; i++; } ret = sign * ret; return ret; } int main() { printf("%d\n", str2int("123")); printf("%d\n", str2int("-12345")); printf("%d\n", str2int("567xyz89")); printf("%d\n", str2int("abc")); printf("%d\n", str2int("-xyz")); return 0; }
下面為輸出結(jié)果:
在程序設(shè)計中,將函數(shù)自調(diào)用稱為遞歸調(diào)用
遞歸是一種數(shù)學(xué)上分而自治的思想
將原問題分解為規(guī)模較小的問題進(jìn)行處理
問題的分解是有限的(遞歸不能無限進(jìn)行)
遞歸模型的一般表示法
遞歸在程序設(shè)計中的應(yīng)用
遞歸函數(shù)
函數(shù)體中存在自我調(diào)用的函數(shù)
遞歸函數(shù)必須有遞歸出口(邊界條件)
函數(shù)的無限遞歸將導(dǎo)致程序崩潰
遞歸思想的應(yīng)用:
自然數(shù)列求和:sum( n ) = 1 +2 +3 + ... + n
斐波拉契數(shù)列:1,1,2,3,5,8,13,21,...
上代碼:
#include <stdio.h> int sum(int n) { int ret = 0; if( n == 1 ) ret = 1; else ret = n + sum(n-1); return ret; } int fac(int n) { int ret = 0; if( n == 1 ) ret = 1; else if( n == 2 ) ret = 1; else if( n >= 3 ) ret = fac(n-1) + fac(n-2); else ret = -1; return ret; } int main() { int i = 0; printf("sum(1) = %d\n", sum(1)); printf("sum(10) = %d\n", sum(10)); printf("sum(100) = %d\n", sum(100)); for(i=1; i<=10; i++) { printf("%d, ", fac(i)); } printf("\n"); return 0; }
下面為輸出結(jié)果:
到此,關(guān)于“C語言函數(shù)的知識點(diǎn)有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。