c4-function,c語言.ppt_第1頁
c4-function,c語言.ppt_第2頁
c4-function,c語言.ppt_第3頁
c4-function,c語言.ppt_第4頁
c4-function,c語言.ppt_第5頁
已閱讀5頁,還剩89頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Computer Science & Technology HIT,September 2011,High-Level Language Programming,ZhongChuan Fu (傅忠傳),Chapter IV,Functions 函數(shù),Outline,函數(shù)原型(prototype)。函數(shù)definition定義和函數(shù)原型prototype說明declaration的方法及二者區(qū)別,調(diào)用。 掌握函數(shù)的參數(shù)傳遞方式與函數(shù)調(diào)用方法實參argument,形參parameter。 理解掌握variable變量的scope作用域和storage class存儲類的概念。,Contents,functions函數(shù) scope and storage class 變量作用域與存儲類 *homework Pitfalls 5. #define macro 宏定義,Contents,function函數(shù) 1.1. functions相關(guān)概念 1.2.function definition函數(shù)定義 1.3. return value函數(shù)的返回值 1.4.function calling調(diào)用與parameter passing參數(shù)傳遞 1.5. prototype declaration函數(shù)原型聲明 scope and storage class變量作用域和存儲類 *homework Pitfalls *#define macro宏定義(macro substitution),Structure of a typical C program,functions函數(shù),(1) functions commercial programs have hundreds or thousands of lines of code. In order to reduce the complexity involved in writing large programs, they have to be broken into smaller, less complex parts. Functions, along with classes become the building block of c/c+.即所謂的分而治之(divide and conquer).,(3)C程序的執(zhí)行從main()函數(shù)開始。沒有main( )函數(shù)的程序,不能執(zhí)行。 調(diào)用其他函數(shù)后流程回到main函數(shù),在main函數(shù)結(jié)束整個程序運行。 main函數(shù)是系統(tǒng)定義的。,(4)主函數(shù)可以調(diào)用任意子函數(shù),而子函數(shù)不能調(diào)用主函數(shù)。 子函數(shù)的地位是平等的,相互獨立,相互無從屬關(guān)系,可以相互調(diào)用。 子函數(shù)可以直接或間接地自己調(diào)用自己,即遞歸調(diào)用。,functions(1),Built-in standard library functions標準庫函數(shù) 使用:用#include 命令將調(diào)用函數(shù)所需頭 文件包含到源文件中之后可直接調(diào)用。,從用戶角度看:,如:scanf、printf、sqrt、getchar等,用戶自定義函數(shù)user defined functions:先定義而后使用(調(diào)用)! 用戶自定義函數(shù)過程:,definition定義,declaration聲明, call調(diào)用,無參函數(shù) int a( ) ,functions,從函數(shù)的形式看:,有參函數(shù) int max( x , y ) ,主調(diào)函數(shù)調(diào)用 被調(diào)函數(shù)時,不 能傳遞參數(shù)(數(shù) 據(jù))。一般用來執(zhí) 行指定的一組 操作。,User defined function定義,(1)傳統(tǒng)風格函數(shù)定義: 類型 函數(shù)名(形參表列) 形參說明 說明部分 語句 ,形參表列是用逗號分隔 的形參parameter,形參又稱為形式參數(shù)、啞元、虛參、虛擬參數(shù)。在形參說明中,說明形參表中每個形參的類型。,函數(shù)類型:用來說明函數(shù)返回值的類型。當函數(shù)返回值是整型或不要求返回值時,可省略類型說明。無返回值可用“空類型” void,函數(shù)定義時的參數(shù)稱為行參parameter;函數(shù)調(diào)用時的參數(shù)稱為實參argument。,(2)函數(shù)的現(xiàn)代定義方式,類型 函數(shù)名 (形參說明表列) 說明部分 語句 ,函數(shù)體,將形參說明包含到形參列表中,即在 列出形參的同時,說明形參類型。 形參列表: 類型 參數(shù)1,類型 參數(shù)2, ,類型 參數(shù)n,傳統(tǒng)定義舉例 現(xiàn)代定義舉例 int add(x, y) int add(int x, int y) int x, y; ,程序舉例1,編寫一個求模函數(shù)。,int mod(int m,int n) int x; x=m%n; return x; ,當函數(shù)不需要參數(shù)時,省略形參表列和形參說明,但不能省略括號,函數(shù)名后的括號內(nèi)為空,即為無參函數(shù)。 Void print_info( ) printf(“-n“); printf(“Welcome to HIT.n“); printf(“-n“); ,函數(shù)定義說明,當函數(shù)為有參函數(shù)時,應對其全部參數(shù)進行數(shù)據(jù)類型說明。,函數(shù)使用標識符給函數(shù)命名,即取名原則與變量名相同。 Int max(float x, float y) float z; z=xy?x: y; return(z); ,函數(shù)名前面的類型即為函數(shù)的類型。 函數(shù)的類型實際上是函數(shù)返回值的類型。當被調(diào)函數(shù)無返回值時,實際上就是帶回的是一個不確定的值,可用“void” 定義“無類型”(或稱“空類型”)。當函數(shù)的返回值為整型時,函數(shù)名前的數(shù)據(jù)類型可以省略。,形參表列中,形參與形參間用“,”分隔。 形參說明是對形式參數(shù)的數(shù)據(jù)類型的說明。,在定義函數(shù)中指定的形參,在未被調(diào)用時,他們不占用內(nèi)存單元,只有在該函數(shù)被調(diào)用時,函數(shù)中的形參才被分配 內(nèi)存單元。,Return value函數(shù)返回值,功能,將被調(diào)函數(shù)中的結(jié)果值返回給主調(diào)函數(shù)。,語句,return(返回值表達式);,舉例,int add(int x, int y) int z; z=x+y; return(z); ,Return,當函數(shù)要求返回函數(shù)值時,函數(shù)體內(nèi)最后執(zhí)行的語句應為返回語句return。 一個函數(shù)中可以有一條或多條return語句,只有被執(zhí)行到的return語句才起作用。當函數(shù)不需要返回值時 ,后面不加括號和表達式,也可沒有return。,當函數(shù)值的類型和return語句后的表達式類型不一致時,則以函數(shù)類型為準。對數(shù)值型數(shù)據(jù)可自動轉(zhuǎn)換。 int max(float x, float y) float z; z=xy?x: y; return(z); ,有些系統(tǒng)可省略return后的括號。 return _ 表達式; 4.“函數(shù)類型就是函數(shù)中return語句后表達式的類型”是錯誤! 5.return語句完成了被調(diào)函數(shù)向主調(diào)函數(shù)值傳遞的功能。,Function definition函數(shù)定義,下面add函數(shù)的功能是求兩個參數(shù)的和,并將和值返回調(diào)用函數(shù)。函數(shù)中的錯誤是: void add(float a, float b) float c; c=a+b; return c; ,void add(float a, float b),float add(float a, float b),calling of a function,格式,函數(shù)名(實參argument表列),與調(diào)用標準函數(shù)相同,說明,1.無參函數(shù)實參形參均為空;有參函數(shù)調(diào)用時,實參列表中各參數(shù)以逗號分隔,且實參與形參應在個數(shù)、類型、位置一一對應。即要按形參定義為準。,2.實參可以是常量、變量或表達式,調(diào) 用函數(shù)前必須保證每個實參都有確定值。 且調(diào)用時發(fā)生了實參向虛參進行參數(shù)傳 遞的過程。,3. 調(diào)用時,主調(diào)函數(shù)與被掉函數(shù)發(fā)生了程序 執(zhí)行權(quán)的轉(zhuǎn)移,被調(diào)函數(shù)只有在被調(diào)用時, 才被調(diào)入內(nèi)存,獲得程序執(zhí)行權(quán);函數(shù)退出時, 將返回值返回給主調(diào)函數(shù),被掉所占存儲空間 被釋放,程序執(zhí)行權(quán)返還給主調(diào)函數(shù),主調(diào)函 數(shù)繼續(xù)在斷點處執(zhí)行 。,4. 形參變量和實參變量占據(jù)不同的存儲 單元,有不同的作用域。,5.實參argument和形參parameter 的數(shù)據(jù)傳遞是單向的(即只有實參傳遞給形參,而不能由形參傳回數(shù)據(jù)給實參)。,Example (3),輾轉(zhuǎn)相除法求最大公約數(shù)。,#include main() int m,n,r; scanf(“%d,%d“, ,int mod(int m,int n) int x; x=m%n; return x; ,函數(shù)調(diào)用方式,調(diào)用方式,函數(shù)調(diào)用語句,函數(shù)表達式,函數(shù)參數(shù),print_star(n);,void print_star(int n) int i; for(i=1; i=n; i+) printf(“*“); ,x=max(a, b)+5;,x=max(max(a, b), c);,程序舉例(4),分析一下程序,寫出運行結(jié)果。,#include main( ) int a=5, b=10; printf(“a=%d, b=%dn“, a, b); fun(a, b); /*函數(shù)調(diào)用*/ printf(“a=%d, b=%dn“, a, b); int fun(int x, int y)/*現(xiàn)代風格函數(shù)定義*/ x=3; y=3; return; ,a=5 , b=10 a=5 , b=10,參數(shù)傳遞,主調(diào)函數(shù)向被調(diào)函數(shù)傳值的方式:,賦值調(diào)用 把實參的值賦給形參。 賦地址調(diào)用 把實參的地址付給形參。在被調(diào)函數(shù) 中,用該地址訪問主調(diào)函數(shù)中的實參。,實參,形參,調(diào)用,返回,單向值傳遞,Argument passing by value簡單變量作函數(shù)參數(shù),傳遞方式,屬于賦值調(diào)用,將實參值傳給虛參。,虛參要求,必須是簡單變量。,實參要求,可為一般變量、常量、數(shù)組元素或者 表達式。,啞實結(jié)合,啞元和實元按順序一一結(jié)合。由于是 賦值調(diào)用,修改啞元,對實元無影響,Pi function example,下面函數(shù)pi的功能是:根據(jù)以下公式, 返回滿足精度(0.0005)要求的的值,請 填空。,程序舉例52,#include /*Direct MSDOS console input/output*/ #include #include double pi(double eps ) /*子函數(shù)的定義*/ double s, t; int n; for( ; teps; n+) s+=t; t=n*t/(2*n+1); return ( ); /*函數(shù)的返回值*/ main( ) /*主函數(shù)*/ double x,p; printf(“nPlease enter a precision: “); scanf(“ %lf “, ,s=0.,t=1.0,n=1,2.0*s,實參,形參,調(diào)用,return,p=pi(x),函數(shù)原型的說明,在一個函數(shù)中調(diào) 用另一個函數(shù)時, 應具備什么條件?,被調(diào)用的函數(shù)必須是已經(jīng)存在的函數(shù) (是庫函數(shù)或用戶自己定義的函數(shù))。,如果使用庫函數(shù),一般還應該在本文 件開頭用 #include 命令將調(diào)用有關(guān)庫函 數(shù)所需要用到的信息“包含”到本文件中 來。 #include 標準輸入輸出函數(shù) #include 標準數(shù)學計算函數(shù) ,如果使用用戶自己定義的函數(shù),而且 該函數(shù)與調(diào)用它的函數(shù) (即主調(diào)函數(shù)) 在 一個文件中時,應在主調(diào)函數(shù)的說明部 分或主調(diào)函數(shù)之前對被調(diào)函數(shù)作聲明。 函數(shù)聲明的一般形式: 類型 函數(shù)名(類型1,類型2,) ; 類型 函數(shù)名(類型1 參數(shù)名1,);,函數(shù)聲明的一般形式: 類型 函數(shù)名(類型1,類型2,) ; 類型 函數(shù)名(類型1 參數(shù)名1,); 舉例: float add(float a, float b); float add(float, float);,不同版本的編譯器,函數(shù)聲明方式略 有不同。,有些系統(tǒng)在函數(shù)調(diào)用前,不對函數(shù)作 聲明時,編譯系統(tǒng)會把第一次遇到的該 函數(shù)形式(函數(shù)定義和函數(shù)調(diào)用)作為函 數(shù)聲明,并將函數(shù)類型默認為int型。 因而,如果函數(shù)類型為int整形,可以在 函數(shù)調(diào)用前不必作函數(shù)聲明。,如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函 數(shù)之前,可以不必加以說明。 float add(float a, float b) return (ab?a: b); main( ) float a, b; scanf(“%f, %f“, ,如果在所有函數(shù)定義之前,在函數(shù) 的外部已作了函數(shù)聲明,則在各個主調(diào) 函數(shù)中不必對所調(diào)用的函數(shù)再作聲明。 float add(float a, float b); main( ) ,函數(shù)的“聲明”和“定義”的差別: 定義:指函數(shù)功能的確立,包括指定函 數(shù)名、函數(shù)類型、形參及類型、函數(shù) 體等,是一個完整、獨立的函數(shù)單位。 聲明:是對已定義函數(shù)的返回值和形參 進行類型說明。它不包括形參本身和函 數(shù)體。,prototype,宏定義,不帶參數(shù)的宏定義: 即第二章的符號常量,帶參數(shù)的宏定義:,帶參數(shù)的宏定義,功能,將一個帶參數(shù)的標識符定義成一個字符串。,格式,#define 宏名(參數(shù)表) 字符串,字符串中可包含參數(shù)表中的參數(shù)。,舉例,#define s(a, b) a*b area=s(3, 2);,處理,在編譯時,用字符串替代帶參數(shù)的宏名, 其中出現(xiàn)的參數(shù)由相應的實際參數(shù)替代。,帶參數(shù)宏定義的說明,書寫字符串時,應注意括號的使用。,如想計算(3+5)*(4+7),不能寫成 #define s(a, b) a*b s(3+5, 4+7) 3+5*4+7=30 而應是 #define s(a, b) (a)*(b),不能寫成 #define s(a, b) (a)*(b) 否則,在計算24/(3*4)時,使用 24/s(3,4)會出錯, 24/(3)*(4) 32 而應是 #define s(a, b) (a*b),為了適應各種情況,將 #define s(a, b) a*b 改寫成 #define s(a, b) (a)*(b),帶參數(shù)宏和函數(shù)的區(qū)別,帶參數(shù)宏與函數(shù)在使用上,同函數(shù)相同, 與其它語言的語句函數(shù)相似。,函數(shù)調(diào)用時,先求出實參表達式的值,然 后帶入函數(shù)定義中函數(shù)的形參;而用帶參宏 只是進行簡單的字符替換,不進行計算。,函數(shù)調(diào)用是在程序運行時處理的,分配臨 時的內(nèi)存單元;而宏擴展則是在編譯之前進 行的,在展開時并不分配內(nèi)存單元,也不進 行值的傳遞處理,也沒有“返回值”的概念 。,對函數(shù)中的實參和形參都要定義類型,且 二者的類型要求一致,如不一致應進行類型 轉(zhuǎn)換;而宏不存在類型問題,宏名無類型, 它的參數(shù)也無類型,只是一個符號代表。,函數(shù)只可得到一個返回值,而用宏可以設(shè) 法得到幾個結(jié)果。例如: #define PI 3.14159 #define CIRCLE(R,L,S) L=2*PI*R;S=PI*R*R CIRCLE(5,L,S);,多次使用宏時,宏展開后源程序變長,而 函數(shù)調(diào)用不使源程序變長。,宏替換不占運行時間,只占編譯處理時 間,而函數(shù)調(diào)用則占運行時間。,Scope and storage class變量的作用域和存儲類,varable scope 變量的作用域 variable storage class 變量的存儲類,定義:存儲類 類型 變量名; 描述變量的另外兩個屬性作用域與存儲類 當了解了函數(shù)調(diào)用時發(fā)生程序執(zhí)行權(quán)的轉(zhuǎn)移,就很容易理解。,變量的使用過程:定義、聲明、使用;,31,Scope of Variables,Scope The part of the program where the variable can be referenced. The scope of a variable starts from its declaration and continues to the end of the block that contains the variable. 從變量的定義或者生命開始,到程序塊結(jié)束block:函數(shù),復合語句等。,scope變量的作用域,程序中定義變量的位置及其能被讀寫訪問的范圍,它是從空間角度來描述變量。,Local 局部變量 Global 全局變量,定義,變量的作用域的分類,局部變量 local,定義,所謂local, global,相對于一個 function 而言。在一個函數(shù)(包括主函數(shù)main)內(nèi)部定義的變量是local ,它只在本函數(shù)內(nèi)有效,在此函數(shù)以外是不能使用這些變量。 The scope of a variable starts from its declaration and continues to the end of the block that contains the variable.,局部變量說明,不同函數(shù)中可以使用相同名字的變量,它 們代表不同的對象,互不干擾。 Float fun(int a) /*函數(shù)fun*/ int b, c; main( ) /*主函數(shù)main*/ int b, c; ,形式參數(shù)也是局部變量。 Float fun(int a) /*函數(shù)fun*/ int b, c; 形參a的作用域只在fun中 main( ) /*主函數(shù)main*/ int b, c; ,global全局變量,定義,在所有函數(shù)之外定義的變量稱為全局變量,外部變量即全局變量。全局變量可以為本文件中所有其他函數(shù)所共有。它的有效范圍為從定義變量的位置開始到本源文件結(jié)束。,實際上,local與global管理方式分別屬于動態(tài)管理和靜態(tài)管理。它們在內(nèi)存的存儲區(qū)不同。動態(tài)管理,復合自然規(guī)律(jobs講稿)。,C程序的內(nèi)存映像,C程序中變量的內(nèi)存分配方式 從靜態(tài)存儲區(qū)分配 全局變量和靜態(tài)變量 在棧上創(chuàng)建 存放函數(shù)參數(shù)值、局部變量值等 在執(zhí)行函數(shù)調(diào)用時,系統(tǒng)在棧上為函數(shù)內(nèi)的局部變量及形參分配內(nèi)存,函數(shù)執(zhí)行結(jié)束時,自動釋放這些內(nèi)存 從堆上分配 在程序運行期間,用動態(tài)內(nèi)存分配函數(shù)來申請的內(nèi)存都是從堆上分配的,動態(tài)內(nèi)存的生存期由程序員自己來決定,37,Global Variables,Declared outside all functions and are accessible to all functions in its scope. Local variables do not have default values, but global variables are defaulted to zero.,Global variable,int p=1, q=5; float f1(int a) int b, c; char c1, c2; char f2(int x, int y) int i, j; main( ) int m, n; ,/*外部變量*/,/*定義函數(shù)f1*/,/*外部變量*/,/*定義函數(shù)f2*/,/*主函數(shù)*/,c1, c2 作 用 范 圍,p, q 作 用 范 圍,如果一個C程序只有一個源文件, 則外部變量的作用域為從定義變量的 位置開始到本源文件結(jié)束。,若要在定義點之前的函數(shù)內(nèi)引用它 時,則應在該函數(shù)中用extern對該變 量作外部變量說明。,extern 類型 變量名; (與函數(shù)聲明類似),外部變量說明可進行多次不分配內(nèi) 存單元;但定義只能有一次,定義時 分配存儲單元。,若一個程序由多個源文件組成,跨 文件引用外部變量也要做外部變量說 明。,在同一源文件中,外部變量與局部 變量同名,則在局部變量的作用范 圍內(nèi)外部變量不起作用。,全局變量增加了函數(shù)間數(shù)據(jù)聯(lián)系的 渠道。在函數(shù)間可完成數(shù)據(jù)的傳遞。,慎用全局變量,全局變量在程序的全部執(zhí)行過程中始 終占用存儲單元,而不是僅在需要時才 開辟存儲單元。即不利于節(jié)約內(nèi)存資源。,函數(shù)在執(zhí)行時要依賴于其所在的外部 變量,因而它使函數(shù)的通用性降低。 當移植該函數(shù)時,必須連同外部變量 及其值一起移過去。但移過去又有可能 與其他變量名同名。即降低了通用性或 可移植性(portability)。,使用全局變量太多,會降低程序的可 讀性。 在程序執(zhí)行時,人們很難清晰地判斷 每一時刻各外部變量的值。因為每個函 數(shù)都可改變?nèi)肿兞康闹?。即增加了調(diào) 試的困難。,程序舉例20,給出下列程序的運行結(jié)果。,#include main( ) extern int a, b; printf(“Max=%dn“, max(a, b); int a=13, b=8; max(int x, int y) int z; z=xy?x: y; return(z); ,Max=13,int a=13, b=8; /全局變量 main( ) int a=5; /局部變量 printf(“Max=%dn“, max(a, b); max(int a, int b) int c; c=ab?a: b; return(c); ,Max=8,程序舉例21,#include int k=1; main( ) int i=4; fun(i); printf(“(1) %d,%dn“, i, k); fun(int m) m+=k; k+=m; char k=B; printf(“(2) %dn“, k-A); printf(“(3) %d,%dn“, m, k); ,程序的運行結(jié)果是:,(2) 1 (3) 5, 6 (1) 4, 6,/*全局變量k=1*/,/*局部變量*/,/*形參m=4*/,/*m=m+k(5),k=k+m(6)全局變量k*/,/*復合語句的局部變量k*/,/*實參i=4*/,程序舉例22,int i=0; main( ) int i=5; reset(i/2); printf(“i=%dn“, i); reset(i=i/2); printf(“i=%dn“, i); reset(i/2); printf(“i=%dn“, i); workover(i/2); printf(“i=%dn“, i); workover(int i) i=(i%i)*(i*i)/(2*i)+4); printf(“i=%dn“, i); return(i); reset(int i) i=i=2?5: 0; return(i); ,運行結(jié)果是:,i=5 i=2 i=2 i=0 i=2,Storage class,變量的存儲類是從變量的存在時間或數(shù)據(jù)在內(nèi)存中的存儲方式,即變量的存儲類別。,描述,存儲方式,具體類型,auto自動變量 extern外部變量 static靜態(tài)變量 register寄存器變量,定義:存儲類 類型 變量名;,定義、聲明、使用;,自動變量auto,在函數(shù)中,沒有用static說明的形參和變量都屬此類型,屬于系統(tǒng)默認類別。,描述,在調(diào)用函數(shù)時系統(tǒng)會給該類型變量自動分配存儲空間,在函數(shù)調(diào)用結(jié)束時就自動釋放這些空間。這類局部變量稱為自動變量。,定義,auto 類型 變量序列,變量聲明,聲明時,auto可省略,省略時,默認auto型。,自動變量是局部變量,作用域同于局部變量。,自動變量是動態(tài)存儲類型的變量。,可在定義時初始化,若未進行初始 化,也沒賦值,其值將是不確定的。,自動變量舉例,int f(int a) auto int b,c=3; ,舉例,/*定義函數(shù)f,a為形參*/,/*定義b, c為自動變量*/,auto int b,c=3; int b,c=3;,自動類型是默認類型,等價,寄存器變量register,該類型變量的存儲空間不是內(nèi)存,而 是cpu中的寄存器,因而稱為寄存器變量。,定義,為了提高訪問速度,將經(jīng)常使用的變量定義在 cpu中的寄存器,提高系統(tǒng)效率。,原因,register 類型名 變量名;,定義格式,寄存器變量說明,只有局部自動變量和形參可以作為寄 存器變量,其他 ( 如全局變量、局部靜 態(tài)變量)不行。并且寄存器變量一般只 限于整形、字符型和指向整形、字符型 的指針。 register static int a, b, c; register float x, y;,一個計算機系統(tǒng)中的寄存器數(shù)目是有 限的,不能定義任意多個寄存器變量。 不同的系統(tǒng)允許使用的寄存器不同。 例如: Turbo C只把源變址寄存器SI和 目的變址寄存器DI用于寄存器變量, 多余的按自動變量處理。,3.由于寄存器不參加內(nèi)存編址,因而對 寄存器變量不能使用&運算符。 4.寄存器變量特別適用于要求快速和頻 繁使用的場合,例如:循環(huán)控制變量、 數(shù)組的下標、動態(tài)數(shù)據(jù)結(jié)構(gòu)中用于查詢 的指針等。,寄存器變量舉例,int fac (int n) register int i, f=1; for(i=1; i=n; i+) f=f*i; return(f); main( ) int i; for(i=1; i=5; i+) printf(“%d!=%dn“, i, fac(i); ,循環(huán)的次數(shù)越多, 越節(jié)省訪問時間。,外部變量,在所有函數(shù)之外定義而沒有指定其存 儲類別的變量稱為外部變量,即全局變 量。其作用域符合全局變量的規(guī)定,連 接在一起的各目標文件的源程序文件中 的所有函數(shù)均可以訪問外部變量。,外部變量是靜態(tài)存儲類型的變量,在 程序運行期間分配固定的存儲空間,因 此其生存期是整個程序的運行期,就是 說它的值不隨函數(shù)的退出調(diào)用而消失。,外部變量可在定義時作初始化;沒有 顯式初始化的外部變量,由編譯程序自 動初始化為零值。,外部變量的聲明,*在一個文件內(nèi)聲明外部變量 *在多個文件中聲明外部變量,在一個文件內(nèi)聲明外部變量,如果外部變量不在文件的開頭定義, 其有效的作用域只限于定義處到文件終結(jié) 處。如果在定義點之前的函數(shù)想引用該外 部變量,則應該在引用前用關(guān)鍵字extern 對該變量作“外部變量聲明”。表明該變量 是一個已經(jīng)定義的外部變量。,int max(int x, int y) int z; z=xy? x: y; return(z); main( ) extern A, B; printf(“%dn“, max(A, B); int A=13, B=-8;,變量定義、變量聲明、變量引用,/*外部變量定義*/,/*外部變量聲明*/,/*外部變量的引用*/,在多個文件內(nèi)聲明外部變量,如果一個C程序是由一個或多個源程 序文件組成,如果在兩個程序中都用到同 一個外部變量num時,不能分別在兩個文 件中各自定義一個外部變量num,否則編 譯出錯。正確的作用:在任意一個文件中 定義外部變量num,而在另一個文件中用 extern對num作“外部變量聲明”。,/*project工程文件包含func4.c和fun4.h兩個文件*/ main() extern num; /*變量聲明*/ int i; num=800; i=j;/*變量引用*/ printf(“%d“,num); getch(); ,/*func4.h*/ int num;/*變量定義*/,#include main() int i; num=800; i=j;/*變量引用*/ printf(“%d“,num); getch(); ,靜態(tài)變量,靜態(tài)變量是靜態(tài)存儲類型的變量,即在程序運行期間分配固定的存儲單元,它永久存在,不隨函數(shù)的退出調(diào)用而釋放。,定義,靜態(tài)局部變量,分類,static 類型 變量名;,語句格式,55,Static Local Variables,Static local variables are permanently allocated in the memory for the lifetime of the program. static int x; After a function completes its execution, all its local variables are destroyed. While, the static local variables are retained and can be reused in the next call. 靜態(tài)局部變量,其值不隨函數(shù)退出而釋放,繼續(xù)保存。因此,下次調(diào)用的初值是上次調(diào)用的終值。,在函數(shù)內(nèi)部定義的靜態(tài)變量是靜態(tài)局 部變量。,定義,說明,對局部變量用static聲明,則為該 變量分配的存儲空間在整個程序執(zhí)行 期間始終存在。,靜態(tài)局部變量是在某函數(shù)中的局部 變量,其他函數(shù)無權(quán)訪問。當退出對 該函數(shù)調(diào)用時,其值保留,下次調(diào)用的初值是上次調(diào)用退出的終值。,靜態(tài)局部變量可在定義時初始化, 未顯式初始化的靜態(tài)局部變量在編譯 時自動初始化為零值。,靜態(tài)局部變量可使變量由動態(tài)存儲 方式改變成靜態(tài)存儲方式。它作用域 不變,局限于本函數(shù)。,Static Local Variables,Example 23,給出以下程序的運行結(jié)果。,main( ) increment( ); increment( ); increment( ); increment( ) int x=0; x+=1; printf(“%dn“, x); ,1 1 1,main( ) increment( ); increment( ); increment( ); increment( ) static int x=0; x+=1; printf(“%dn“, x); ,1 2 3,main( ) int x=1; increment( ); printf(“%dn”,x); increment( ); printf(“%dn”,x); increment( ); printf(“%dn”,x); ,increment( ) static int x=0; x+=1; printf(“%dn“, x); ,1 1 2 1 3 1,程序舉例24,給出以下程序的運行結(jié)果。,int n=1; func(); main( ) static int x=5; int y; y=n; printf(“MAIN: x=%2d y=%2d n=%2dn“, x, y, n); func( ); printf(“MAIN: x=%2d y=%2d n=%2dn“, x, y, n); func( ); func( ) static int x=4; int y=10; x=x+2; n=n+10; y=y+n; printf(“FUNC: x=%2d y=%2d n=%2dn“, x, y, n); ,MAIN: x= 5 y= 1 n= 1 FUNC: x= 6 y=21 n=11 MAIN: x= 5 y= 1 n=11 FUNC: x= 8 y=31 n=21,/*x 靜態(tài)局部變量*/,/*函數(shù)聲明*/,/*函數(shù)定義*/,/*函數(shù)調(diào)用*/,/*全局變量 n */,/* x 靜態(tài)局部變量,初值=5;y局部變量*/,/*y=1 5 1 1 */,本章目錄,函數(shù) 宏定義 變量的作用域和存儲類 模塊化程序設(shè)計方法 4.1.模塊化程序設(shè)計方法的指導思想 4.2.模塊分解的原則 應用設(shè)計實例 多文件方式組織的程序,模塊化程序設(shè)計方法的指導思想,什么是模塊化程序設(shè)計方法,在編寫較大規(guī)模的程序,為了提高編寫工作 的效率,可把程序總體上劃分成幾個功能相對 獨立的程序模塊,分別由不同的編程人員進行 編寫。各模塊之間用接口聯(lián)系。這樣,只要接 口關(guān)系不變,每個模塊內(nèi)部的具體實現(xiàn)細節(jié)可 以由各自的編程人員隨意修改。這就是模塊化 程序設(shè)計方法的指導思想。,無論多么復雜的任務(wù),都可以劃分為若干個 子任務(wù)。把每個子任務(wù)設(shè)計成一個子函數(shù),若 子任務(wù)較復雜,還可以將子任務(wù)繼續(xù)分解,直 到分解成為一些容易解決的子任務(wù)為止。每個 子任務(wù)對應一個子函數(shù),完成總?cè)蝿?wù)的程序由 一個主函數(shù)和若干子函數(shù)組成,主函數(shù)起著任 務(wù)調(diào)度的總控作用。,模塊分解的原則,分解原則,1.使模塊脫離其使用環(huán)境,應該保證 是正確的。,2.每個模塊只完成一個相對獨立的特 定功能,模塊之間僅僅交換那些為完 成系統(tǒng)功能必須交換的信息,即模塊 具有獨立性。,3.模塊應該設(shè)計得使其所含信息(過 程和數(shù)據(jù))對于那些不需要這些信息 的模塊不可訪問,即信息隱藏性。,結(jié)構(gòu)圖,主模塊,A,B,C,E,F,逐步求精與模塊化設(shè)計的聯(lián)系,1.在規(guī)模比較大的程序進行逐步求精時,為了提高 清晰度,常常采用分段結(jié)構(gòu)的形式。在C語言中采用 函數(shù)表示一些功能比較獨立的部分,而在PASCAL語 言中用過程(procedure)表示,從而使大的程序分 解為若干功能獨立的小的程序段,這種形式蘊含著 模塊化設(shè)計思想。 2.而對于每個模塊來說,又可以采用逐步求精方法 進行設(shè)計。,逐步求精與模塊化設(shè)計的區(qū)別,1.就程序規(guī)模來說,逐步求精主要是指一個程序的 設(shè)計過程,而模塊化設(shè)計主要指一個比較大的系統(tǒng) 的設(shè)計過程。 2.就程序設(shè)計的兩種方法(分解與抽象)來說,逐 步求精方法側(cè)重于分解,而模塊設(shè)計側(cè)重于抽象。 模塊化方法的外表是將系統(tǒng)化分成若干子系統(tǒng),而 實質(zhì)是要實現(xiàn)不同層次的數(shù)據(jù)或過程的抽象。,應用設(shè)計實例,請大家關(guān)注cms網(wǎng)站: 1、本周補實驗,:同學們時間? 答疑時間:? 2、請同學們申報ACM競賽情況; 3、補充練習題:三大結(jié)構(gòu),函數(shù),數(shù)組。 打印楊輝三角形 求素數(shù)之和,程序舉例1楊輝三角形,1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 ,問題分析1,主函數(shù)main(): 調(diào)用輸入三角形輸出行數(shù)n的函數(shù)input(); for i=0 to n 調(diào)用print_space(k)輸出k個空格 調(diào)用輸出楊輝三角形的第i行函數(shù)print(); ,輸入函數(shù)input() 輸入三角形輸出行數(shù)n,問題分析2,輸出三角形第i行函數(shù)print() for j=0 to i 調(diào)用print_j(i,j)輸出第i行第j個元素; 輸出回車換行,輸出k個空格print_space(k) for l=1 to k printf(“ “);,問題分析3,輸出第j個元素print_j() 輸出 i!/(j!*(i-j)!),求m!函數(shù)func(m) fun=1 for l=1 to m fun=fun*l;,C程序1,#include void print_space(int); void print_j(int, int); int input( ); main() int i, j, n; n=input( ); for(i=0; in; i+) print_space(36-i*3); for(j=0; j=i; j+) print_j(i, j); printf(n ); ,C程序2,int input( ) int n; printf(請輸入輸出的行數(shù):); scanf(%d , ,C程序3,long func(int n) int i; long m; for(m=i=1; i=n; i+) m*=i; return(m); void print_j(int n, int m) long cij; cij=func(n)/(func(m)*func(n-m); printf(%6ld , cij); ,程序舉例2求素數(shù)之和,求1n之間所有素數(shù)之和。,問題分析1,輸入n的值(輸入函數(shù)input( ); 1到n間的所有素數(shù)求和; 輸出求和的值。,細化2: i從1變化到n; 判斷i 是否為素數(shù); 若i為素數(shù)則進行累加求和。,問題分析2,C程序1,#include long sumofprime( ); int isprime( ); int input( ); void output( ); main( ) int n; long m; printf(“input n:“); n=input( ); m=sumofprime(n); output(m); ,C程序2,input( ) /* 輸入模塊 */ int n; scanf(“%d“, ,C程序3,int isprime(int m) /* 判斷素數(shù)模塊 */ int i; if(m=1) return 0; for (i=2; i=sqrt(m);i+) if (m%i=0) return 0; return 1; void output( long int n) printf(“sum=%ldn“,n); ,本章目錄,函數(shù) *宏定義 變量的作用域和存儲類 *模塊化程序設(shè)計方法 *應用設(shè)計實例 多文件方式組織的程序 1.文件包含 2. Turbo C集成開發(fā)環(huán)境下的項目文件,文件包含,指一個源文件可以將另一個源文件的全部 內(nèi)容包含進來,即將另外的文件包含到本 文件中。,功能,格式,#include 或 #include “文件名“,功能,用雙引號的,系統(tǒng)先在引用被包含文件的源文件所 在的文件目錄中尋找要包含的文件,若找不到,再 按系統(tǒng)指定的標準方式檢索其他目錄。,用尖括號時不檢查引用被包含文件的源文件所在的 文件目錄,直接按系統(tǒng)指定的標準方式檢索文件目 錄。,include示意過程,1,文件包含的注明,1.在被包含文件修改后,凡包含此文件的所 有文件都要重新編譯。 2.一個include命令只能指定一個被包含文件, 如果包含n個文件,要用n個include命令。 3.在一個被包含文件中還可以包含另一個被包 含文件,即文件包含是可以嵌套的。,Turbo C集成開發(fā)環(huán)境下的項目文件,定義,在Turbo C集成開發(fā)環(huán)境中,把多文件組成 的程序叫做project (項目),一個項目就 是一個擴展名為.prj 的文件。,說明,把項目文件進行編譯,連接,運行會產(chǎn)生與 項目文件同名的.exe文件(可執(zhí)行文件)。,建立項目程序的步驟,在Turbo C集成開發(fā)環(huán)境中,分別設(shè)計好組成項目 程序的各文件a.c,b.c,c.c。 設(shè)計一個叫myproject的項目文件。用文本編輯口把 所有的文件列出,一行一個文件名,該程序由三個文件 a.c,b.c和c.c組成。保存這個文件為myproject.prj。 在集成開發(fā)環(huán)境下,選擇Project

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論