分析C程序的變量所存放的數(shù)據(jù)_第1頁
分析C程序的變量所存放的數(shù)據(jù)_第2頁
分析C程序的變量所存放的數(shù)據(jù)_第3頁
分析C程序的變量所存放的數(shù)據(jù)_第4頁
分析C程序的變量所存放的數(shù)據(jù)_第5頁
已閱讀5頁,還剩88頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、 分析C程序的變量所存放的數(shù)據(jù): 數(shù)值型數(shù)據(jù):整數(shù)、實數(shù)這些變量具有以下性質(zhì): 占有一定長度的內(nèi)存 單元 如:int x; x占二字節(jié)、二個單元 每一個變量都有一個地址,為無符號整數(shù),稱為地址,它不同于一般的整數(shù)。問題:能否對地址運算?能否用一個變量保存地址? 字符型數(shù)據(jù):字符、字符串10.1 指針的概念指針的概念一、數(shù)據(jù)在內(nèi)存中的存放一、數(shù)據(jù)在內(nèi)存中的存放系統(tǒng)分配i在地址為2000的單元內(nèi)存:為一個連續(xù)編號(連續(xù)地址)且以一個單元為一個字節(jié)的連續(xù)存貯區(qū)。 若程序中定義了三個int變量i, j, k int i= 5, j=5, k=10; 20002001200220032004200530

2、01 5+5102000j在地址為2002的單元k在地址為2004的單元當程序中要用它們的值時: y=i+j+k;則系統(tǒng)通過一張變量名與地址對應關系表:分別 找到i的地址為2000,將2000,2001中的數(shù)據(jù)5讀出;找到j的地址為2002,將2002,20003中的數(shù)據(jù)5讀出;找到k的地址為2004,將2004,2005中的數(shù)據(jù)10讀出。直接訪問:在程序中表現(xiàn)為直接使用存放該數(shù)據(jù)的變量名。 間接訪問:如果將某一變量的地址(如i的地址2000)存放到另一個變量x,則可通過x來存取i的值。上述過程稱為變量的“ 直接訪問” 52000i直接訪問53001i間接訪問2000 x 顯然,x與i是通過i

3、的地址聯(lián)系起來的,一個變量的地址稱為該變量的指針。因此,i的指針為2000,而存放地址(指針)的變量叫做指針變量。 如:x5510.2 指針變量的定義和引用指針變量的定義和引用 首先明確一個概念:指針變量也有類型,因為類型涉及到所占單元數(shù),也就是指針變量在計算時有所不同。例如: 當x為一個指向float型的指針變量時 x1:設x為2000,則x+12004 當x為一個指向整型變量的指針變量時。 x+1: 設x原為2000,則x+12002一、一、 定義指針變量的形式:定義指針變量的形式:表示該變量為指向某類型變量的指針變量x只能指向整型變量,即只能存放整型變量的地址。如: int x;類型名

4、變量名二、引用指針變量二、引用指針變量 將一個變量的地址(指針)賦給一個指針變量,用取地址運算符:&int i, j, x; x=&i; 如果將整數(shù)賦給地址量x=1000;編譯會提出警告性錯誤,但還是有值(地址) 存取指針變量所指向變量(目標變量)的值: 用指針運算符*, 即:*x 為 i , &為同級運算符,結(jié)合性自右至左。則當&或&在一起時,具有抵消作用如上例: &i相當于xi &x相當于&ix三、指針變量作為函數(shù)參數(shù)三、指針變量作為函數(shù)參數(shù)但當用地址(指針變量)作參數(shù)時,與數(shù)組名類似。 則:形參、實參均為地址量。形參,于是,

5、形參數(shù)前面講過:函數(shù)實參傳遞單向據(jù)值的改變不會影響實參。例: swap(p1, p2) int p1, p2; int p; p=p1; p1=p2 p2= p; main( ) int a, b; int x1, x2; scanf(%d,%d,&a, &b); x1=&a; x2=&b; swap(x1, x2); printf(%d,%d n,a, b);執(zhí)行過程分析(設a10, b20) &a&b2010 x1ax2b&a&a&b&b1020p1p2x1x2abp= p1; p1= p2; p2 =p;10

6、20abp1p2p&a&a&b&b2010p1p2x1x2ab 釋放p1, p2后&a&b1020 x1ax2b1. 注意函數(shù)中p為普通變量,并非地址量,如p為地址量,它為哪一個變量的地址?這時: int t,*p=&t;(允許) p= p12. 如果swap函數(shù)中的交換語句改為: int p1, p2, p; p=p1; p1=p2; p2=p; 則僅將p1, p2的指向改變,函數(shù)返回后,p1, p2釋放, a、b中的內(nèi)容依然未改變。 sway(p1, p2)int p1, p2; int p;p=p1;p1=p2;p2=p; 則:只將

7、p1,p2的內(nèi)容改變,而不能使a, b交換。3. 不用地址量,也未能實現(xiàn)交換,即:4. 結(jié)論:當需要被調(diào)函數(shù)改變調(diào)用函數(shù)中n個變量的值時,需將這n個變量的地址(用指針變量、或直接用地址量&a, &b)作為實參傳給指針形參,且被調(diào)函數(shù)通過改變指針形參所指向的變量來實現(xiàn)實參中變量值 的改變。10.3 數(shù)組的指針及指向數(shù)組的指針變量數(shù)組的指針及指向數(shù)組的指針變量前面介紹:一個變量的地址為該變量的指針。當用一個變量來存放該地址(指針)時,稱為指針變量。又有說明: 一個數(shù)組元素相當于一個簡單變量。于是,亦可用一個指針變量來指向數(shù)組元素。不同點: 數(shù)組元素連續(xù)地占用內(nèi)存單元,則當一個元素的

8、指針已知時,其它元素的指針亦可知道。 定義方法與簡單變量指針定義相同,但引用略有不同例: int a10; int p; 定義p=&a0; 將a的第0個元素的地址p C語言規(guī)定: a的首地址即可用&a0表示,亦可用a表示 所以:p=&a0; 和 p=a等價一、數(shù)組元素指針變量的定義與引用一、數(shù)組元素指針變量的定義與引用可以在定義指針變量時賦初值: int p=&a0; 或 int p=a; (等價于) int p; p=a;它不同于語句: p=&a0;1. 由首地址指針來引用數(shù)組中的其它元素。 設p為a的首地址,p=a,或p=&a0; p+1為a

9、1的地址,當a為int,p+1相當于地址+2, 而當a為float時,p+1相當于地址+4.則p+1是什么意思?一般地: p+i ai 的地址,或為a+i引用ai的值: ai, (p+i), (a+i)例:int a10, i; int p; p=a;則: (a+i)和ai都得計算元素地址,而p+后,p可直接指向ai。2. 在搜索數(shù)組元素時,用p+i比ai+來得快3. 關于指針的運算 指針運算符 與+, 同級,且自右至左。 p+ / p 的作用: 若p=a或p=&a0, 則p+相當于p=p+1, 即指向a1 若p=&a5, 則p 相當于p=p 1,即指向a4 (p)+ 或(p)

10、 (p)+:將p指向的變量的值自增1; (p) : 將p指向的變量的值自減1。 p+與(+p) p+相當于(p+) 若p=&a0, 則:先取p的值,即 a0的值,再使p+1, p指向a1. (+p)為先使pp+1, p指向a1, (+p)取出a1的值。 前面已敘述過,當實、形參均為數(shù)組名時,調(diào)用時將實參數(shù)組首地址傳遞(單向)給形參數(shù)組,使它們共享內(nèi)存。 例:編寫函數(shù),將數(shù)組各元素值取反。 main ( ) void invert( ); int a10, i; for (i=0;i10; i+) scanf( %d, &ai); invert(a, 10);二、數(shù)組名作函數(shù)參數(shù)

11、二、數(shù)組名作函數(shù)參數(shù) for (i=0; i10; i+) printf(a%d=%d, ,i, ai); void invert(x, n) int x , n; int i; for (i=0; in; i+) xi= xi; return; 分析參數(shù)傳遞情況:a10:a0 a1 a2 a9axx0 x1 x9即:x, a共享同一段內(nèi)存單元。前面已分析: 可用指針表示數(shù)組。即:指針運算引用數(shù)組元素,于是,可用指針變量作為形參接收實參數(shù)組首地址。函數(shù)改為: void invert (x, n) int x, n; int i; for (i=x; i(x+n) ;i+) i= i retur

12、n;參數(shù)傳遞情況:a0 a1 a2 a9a:xx+1x+9 x (x+1)(x+9) 進一步分析:在主函數(shù)中也不一定要用數(shù)組名a,只要用一指針變量即可。設int p; p=&a0, 則: invert(p, n); 即可完成同樣功能總結(jié)以上情況,有四種參數(shù)傳遞形式: 特別是(3)種情況:當不是數(shù)組元素時,即實參形參均為單個指針變量時,實現(xiàn)了實、形參共用內(nèi)存單元。(1) 實參、形參均為數(shù)組名(2) 實參為數(shù)組名、形參為指針變量(3) 實參、形參均為指針變量(4) 實參為指針變量,形參為數(shù)組名。1. 多維數(shù)組的地址: 將一維數(shù)組內(nèi)容擴充,也可用一指針變量指向多維數(shù)組,以二維數(shù)組為例加以討論

13、。設: static int a34 = 1, 2, 3, 4, 5, 6,7, 8, 9, 10, 11, 12;三、指向多維數(shù)組的指針和指針變量。三、指向多維數(shù)組的指針和指針變量。1212345678910 11第1行第2行第3行a0a0+1a0+2a0+3a1a1+1a1+2a1+3a2a2+1a2+2a2+3數(shù)組名a0 數(shù)組名a1數(shù)組名a2aa+1a+1 設首地址a:2000, 則a+1:2008, a+2: 2016 從一維數(shù)組中我們認為:a0與a, (a+0)等價所以:a0i的地址&a0i還可表示為(a+i)于是:aij可表示為 *(*(a+i)+j) a0i的地址:a0+

14、i, a+i, 和&a0i a1i的地址:a1+i, (a+1)+i, &a1i aij的地址:ai+j= (a+i)+j 有了多維數(shù)組的地址概念后,可用指針變量來指向多維數(shù)組 設二維數(shù)組的大小為m*n, 則第i, j個元素相對于a00的個數(shù)為mi + j (i=0,1,,n1)2. 多維數(shù)組的指針 指向數(shù)組元素 當用一個指針變量指向第0行的首地址后,即可搜索到全部元素。設:int p; p=a0; 則第aIj 的地址為p+i m+jmain ( ) static int a34=1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; int p; for

15、 (p=a0; pa0+12; p+) if (p a0) %4= =0) printf(n); printf (%4d, p); 例: 設有一34的二維數(shù)組,利用指針逐行逐個輸出元素。注: 為什么p的初值不能寫成p=a;?仍為上例為例: 當p=a, 則p+1為下一行首地址,于是引用第(i, j)個元素的方法:第i行首地址,相當于ai 這時,需將p的定義改為 int (p)4; 指向數(shù)組的每一行(p+i)+j) a) 不能去掉( ),否則為int p4為指針數(shù)組 b) 之所以這樣定義是為了使p+1的地址為a1, 即:移動4個元素。例:有一個班,3個學生,各學4門課,計算總平均分數(shù),以及第n個學

16、生的成績。程序如下: main ( ) void average( );void search ( );static float score 3 4=65, 67, 70, 60,80,87,90,81, 90,99,100,98;average (*score, 12); /*求12個分數(shù)的平均分8*/search( score,2); /*求第2個學生成績*/void average (p, n)float *p; int n;float *p_end;float sum=0, aver;p_end=p+n1;for (; p=p_end; p+) sum=sum+(*p);aver=su

17、m/n;printf(average=%5.2fn, aver);void search (p, n)float (*p) 4; int n;int i;printf(the scores of No.%d are:n, n);for (i=0; i4; i+) printf(%5.2f , *(*(p+n)+i);程序運行結(jié)果如下:average=82.25the scores of No. 2 are:90.00 99.00 100.00 98.00 設有三個學生,各有四門功課,求總的平均分,各學生總分,且將三個學生的成績按總分排序。要求用指針變量:應有舉例: 實參可用指向一維數(shù)組的指針變

18、量;即: 數(shù)組名 實參可用指向數(shù)組的指針變量(實數(shù)組名) 輸入三學生單科成績一、流程圖:計算各學生總分計算總平均分按各學生總分排序打印各科成績總分及總平均分結(jié)束調(diào)用函數(shù)sumscore(p,n)指針,指向一維數(shù)組調(diào)用函數(shù)average(p,n)調(diào)用函數(shù)sort(p,n)調(diào)用函數(shù)printscore(p,n)學生人數(shù)指向二維數(shù)組 人數(shù)返回值float指向一維數(shù)組人數(shù)指向二維數(shù)組人數(shù)main ( ) void sumscore ( ); float average( ); void sort( ); void printscore( ); static float score35=65, 80,

19、90, 100, 80, 66, 75, 90, 58, 60, 90, 83;二、程序1. 主函數(shù)sumscore(score, 3);printf(n average=%f, average(score, 3);sort(score, 3);printscore(score, 3); void sumscore(p, n)float p; int n; float aver, p_end;p_end=p+5 n 1;for (; p=p_end; p=p+5) (p+4)= p+ p(p+1)+ (p+2)+ (p+3); 2. sumscore函數(shù)求總分float average(p,

20、n)float (p)5;int n; float aver=0.0; int i; for (i=0; in; i+) aver=aver+ (p+i)+4); aver=aver/nreturn(aver); 3. average函數(shù)求總平均分有二種方法:(1)循環(huán)時用簡單變量 (2)循環(huán)時用指針變量方法(1)void sort (p, n)float p;int n; int i, j, k, m; float t;for (i=0; in 1; i+)3. sort函數(shù)排序 k=i; for (j=i+1; jn; j+) if (p+4+5 i) (p+4+5 j) k=j; if

21、(k!=i) for (m=0; m5; m+) t= (p+m+5 i); (p+m+5 i)= (p+m+5 k); (p+m+5 k)=t; 方法(2)void sort (p, n)float pint n; float p1, p_end, k, t;int m;p_end=p+5 n 1;p=p+4;for (; pp_end 5; p+=5) k=p; for (p1=p+5; p1p_end; p1+=5) if (p p1) k=p1; if (k!=p) for (m=0; m5; m+) t= (p m); (p m)= (k1 m); (k1 m)=t; void pr

22、intscore(p, n)float (p)5;int n; int i, j;printf(n A B C D sumn);for (i=0; i0; i+) printf(n);for (j=0; jy)? x:y; return(z); main ( ) int max( ); int (p)( ); int a, b, c; p=max; scanf(a=%d, b=%d, &a,&b); c=(p) (a, b) printf(max value=%d, c)4. 對函數(shù)指針變量進行運算無意義。二、函數(shù)指針變量作為函數(shù)參數(shù)二、函數(shù)指針變量作為函數(shù)參數(shù) 意義:當一個函

23、數(shù)被調(diào)用后,執(zhí)行過程中需根據(jù)實際情況調(diào)用f1, f2,或調(diào)用f3, f4,于是在該函數(shù)中即可用函數(shù)指針變量作形式參數(shù)。前面介紹過:簡單變量、數(shù)組名、指針變量均可作為函數(shù)的參數(shù)。能否用函數(shù)指針變量作參數(shù)呢?當然可以!例:sub (x1, x2) int (x1 )( ), (x2 )( ); int a, b, i, j; a=(x1) (i); b=(x2) (i, j) 于是,可用 sub(f1, f2)或sub(f3, f4)調(diào)用sub,表示執(zhí)行sub時,根據(jù)實參傳遞過來的函數(shù)入口地址而調(diào)用f1, f2或f2, f4.例2. 設計一個函數(shù)process, 每次實現(xiàn)不同的功能,當用不同的函數(shù)

24、名作實參調(diào)用process時,process再去調(diào)用相應的函數(shù)。程序如下:main ( )int max( ), min( ), add( );int a, b;printf(enter a and b:);scanf(%d, %d, &a, &b);printf(max=);process(a, b, max);printf(min=)process(a, b, min);printf(sum=);process(a, b, add);max(x, y)int x, y;int z;if (xy) z=x;else z=y; return(z);min(x, y)int x,

25、 y;int z;if (xy) z=x;else z=y; return(z);add(x, y)int x, y;int z;z=x+y;return(z); process (x, y, fun) int x, y; int (* fun) ( ); int result; result=(*fun) (x,y); printf(%dn, result); 注:當用函數(shù)名作參數(shù)時,不論函數(shù)返值類型如何均應作說明,以與變量名相區(qū)別。運行情況如下:enter a and b:2, 6max=6min=2sum=8 本概念比較簡單,既然函數(shù)返回值可以是整、實型等數(shù)據(jù)。當然也可以是指針值,只是函

26、數(shù)定義形式略有不同:例: 有若干個學生的成績(每個學生有4門課程),要求在用戶輸入學生序號以后,能輸出該學生的全部成績。用指針函數(shù)來實現(xiàn)。類型標識符 函數(shù)名(形參表列)float * search ( );float * p;int i, m;printf(enter the number of student:);scanf(%d, &m);printf(The scores of No. %d are :n, m);程序如下:static float score 4=60,70,80,90, 56,89,67, 88, 34, 78, 90, 66;main ( )p=search

27、 (score, m);for (i=0; i4; i+) printf(%5.2ft, * (p+i); float * seaarch (pointer, n)float (* pointer) 4;int n;float * pt;pt= * (pointer +n);return (pt);運行情況如下:enter the number of student: 1The scpres pf Mp. 1 are:56.00 89.00 67.00 88.00一、指針數(shù)組一、指針數(shù)組1. 定義形式 類型說明符 數(shù)組名常量數(shù)組同種類型的數(shù)據(jù)集合。 當每一個元素均為指針類型數(shù)據(jù)時,該數(shù)組被稱為

28、指針數(shù)組。例:int p10; p為指針型數(shù)組,其每一個元素為一指針型變量。用來存入一組地址。一個重要的應用存放一組字符串 在對字符串排序時,若交換數(shù)組元素,時間太長。 所以,用指針數(shù)組(一維)保存各字符串首地址,且交換時只需交換指針數(shù)組各元素首地址即可解決上述二個問題。 字符串長度不一,于是只得以最長字符串的長度作為二維數(shù)組列數(shù),造成空間浪費。 一般情況下,當有一組字符串,如一組書名,也可用二維字符數(shù)組存放,但存在二個問題:2. 應用例:將若干字符串按字母順序(由小到大)輸出。main ( )void sort ( ); void print ( ); static char * name =Follow me, BASIC, Great Wall, FORTRAN, Computer design;int n=5;sort (name, n);print(name, n);void s

溫馨提示

  • 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

提交評論