C語言函數課件_第1頁
C語言函數課件_第2頁
C語言函數課件_第3頁
C語言函數課件_第4頁
C語言函數課件_第5頁
已閱讀5頁,還剩81頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第7章函數教學目標掌握自定義函數的一般結構及函數的定義方法;掌握函數聲明、函數調用的一般方法;掌握形參、實參、函數原型等重要概念;熟悉數組作函數的參數時函數的定義和調用方法;熟悉函數嵌套、函數遞歸的概念;能定義和使用嵌套函數、遞歸函數;了解局部變量、全局變量和變量的存儲類型的概念;熟悉auto型和static型局部變量的特點和用法。

Page1

第7章函數知識點函數的定義與調用;函數調用時的數據傳遞方法;數組作為函數參數;函數的嵌套調用和遞歸調用;局部變量與全局變量的作用域;動態存儲變量和靜態存儲變量的生存期。重點:函數的定義與調用;函數調用時的數據傳遞方法。難點:函數調用時的數據傳遞方法;遞歸函數的設計;變量的作用域和生存期。

Page2

7.1函數概述函數是構成C程序的基本構件。C語言的程序是由一個主函數或若干個函數組成的。但編譯單位是源程序文件,而不是函數。C程序執行是從main函數(主函數)開始,在main函數中結束,不管main函數的位置如何。所有的函數獨立定義,main()函數可以調用任意其它函數,其它函數之間可以相互調用,但任何函數都不能調用main()函數。

Page3

函數的分類標準函數(庫函數):由系統提供,如printf()自定義函數:由用戶自己定義,解決特定的問題有參函數:主調函數與被調函數之間有參數傳遞如printf()無參函數:主調函數與被調函數之間無參數傳遞如getchar()有返回值函數:被調函數返回一個值給主調函數如getchar()無返回值函數:被調函數不帶回值給主調函數如printf()

Page4

7.2函數定義與函數調用函數定義:

函數調用:

函數定義時函數名后的括號中的變量叫形式參數,簡稱形參

兩個實際參數函數調用時函數名后的括號中的參數叫實際參數,簡稱實參

函數值兩個形式參數

Page5

一、函數定義與函數調用函數定義的格式:

[函數類型]函數名([形參及形參聲明表列]){內部變量定義和聲明部分執行語句

}函數定義后,并不被執行,只有當調用函數時,程序才轉到函數去執行。函數調用的格式:函數名([實參表列])

Page6

1.無參無返回值函數的定義與調用#include<stdio.h>voidpstar(){ printf("****************\n");}voidmain(){inti;for(i=1;i<=10;i++)pstar();}函數類型void(“空類型”)表示無返回值

函數名無參數函數定義以語句方式調用無返回值函數函數定義

Page7

2.有參無返回值函數的定義與調用#include<stdio.h>voidpstar(intn){intk;/*形參在函數體內不能再定義*/for(k=1;k<=n;k++)printf("*");printf("\n");}voidmain(){inti;for(i=1;i<=10;i++)pstar(20);

}形參k

被聲明為int型

函數定義實參20

Page8

3.有返回值函數的定義與調用#include<stdio.h>intmax(intx,inty){intz;z=x>y?x:y;return(z);}voidmain(){inta,b,c;scanf("%d%d",&a,&b);c=max(a,b);/*將函數的返回值賦給變量c*/

printf("Maxis%d\n",c);

}int型函數(int

可缺省),表示函數返回值為整型

函數定義return后的括號可以不要

注意:程序可直接寫為:return(x>y?x:y);

Page9

有返回值函數的定義與調用上題程序可修改為:#include<stdio.h>intmax(intx,inty){return(x>y?x:y);}voidmain(){inta,b,c;scanf("%d%d",&a,&b);

printf(“Maxis%d\n”,max(a,b));

}將max函數的返回值作為printf函數的參數函數定義

Page10

二、函數的參數一、形式參數與實際參數對無參函數,形參表列與實參表列均為空,但括號不能省略,如fun()。對有參函數,實參與形參應個數相等,順序對應,類型一致或賦值相容。定義函數時形參不占用存儲單元,只有在調用函數期間才給形參分配存儲單元,并將實參的值傳遞給形參。函數調用結束,形參所占用存儲單元也被釋放。

Page11

函數的參數若形參是變量名,實參可以是常量、變量或表達式,如函數調用max(3,a+b);若形參是數組名,實參是數組名,或者數組指針。注:實參對形參的數據傳遞是“單向值傳遞”:實參的值傳遞給形參,而形參的值不會傳回給實參。

Page12

三、函數的返回值函數返回值的獲得:由return語句獲得。函數返回值的類型:取決于函數的類型。例:

floatmax(intx,inty){return(x>y?x:y);}

問:函數返回值是int還是float型?答:float將無返回值的函數類型定義為void。

Page13

四、函數的調用方式函數調用的格式:函數名([實參表列])函數調用的三種方式:函數語句:把函數調用作為一個語句,這種調用方式不使用函數的返回值,是無返回值函數的調用方式。

如,pstar(20);

Page14

函數的調用方式函數表達式:把函數調用作為表達式的一部分,這種調用方式使用函數返回的函數值,是有返回值函數的調用方式。

如,c=max(a,b);函數參數:把函數調用作為一個實參進行函數調用,這種調用方式也要使用函數的返回函數值,也是有返回值函數的調用方式。

如,printf("Maxis%d\n",max(a,b));

Page15

舉例判斷素數函數1

(無返回值函數)#include<stdio.h>#include<math.h>voidprime(intm){intj,k;k=sqrt(m);for(j=2;j<=k;j++)if(m%j==0)break;if(j>k)printf("%disaprimenumber\n",m);elseprintf("%disnotaprimenumber\n",m);}main(){intn;scanf("%d",&n);prime(n)}為了明確表示無返回值用void定義函數類型

Page16

舉例判斷素數函數2

(有返回值函數)#include<stdio.h>#include<math.h>prime(intm){intj,k,f;k=sqrt(m);for(j=2;j<=k;j++)if(m%j==0)break;if(j>k)f=1;/*返回1表示m是素數*/elsef=0;/*返回0表示m不是素數*/return(f);}voidmain(){intn;scanf("%d",&n);if(prime(n)==1)printf(“%disaprimenumber\n",n);elseprintf("%disnotaprimenumber\n",n);}prime(n)

Page17

五、函數調用的條件1、被調函數是庫函數或已經存在的自定義函數;2、若被調函數是庫函數,一般需在文件開頭將其頭文件#include到本文件;

3、若被調函數是自定義函數,一般應在調用前進行函數原型聲明,聲明的格式是:函數類型函數名(形參類型表列);或者:函數類型函數名(形參名及其類型表列);舉例:intmax(int,int);

或:intmax(intx,inty);

一個例外:若被調函數定義在前、調用在后,則可不加函數原型聲明。

Page18

函數原型聲明方式1、在主調函數內部聲明;2、在函數的外部聲明,一般放在所有函數定義之前,即文件開頭。

Page19

函數原型聲明舉例#include<stdio.h>voidmain(){inta,b;floatz;

scanf("%d%d",&a,&b);z=average(a,b);printf("a=%d,b=%d,c=%.2f\n",a,b,z);}floataverage(a,b)inta,b;{floatc;c=(a+b)/2.0;return(c);}函數調用在前

在主調函數內部聲明floataverage(int,int);函數定義在后

Page20

函數原型聲明舉例#include<stdio.h>

voidmain(){inta,b;floatz;scanf("%d%d",&a,&b);z=average(a,b);printf("a=%d,b=%d,c=%.2f\n",a,b,z);}floataverage(a,b)inta,b;{floatc;c=(a+b)/2.0;return(c);}函數調用在前

文件開頭,外部聲明floataverage(int,int);函數定義在后

Page21

函數原型聲明舉例#include<stdio.h>

floataverage(a,b)inta,b;{floatc;c=(a+b)/2.0;return(c);}voidmain(){inta,b;floatz;scanf("%d%d",&a,&b);z=average(a,b);printf("a=%d,b=%d,c=%.2f\n",a,b,z);}函數定義在前函數定義在前,函數調用在后;無需聲明函數調用在后

Page22

7.3函數調用中的參數傳遞簡單變量作為函數參數指針變量作為函數參數數組作為函數參數

Page23

1、簡單變量作為函數參數若形參是變量名,實參可以是常量、變量或表達式。實參對形參變量的傳遞是“單向數值傳遞”:實參的值傳遞給形參,而形參的值不會傳回給實參。改變形參的值不會使實參的值發生變化實參形參值

Page24

舉例對兩個數按降序排列(1)例:以下程序能實現a和b兩個變量的交換嗎?voidswap(intx,inty){intt;t=x;x=y;y=t;}#include<stdio.h>voidmain(){inta,b;scanf(”%d,%d”,&a,&b);if(a<b)swap(a,b);printf(”%d,%d\n”,a,b);}這樣的程序無法實現a和b兩個變量的交換!

35abxyt35353

Page25

2、指針變量作為函數參數指針作為函數參數:

形參指針也指向實參指針所指的單元,于是改變形參指針所指單元的值,也就是改變實參指針所指單元的值。指針類型實參指針類型形參地址值

Page26

舉例對兩個數按降序排列(2)swap(int*p1,int*p2){intt;t=*p1;*p1=*p2;*p2=t;}#include<stdio.h>voidmain(){inta,b;int*pointer1,*pointer2;scanf(”%d,%d”,&a,&b);pointer1=&a;pointer2=&b;if(a<b)swap(pointer1,pointer2);printf(”%d,%d\n”,a,b);}若改變的是形參指針的值而不是形參指針所指單元的值,還能實現a和b兩個變量的交換嗎?

35……abp1p2t2000pointer1pointer220002002200220002002533

Page27

舉例對兩個數按降序排列(3)swap(int*p1,int*p2){int*t;t=p1;p1=p2;p2=t;}#include<stdio.h>voidmain(){inta,b;int*pointer1,*pointer2;scanf(”%d,%d”,&a,&b);

pointer1=&a;pointer2=&b;

if(a<b)swap(pointer1,pointer2);printf(”%d,%d\n”,a,b);}改變形參指針的值無法實現a和b兩個變量的交換!

35……abp1p2t2000pointer1pointer220002002200220002002200220002000

Page28

普通變量的指針作函數參數小結欲通過函數調用得到n個要改變的值,主調函數:設置n個普通變量(a1,a2,……)存放n個要改變的值,并用n個指針變量(pa1,pa2,……)指向它們;被調函數:設置n個指針變量(p1,p2,……)作為形參,函數體改變*p1,*p2,……的值;函數調用:主調函數以pa1,pa2,……為實參,將a1,a2,……的地址傳給形參p1,p2,……,于是,被調函數改變*p1,*p2,……的值實際上就是改變a1,a2,……的值。因此,函數調用結束,主調函數得到改變了的值。

Page29

3、數組作為函數參數

數組元素作為函數參數數組名作為函數參數

Page30

數組元素作為函數參數

例7.15:對應元素比較,如果數組a中的元素比數組b中元素大的次數多,則數組a大于數組b,反之數組b大于數組a,如果兩數組元素大于對方的元素次數相等,則兩數組相等。通過調用large函數實現:

large(intx,inty){intflag;if(x>y)flag=1;elseif(x==y)flag=0;elseflag=-1;return(flag);}

Page31

舉例判斷兩個數值型數組的大小#include<stdio.h>voidmain(){inta[10],b[10],i,n=0,k=0;for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=0;i<10;i++)scanf("%d",&b[i]);for(i=0;i<10;i++)

if(large(a[i],b[i])==1)n++;

elseif(large(a[i],b[i])==-1)k++;if(n>k)printf("aislargerthanb\n");

elseif(n<k)printf("bislargerthana\n");

elseprintf("aisequaltob\n");}數組元素a[i]、b[i]作實參

Page32

一維數組名作為函數參數形參接收實參傳遞的數組首地址,實際上,C編譯是將形參數組名作為指針變量來處理的。參數傳遞:地址值實參數組指針形參數組名或指針變量效果:函數調用期間,形參數組就是實參數組。一維數組名

一維數組名

一維數組指針一維數組指針變量實參

形參

Page33

一維數組名作參數使用說明實參數組與形參數組類型要一致。實參數組和形參數組大小可以不一致,也可以不指定形參數組第一維的大小,因為C編譯對形參數組第一維大小不做檢查,函數調用時不是把實參數組的值傳遞給形參數組,而是把實參數組的首地址傳遞給形參數組,于是形參數組結合到實參數組所占用的存儲空間。為方便編程,通常另設一參數用于傳遞數組元素的個數。

Page34

例7.17編寫函數統計一個一維數組(10個元素)中非0元素的個數。#include<stdio.h>intsolve(intb[10])/*一維數組名b作形參*/{intsum=0,i;for(i=0;i<10;i++)if(b[i]!=0)sum++;return(sum);} voidmain(){inta[10],num,i;for(i=0;i<10;i++)scanf("%d",&a[i]);num=solve(a);/*一維數組名a作實參*/printf("num=%d\n",num);}

Page35

例7.17編寫函數統計一個一維數組(10個元素)中非0元素的個數。#include<stdio.h>intsolve(intb[],intn)/*一維數組名b作形參*/{intsum=0,i;for(i=0;i<n;i++)if(b[i]!=0)sum++;return(sum);} voidmain(){inta[10],num,i;for(i=0;i<10;i++)scanf("%d",&a[i]);num=solve(a,10);/*一維數組名a作實參*/printf("num=%d\n",num);}一維形參數組的大小通常不指定,另設一參數用于傳遞數組元素的個數。

Page36

例:編寫函數將數組中n個元素按相反順序存放(1)voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-i-1;t=x[i];x[i]=x[j];x[j]=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

inv(a,10);

printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}形參和實參均為一維數組

Page37

方法(2)形參為指針變量,實參為一維數組voidinv(int*x,intn)

{intt,*i,*j,m=(n-1)/2;for(i=x,j=x+n-1;i<=x+m;i++,j--){t=*i;*i=*j;*j=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

inv(a,10);

printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}

Page38

方法(3)形參,實參均為指針變量

voidinv(int*x,intn)

{intt,*i,*j,m=(n-1)/2;for(i=x,j=x+n-1;i<=x+m;i++,j--){t=*i;*i=*j;*j=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2},*p;printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

p=a;inv(p,10);printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}

Page39

方法(4)形參為一維數組,實參為指針變量voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-i-1;t=x[i];x[i]=x[j];x[j]=t;}}#include<stdio.h>voidmain(){inti,a[10]={3,7,9,11,0,6,7,5,4,2},*p;printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");

p=a;inv(p,10);printf("Thearrayhasbeeninverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);}

Page40

折半(二分)查找折半查找法只能對有序數列進行查找,方法如下:假設n個數按由小到大的順序存放在數組a中,兩個位置指針top、bot分別指向查找范圍的頂部、底部。取查找范圍的中間位置mid=(top+mid)/2,將待查找的數x與a(mid)進行比較,將按以下三種結果分別處理:(1)x=a(mid):已找到,退出查找;

Page41

折半(二分)查找(2)x<a[mid]:x只可能落在top和mid-1范圍之內,將查找范圍的底部改為bot=mid-1,頂部top不變;(3)x>a[mid]:x只可能落在mid+1和bot范圍之內,將查找范圍的頂部改為top=mid+1,底部bot不變。確定新的查找范圍后,重復以上比較,直到找到或者top>bot,退出循環。top>bot表明嘗試過所有可能的范圍,但沒找到。

Page42

折半(二分)查找

x=65的查找過程下標數組元素第一次第二次第三次010←top123235341456←mid565←top←top←mid673←bot785←mid8979102←bot←bot

Page43

折半(二分)查找(數組從小到大)核心部分算法:top=0;bottom=n-1;result=-1;while((top<=bottom)&&(result==-1)){mid=(top+bottom)/2;/*取中間元素*/

if(a[mid]==x)/*所查找的數據是否是中間元素*/ result=mid;/*找到的位置*/

elseif(a[mid]<x) top=mid+1;elsebottom=mid-1;}

Page44

折半查找函數的定義

(數組從大到小)intBinarySearch(inta[],intn,intkey)/*key表示要找的數*/{inttop,bottom,mid;if(key>a[0]||key<a[n-1])return-1;/*返回-1表示沒找到*/else{top=0;bottom=n-1;while(top<=bottom){mid=(top+bottom)/2; /*取中間元素*/if(a[mid]==key)/*所查找的數據是否是中間元素*/ returnmid; /*返回找到的位置*/elseif(a[mid]>key) top=mid+1;elsebottom=mid-1;}return-1;}/*返回-1表示沒找到*/}

Page45

例7.24編寫一個字符串復制函數。#include<stdio.h>voidstringcopy(chars[],char*t){inti=0;while(*t!='\0'){s[i]=*t;i++;t++;}s[i]='\0';}voidmain(){charstr1[]="IloveBeijing!";char*str2="IloveChina!";stringcopy(str1,str2);printf("str1=%s\nstr2=%s\n",str1,str2);}

Page46

例7.25改用兩個字符指針變量作stringcopy函數的形參#include<stdio.h>voidstringcopy(char*p,char*q){while((*p++=*q++)!='\0');*p='\0';}voidmain(){charstr1[]="IloveBeijing!";char*str2="IloveChina!";stringcopy(str1,str2);printf("str1=%s\nstr2=%s\n",str1,str2);}

Page47

例7.26編寫一個求字符串長度函數#include<stdio.h>#include<string.h>intstringlen(chars[]){inti=0,len=0;while(s[i]!='\0'){len++;i++;}returnlen;}voidmain(){char*str;printf("Pleaseinputastring:");gets(str);printf("\nThestringlenthis%4d\n",stringlenth(str));}

Page48

多維數組名作函數參數例如:

floatmax(intarray[3][10])形參多維數組的第一維大小可以不指定

floatmax(intarray[][10])正確但是形參多維數組的第二維及其它高維的大小不能省略

floatmax(intarray[3][])錯誤

floatmax(intarray[][])錯誤

Page49

舉例求二維數組最大值函數的定義與調用例7.23#include<stdio.h>max_value(inta[][4]){inti,j,max;max=a[0][0];for(i=0;i<3;i++)for(j=0;j<4;j++)if(a[i][j]>max)max=a[i][j];return(max);}voidmain(){inta[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}};printf("max=%d\n",max_value(a));}/*形參二維數組的第一維大小可以不指定*/

Page50

7.4函數的嵌套調用和遞歸調用從什么地方調用函數,就返回到什么地方...調用函數fun1...調用函數fun2main()函數fun2()函數fun1()函數①②⑤⑥⑦⑧⑨④③

Page51

函數的嵌套調用舉例—求cnm

voidmain(){intm,n,t;longc(int,int);scanf("%d%d",&m,&n);if(n>m){t=m;m=n;n=t;}printf("%ld\n",c(m,n));}longc(intm,intn){longf;longfac(int);f=fac(m)/(fac(n)*fac(m-n));return(f);}longfac(intt){inti;longs=1;for(i=1;i<=t;i++)s*=i;return(s);}在main函數中調用c函數在c函數中三次調用fac

函數

返回main函數返回c函數函數C:求cnm

函數fac:求t!

Page52

函數的遞歸調用inta(intn){intd,c;…d=a(c);

…}遞歸函數兩要素:1.遞歸調用

2.使遞歸結束的條件函數的遞歸調用:在定義一個函數的過程中又直接或間接地調用函數本身

Page53

函數的遞歸調用f函數調用f函數f2函數調用f1函數f1函數調用f2函數直接遞歸調用間接遞歸調用

Page54

遞歸函數舉例1—求階乘例7.31分析:1(n=0,1)fac(n)=n*fac(n-1)(n>1)floatfac(intn)/*求階乘函數*/{floatf;if(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}#include<stdio.h>voidmain(){intn;scanf("%d",&n);if(n<0)printf("n<0,dataerror!");elseprintf("%d!=%15.0f\n",n,fac(n));}遞歸調用遞歸結束條件

Page55

遞歸函數舉例1—年齡問題例7.32分析:age(n-1)+2(n>1)age(n)=10(n=1)#include<stdio.h>age(intn){intc;if(n==1)c=10;elsec=age(n-1)+2;return(c);}voidmain(){printf("%d\n",age(5));}遞歸調用遞歸結束條件遞歸調用遞歸調用遞歸結束條件遞歸調用遞歸結束條件遞歸結束條件遞歸調用遞歸結束條件

Page56

遞歸函數舉例3#include<stdio.h>voidtry(){charc;if((c=getchar())!=’#’){try();putchar(c);}}voidmain(){try();}輸入apple#后的結果是:

elppa

Page57

7.5函數的返回值為指針一個函數可以返回整型、字符型、實型函數值,也可以返回一個指針值,即將地址作為函數值返回到主調函數中。返回指針的函數的定義:類型名*函數名(參數表){

函數體語句組

}

Page58

例7.34編寫一函數,實現兩個字符串的連接,返回值為連接后字符串的首地址。#include<stdio.h>char*strcat(char*s1,char*s2)/*定義返回值是指針的函數*/{char*p=s1;while(*p!='\0')p++;while((*p++=*s2++)!='\0');*p='\0';returns1;}voidmain(){charstr1[30]="Ilearn",*str2="Clanguage.";char*s;s=strcat(str1,str2);/*strcat函數的返回值是指針*/printf("%s\n",s);}

Page59

例7.29編寫程序,使能從輸入的若干個字符串中找出最小的串,并將其輸出。#include<stdio.h>#include<string.h>intgetstring(charc[][81]){charlin[81],linnum=0;printf("Enterstringaspacestringtoend!\n");gets(lin);while(!strcmp(lin,"#")==0){strcpy(c[linnum],lin);linnum++;gets(lin);}returnlinnum;}/*返回字符串行數*/

Page60

接上頁char*findminstr(char(*s)[81],intnum)/*s是指向一維數組的指針*/{char*strq;inti;strq=s[0];for(i=1;i<num;i++)if(strcmp(s[i],strq)<0)/*尋找最小串*/ strq=s[i];returnstrq;}/*返回最小串的地址*/

Page61

接上頁voidmain(){charstr[50][81],*strp;intn,i;n=getstring(str);strp=findminstr(str,n);puts(strp);}

Page62

例7.29編寫程序,使能從輸入的若干個字符串中找出最小的串,并將其輸出。#include<stdio.h>#include<string.h>intgetstring(charc[][81]){charlin[81],linnum=0;printf("Enterstringaspacestringtoend!\n");gets(lin);while(!strcmp(lin,“#”)==0)/*輸入遇#號結束*/{strcpy(c[linnum],lin);linnum++;gets(lin);}returnlinnum;}/*返回字符串行數*/

Page63

接上頁char*findminstr(char(*s)[81],intnum)/*s是指向一維數組的指針*/{char*strq;inti;strq=s[0];for(i=1;i<num;i++)if(strcmp(s[i],strq)<0)/*尋找最小串*/ strq=s[i];returnstrq;}/*返回最小串的地址*/S[][81]

Page64

接上頁voidmain(){charstr[50][81],*strp;intn,i;n=getstring(str);strp=findminstr(str,n);puts(strp);}

Page65

7.6變量的作用域和存儲類別函數間數據傳遞的渠道:主調函數(普通變量參數)被調函數主調函數(函數返回值)被調函數主調函數(數組參數/指針變量參數)被調函數主調函數(全局變量)被調函數

Page66

局部變量#include<stdio.h>voidsub(int,int);voidmain(){inta=1,b=2;sub(a,b);printf("mainprogram%d%d\n",a,b);}voidsub(inta,intb){a=a+10;b=b+20;printf("subprogram%d%d\n",a,b);}程序結果:

subprogram1122mainprogram12

Page67

局部變量和全局變量變量按照其作用范圍分為局部變量和全局變量(外部變量)。

類別作用域

(有效范圍)局

量函數形參本函數在函數體首部定義的變量/數組本函數在復合語句首部定義的變量/數組本復合語句全局

變量在函數之外定義的變量/數組定義起至文件結束

Page68

局部變量和全局變量兩點說明:

①不同函數中的局部變量可以同名,全局變量與局部變量也可以同名,但它們代表不同的變量,在內存中占有不同的存儲空間。

②局部變量起作用時,同名全局變量不起作用。

Page69

局部變量和全局變量例7.41#include<stdio.h>inta=3,b=5;max(inta,intb){intc;c=a>b?a:b;return(c);}voidmain()

{inta=8;

printf("%d\n",max(a,b));}max()的局部變量a、bmax()的局部變量c實參a是main()的局部變量(8),實參b是全局變量(5)程序運行結果:8

使用max()的局部變量a、b

main()的局部變量a

全局變量a、b

Page70

全局變量intP1=1,P2=2;floatf1(inta){……}charc1,c2;floatf2(intb){……}voidmain(){……}全局變量P1,P2作用范圍全局變量c1,c2作用范圍一個不成文的約定:全局變量名的第一個字母大寫。

Page71

全局變量應用舉例例7.40有一個一維數組,內放10個學生的成績,寫一個函數,求出平均分、最高分和最低分。#include<stdio.h>floatMax,Min;floataverage(floatarray[],intn){inti;floataver,sum=array[0];Max=Min=array[0];for(i=1;i<n;i++){if(array[i]>Max)Max=array[i];elseif(array[i]<Min)Min=array[i];

sum=sum+array[i];}aver=sum/n;return(aver);}全局變量能在定義之后的所有函數中使用

Page72

全局變量應用舉例voidmain(){floatave;floatscore[10],i;for(i=0;i<10;i++)scanf("%f",&score[i]);ave=average(score,10);printf("max=%6.2f\n",Max);printf("min=%6.2f\n",Min);printf("average=%6.2f\n",ave);}

Page73

變量的存儲類型局部變量按其生存的時間(生存期)劃分為動態存儲變量、靜態存儲變量和寄存器變量。變量定義完整格式:

[存儲類別]數據類型變量表列;存儲類別缺省為auto(自動型)

Page74

內存中用戶區存儲空間的分配

內存

系統區用戶區(存放用戶數據與程序)存放系統程序程序區:程序靜態存儲區:全局變量靜態局部變量動態存儲區:自動局部變量形式參數函數調用時現場保護和返回值

Page75

變量的存儲類型動態變量靜態變量類別

存儲類別為auto(通常缺省)的局部變量存儲類別為static的

局部變量存儲類別為register的局部變量所有類別的全局變量存儲

位置動態存儲區靜態存儲區寄存器生存期函數運行期間程序運行期間賦初值每調用函數一次,賦初值一次只在編譯時賦初值一次(數值型默認初值為0)(字符型默認初值為空字符)

Page76

局部靜態變量應用舉例1#include<stdio.h>f(inta){autointb=0;staticintc=3;

溫馨提示

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

評論

0/150

提交評論