課程設(shè)計作品C語言2_第1頁
課程設(shè)計作品C語言2_第2頁
課程設(shè)計作品C語言2_第3頁
課程設(shè)計作品C語言2_第4頁
課程設(shè)計作品C語言2_第5頁
已閱讀5頁,還剩161頁未讀, 繼續(xù)免費閱讀

付費下載

下載本文檔

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

文檔簡介

第七章

善于利用指針01指針是什么02指針變量03通過指針引用數(shù)組04通過指針引用字符串0205函數(shù)指針06返回指針值的函數(shù)07指針數(shù)組和多重指針08動態(tài)存儲分配0309有關(guān)指針的小結(jié)指針是什么01041.1地址與指針7.1.1057.1.2inta=5;int*p;p=&a;變量名:a變量值:5變量的地址:&a變量名:a變量值:5變量的地址:&a5a&ap一個變量的地址稱為該變量的“指針”1.1地址與指針7.1.1067.1.2inta=5;int*p;p=&a;變量名:a變量值:5變量的地址:&a變量名:a變量值:5變量的地址:&a5a&ap對于a變量,可以通過指針p去間接訪問。1.1地址與指針07有如下關(guān)系:

a*p&apa=3;*p=3;7.1.17.1.208printf(“%d”,i);通過變量名i找到i的地址2000,從而從存儲單元讀取3inti=3,j=6,k;1.2直接存取與間接存取7.1.17.1.209k=i+j;從這里取3從這里取6將9送到這里直接存取inti=3,j=6,k;1.2直接存取與間接存取7.1.17.1.2010inti=3,j=6,k;定義特殊變量i_pointeri_pointer=&i;將i的地址存到這里*i_pointer=50;50間接存取1.2直接存取與間接存取7.1.17.1.21.1指針是什么11i200032000i_pointer*i_pointer20003直接存取間接存取7.1.17.1.2指針變量02122.1使用指針變量的例子7.2.17.2.27.2.37.2.413例:通過指針變量訪問整型變量。解題思路:定義2個整型變量定義2個指針變量兩指針分別指向這兩個整型變量訪問指針變量,找到其所指變量,獲取變量值2.1使用指針變量的例子14#include<stdio.h>intmain(){inta=100,b=10;

int*pointer_1,*pointer_2;

pointer_1=&a;

pointer_2=&b;printf(“a=%d,b=%d\n”,a,b);printf(“*pointer_1=%d,*pointer_2=%d\n”,*pointer_1,*pointer_2);return0;}定義兩個指針變量使pointer_1指向a使pointer_2指向b直接輸出變量a和b的值間接輸出變量a和b的值7.2.17.2.27.2.37.2.4#include<stdio.h>intmain(){inta=100,b=10;

int*pointer_1,*pointer_2;

pointer_1=&a;

pointer_2=&b;printf(“a=%d,b=%d\n”,a,b);printf(“*pointer_1=%d,*pointer_2=%d\n”,*pointer_1,*pointer_2);return0;}2.1使用指針變量的例子15此處*與類型名在一起。此時共同定義指針變量此處*與指針變量一起使用。此時代表指針變量所指向的變量7.2.17.2.27.2.37.2.42.2怎樣定義指針變量16定義指針變量的一般形式為:

類型*指針變量名;如:int*pointer_1,*pointer_2;int是為指針變量指定的“基類型”基類型指定指針變量可指向的變量類型7.2.17.2.27.2.37.2.42.2怎樣定義指針變量17下面都是合法的定義和初始化:float*pointer_3;char*pointer_4;inta,b;int*pointer_1=&a,*pointer_2=&b;*pointer_1=&a;錯誤pointer_3=&a;錯誤pointer_1=&a;正確pointer_3=2000;錯誤7.2.17.2.27.2.37.2.42.2怎樣定義指針變量18一個變量的指針含義包括兩個方面:以存儲單位編號表示的地址;其指向的存儲單元的數(shù)據(jù)類型。7.2.17.2.27.2.37.2.42.3怎樣定義指針變量19在引用指針變量時,可能有三種情況:給指針變量賦值。如:p=&a;引用指針變量指向的變量。如有p=&a;*p=1;

則執(zhí)行printf(“%d”,*p);將輸出1引用指針變量的值。如:printf(“%o”,p);使p指向a*p相當于a以八進制輸出a的地址7.2.17.2.27.2.37.2.42.3怎樣定義指針變量20要熟練掌握兩個有關(guān)的運算符:&

取地址運算符。&a是變量a的地址*指針運算符(“間接訪問”運算符)如果:p指向變量a,則*p就代表a。k=*p;(把a的值賦給k)

*p=1;(把1賦給a)7.2.17.2.27.2.37.2.42.4指針變量作為函數(shù)參數(shù)21如果想通過函數(shù)調(diào)用得到n個要改變的值:在主調(diào)函數(shù)中設(shè)n個變量,用n個指針變量指向它們設(shè)計一個函數(shù),有n個指針形參。在這個函數(shù)中改變這n個形參的值7.2.17.2.27.2.37.2.4在主調(diào)函數(shù)中調(diào)用這個函數(shù),在調(diào)用時將這n個指針變量作實參,將它們的地址傳給該函數(shù)的形參在執(zhí)行該函數(shù)的過程中,通過形參指針變量,改變它們所指向的n個變量的值主調(diào)函數(shù)中就可以使用這些改變了值的變量22如果想通過函數(shù)調(diào)用得到n個要改變的值:2.4指針變量作為函數(shù)參數(shù)7.2.17.2.27.2.37.2.42.4指針變量作為函數(shù)參數(shù)23例:對輸入的兩個整數(shù)按大小順序輸出。解題思路:嘗試調(diào)用swap函數(shù)來實現(xiàn)要求在函數(shù)中改變形參(指針變量)的值,由此改變實參(指針變量)的值7.2.17.2.27.2.37.2.42.4指針變量作為函數(shù)參數(shù)24#include<stdio.h>intmain(){voidswap(int*p1,int*p2);inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("max=%d,min=%d\n",a,b);return0;}voidswap(int*p1,int*p2){int*p;p=p1;p1=p2;p2=p;}錯?。?!只交換形參指向7.2.17.2.27.2.37.2.42.4指針變量作為函數(shù)參數(shù)25注意:函數(shù)的調(diào)用可且只可得到一個返回值(即函數(shù)值)使用指針變量作參數(shù),可以得到多個變化值如果不用指針變量是難以做到這一點要善于利用指針法7.2.17.2.27.2.37.2.4通過指針引用數(shù)組03263.1數(shù)組元素的指針7.3.17.3.27.3.37.3.4277.3.5一個變量有地址,一個數(shù)組包含若干元素,每個數(shù)組元素都有相應(yīng)的地址指針變量可以指向數(shù)組元素(把某一元素的地址放到一個指針變量中)數(shù)組元素的指針就是數(shù)組元素的地址3.1數(shù)組元素的指針28可以用一個指針變量指向一個數(shù)組元素inta[10]={1,3,5,7,9,11,13,15,17,19};int*p;p=&a[0];等價于p=a;等價于int*p=a;或int*p=&a[0];注意:數(shù)組名a不代表整個數(shù)組,只代表數(shù)組首元素的地址?!皃=a;”的作用是“把a數(shù)組的首元素的地址賦給指針變量p”,而不是“把數(shù)組a各元素的值賦給p”。7.3.17.3.27.3.37.3.47.3.53.2在引用數(shù)組元素時指針的運算29在指針指向數(shù)組元素時,允許以下運算:加一個整數(shù)(用+或+=),如p+1減一個整數(shù)(用-或-=),如p-1自加運算,如p++,++p自減運算,如p--,--p兩個指針相減,如p1-p2(只有p1和p2都指向同一數(shù)組中的元素時才有意義)7.3.17.3.27.3.37.3.47.3.53.2在引用數(shù)組元素時指針的運算30(1)如果指針變量p已指向數(shù)組中的一個元素,則p+1指向同一數(shù)組中的下一個元素,p-1指向同一數(shù)組中的上一個元素。floata[10],*p=a;假設(shè)a[0]的地址為2000,則p的值為2000p+1的值為2004P-1的值為1996越界7.3.17.3.27.3.37.3.47.3.53.2在引用數(shù)組元素時指針的運算31(2)如果p的初值為&a[0],則p+i和a+i就是數(shù)組元素a[i]的地址,或者說,它們指向a數(shù)組序號為i的元素a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]p+1,a+1p+i,a+ip+9,a+9p7.3.17.3.27.3.37.3.47.3.53.2在引用數(shù)組元素時指針的運算32a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]pp+1,a+1p+i,a+ip+9,a+9(3)*(p+i)或*(a+i)是p+i或a+i所指向的數(shù)組元素,即a[i]。*(p+i)7.3.17.3.27.3.37.3.47.3.53.2在引用數(shù)組元素時指針的運算33a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9](4)如果指針p1和p2都指向同一數(shù)組p2-p1的值是4不能p1+p2p1p27.3.17.3.27.3.37.3.47.3.53.3通過指針引用數(shù)組元素34引用一個數(shù)組元素,可用下面兩種方法:下標法,如a[i]形式指針法,如*(a+i)或*(p+i)其中a是數(shù)組名,p是指向數(shù)組元素的指針變量,其初值p=a7.3.17.3.27.3.37.3.47.3.53.3通過指針引用數(shù)組元素35

例:有一個整型數(shù)組a,有10個元素,要求輸出數(shù)組中的全部元素。解題思路:引用數(shù)組中各元素的值有3種方法:下標法;通過數(shù)組名計算數(shù)組元素地址,找出元素的值;用指針變量指向數(shù)組元素分別寫出程序,以資比較分析。7.3.17.3.27.3.37.3.47.3.53.3通過指針引用數(shù)組元素36(1)下標法。

#include<stdio.h>intmain(){inta[10];inti;printf(“enter10integernumbers:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=0;i<10;i++)printf(“%d”,a[i]);printf("%\n");return0;}7.3.17.3.27.3.37.3.47.3.5(2)通過數(shù)組名計算數(shù)組元素地址,找出元素的值#include<stdio.h>intmain(){inta[10];inti;printf(“enter10integernumbers:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=0;i<10;i++)printf(“%d”,*(a+i));printf("\n");return0;}3.3通過指針引用數(shù)組元素37scanf("%d",a+i);7.3.17.3.27.3.37.3.47.3.5(3)用指針變量指向數(shù)組元素#include<stdio.h>intmain(){inta[10];int*p,i;printf(“enter10integernumbers:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);for(p=a;p<(a+10);p++)printf(“%d”,*p);printf("\n");return0;}3.3通過指針引用數(shù)組元素38for(p=a;p<(a+10);p++)scanf("%d",p);for(p=a;p<(a+10);a++)

printf(“%d”,*a);

錯!7.3.17.3.27.3.37.3.47.3.53.3通過指針引用數(shù)組元素393種方法的比較:①第(1)和第(2)種方法執(zhí)行效率相同C編譯系統(tǒng)是將a[i]轉(zhuǎn)換為*(a+i)處理的,即先計算元素地址。因此用第(1)和第(2)種方法找數(shù)組元素費時較多。7.3.17.3.27.3.37.3.47.3.53.3通過指針引用數(shù)組元素403種方法的比較:②第(3)種方法比第(1)、第(2)種方法快用指針變量直接指向元素,不必每次都重新計算地址,像p++這樣的自加操作是比較快的這種有規(guī)律地改變地址值(p++)能大大提高執(zhí)行效率7.3.17.3.27.3.37.3.47.3.53.3通過指針引用數(shù)組元素413種方法的比較:③用下標法比較直觀,能直接知道是第幾個元素。

用地址法或指針變量的方法不直觀,難以很快地判斷出當前處理的是哪一個元素。7.3.17.3.27.3.37.3.47.3.53.4用數(shù)組名作函數(shù)參數(shù)42用數(shù)組名作函數(shù)參數(shù)時,因為實參數(shù)組名代表該數(shù)組首元素的地址,形參應(yīng)該是一個指針變量C編譯都是將形參數(shù)組名作為指針變量來處理的7.3.17.3.27.3.37.3.47.3.543intmain(){voidfun(intarr[],intn];intarray[10];

fun(array,10);return0;}voidfun(intarr[],intn){┇}fun(int*arr,intn)3.4用數(shù)組名作函數(shù)參數(shù)7.3.17.3.27.3.37.3.47.3.544array[0]arr[0]array數(shù)組arrarray[3]arr[3]arr+33.4用數(shù)組名作函數(shù)參數(shù)intmain(){voidfun(intarr[],intn];intarray[10];

fun(array,10);return0;}voidfun(int*arr,intn){┇}7.3.17.3.27.3.37.3.47.3.545實參數(shù)組名是指針常量,但形參數(shù)組名是按指針變量處理在函數(shù)調(diào)用進行虛實結(jié)合后,它的值就是實參數(shù)組首元素的地址在函數(shù)執(zhí)行期間,形參數(shù)組可以再被賦值voidfun(arr[],intn){printf(″%d\n″,*arr);

arr=arr+3;

printf(″%d\n″,*arr);

}3.4用數(shù)組名作函數(shù)參數(shù)7.3.17.3.27.3.37.3.47.3.546例:將數(shù)組a中n個整數(shù)按相反順序存放解題思路:將a[0]與a[n-1]對換,……將a[4]與a[5]對換。ji3.4用數(shù)組名作函數(shù)參數(shù)7.3.17.3.27.3.37.3.47.3.547ji3.4用數(shù)組名作函數(shù)參數(shù)例:將數(shù)組a中n個整數(shù)按相反順序存放解題思路:將a[0]與a[n-1]對換,……將a[4]與a[5]對換。7.3.17.3.27.3.37.3.47.3.548ji3.4用數(shù)組名作函數(shù)參數(shù)例:將數(shù)組a中n個整數(shù)按相反順序存放解題思路:將a[0]與a[n-1]對換,……將a[4]與a[5]對換。7.3.17.3.27.3.37.3.47.3.549ji3.4用數(shù)組名作函數(shù)參數(shù)例:將數(shù)組a中n個整數(shù)按相反順序存放解題思路:將a[0]與a[n-1]對換,……將a[4]與a[5]對換。7.3.17.3.27.3.37.3.47.3.550ji3.4用數(shù)組名作函數(shù)參數(shù)例:將數(shù)組a中n個整數(shù)按相反順序存放解題思路:將a[0]與a[n-1]對換,……將a[4]與a[5]對換。7.3.17.3.27.3.37.3.47.3.53.5通過指針引用多維數(shù)組51指針變量可以指向一維數(shù)組中的元素,也可以指向多維數(shù)組中的元素。但在概念上和使用方法上,多維數(shù)組的指針比一維數(shù)組的指針要復(fù)雜一些。7.3.17.3.27.3.37.3.47.3.5521.多維數(shù)組元素的地址inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};1357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針3.5通過指針引用多維數(shù)組7.3.17.3.27.3.37.3.47.3.5531357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針a代表第0行首地址a+1代表第1行首地址a+2代表第2行首地址行指針每加1,走一行3.5通過指針引用多維數(shù)組7.3.17.3.27.3.37.3.47.3.5541357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針a+i代表行號為i的行首地址(按行變化)*(a+i)代表什么?相當于a[i]3.5通過指針引用多維數(shù)組7.3.17.3.27.3.37.3.47.3.5551357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針a[0]代表a[0][0]的地址a[0]+1代表a[0][1]的地址a[0]+2代表a[0][2]的地址a[0]+3代表a[0][3]的地址列指針每加1,走一列3.5通過指針引用多維數(shù)組7.3.17.3.27.3.37.3.47.3.5561357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針a[1]代表誰的地址?a[1]+1代表誰的地址?a[1]+2代表誰的地址?a[1]+3代表誰的地址?3.5通過指針引用多維數(shù)組7.3.17.3.27.3.37.3.47.3.5571357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針a[i]+j代表誰的地址?代表a[i][j]的地址*(a[i]+j)代表什么?代表元素a[i][j]*(*(a+i)+j)代表什么?與*(a[i]+j)等價3.5通過指針引用多維數(shù)組7.3.17.3.27.3.37.3.47.3.5582.指向多維數(shù)組元素的指針變量

3.5通過指針引用多維數(shù)組

指向由m個元素組成的一維數(shù)組的指針變量

指向數(shù)組元素的指針變量7.3.17.3.27.3.37.3.47.3.5593.用指向數(shù)組的指針作函數(shù)參數(shù)3.5通過指針引用多維數(shù)組一維數(shù)組名可以作為函數(shù)參數(shù),多維數(shù)組名也可作函數(shù)參數(shù)。用指針變量作形參,以接受實參數(shù)組名傳遞來的地址。可以有兩種方法:①用指向變量的指針變量②用指向一維數(shù)組的指針變量7.3.17.3.27.3.37.3.47.3.5通過指針引用字符串04604.1字符串的引用方式7.4.17.4.27.4.361字符串是存放在字符數(shù)組中的。引用一個字符串,可以用以下兩種方法。

用字符數(shù)組存放一個字符串,可以通過數(shù)組名和格式聲明“%s”輸出該字符串,也可以通過數(shù)組名和下標引用字符串中一個字符。

用字符指針變量指向一個字符串常量,通過字符指針變量引用字符串常量。62

例:通過字符指針變量輸出一個字符串。

解題思路:定義一個字符指針變量用它指向字符串常量中的字符通過字符指針變量輸出該字符串。4.1字符串的引用方式7.4.17.4.27.4.363#include<stdio.h>intmain(){char*string=“IloveChina!”;printf(“%s\n”,string);return0;}stringchar*string;string=”IloveChina!”;4.1字符串的引用方式7.4.17.4.27.4.364#include<stdio.h>intmain(){char*string=“IloveChina!”;printf(“%s\n”,string);

string=”Iamastudent.”;printf(“%s\n”,string);return0;}string4.1字符串的引用方式7.4.17.4.27.4.365#include<stdio.h>intmain(){char*string=“IloveChina!”;printf(“%s\n”,string);

string=”Iamastudent.”;printf(“%s\n”,string);return0;}string4.1字符串的引用方式7.4.17.4.27.4.34.2字符指針作函數(shù)參數(shù)66把一個字符串從一個函數(shù)“傳遞”到另一個函數(shù),可以使用地址傳遞。即用字符數(shù)組名作參數(shù),也可以用字符指針變量作參數(shù)。在被調(diào)用的函數(shù)中可以改變字符串的內(nèi)容在主調(diào)函數(shù)中可以引用改變后的字符串。7.4.17.4.27.4.367用函數(shù)調(diào)用實現(xiàn)字符串的復(fù)制4.2字符指針作函數(shù)參數(shù)(1)用字符數(shù)組名作為函數(shù)參數(shù)(2)用字符指針變量作形參和實參7.4.17.4.27.4.368用函數(shù)調(diào)用實現(xiàn)字符串的復(fù)制4.2字符指針作函數(shù)參數(shù)(3)用字符型指針變量作實參copy_string不變,在main函數(shù)中定義字符指針變量from和to,分別指向兩個字符數(shù)組a,b。僅需要修改主函數(shù)代碼7.4.17.4.27.4.34.3字符指針變量和字符數(shù)組69區(qū)別用字符數(shù)組和字符指針變量實現(xiàn)字符串的存儲和運算:(1)字符數(shù)組由若干個元素組成,每個元素中放一個字符,而字符指針變量中存放的是地址(字符串第1個字符的地址),決不是將字符串放到字符指針變量中。7.4.17.4.27.4.34.3字符指針變量和字符數(shù)組70區(qū)別用字符數(shù)組和字符指針變量實現(xiàn)字符串的存儲和運算:(2)賦值方式。可以對字符指針變量賦值,但不能對數(shù)組名賦值。char*a;a=”IloveChina!”;對charstr[14];str[0]=’I’;對charstr[14];str=”IloveChina!”;錯7.4.17.4.27.4.34.3字符指針變量和字符數(shù)組71區(qū)別用字符數(shù)組和字符指針變量實現(xiàn)字符串的存儲和運算:(3)初始化的含義char*a=”IloveChina!”;與char*a;a=”IloveChina!”;等價7.4.17.4.27.4.34.3字符指針變量和字符數(shù)組72區(qū)別用字符數(shù)組和字符指針變量實現(xiàn)字符串的存儲和運算:(4)存儲單元的內(nèi)容

編譯時為字符數(shù)組分配若干存儲單元,以存放各元素的值,而對字符指針變量,只分配一個存儲單元7.4.17.4.27.4.34.3字符指針變量和字符數(shù)組73區(qū)別用字符數(shù)組和字符指針變量實現(xiàn)字符串的存儲和運算:(4)存儲單元的內(nèi)容char*a;scnaf(“%s”,a);錯

char*a,str[10];a=str;scanf(“%s”,a);對7.4.17.4.27.4.34.3字符指針變量和字符數(shù)組74區(qū)別用字符數(shù)組和字符指針變量實現(xiàn)字符串的存儲和運算:(5)指針變量的值是可以改變的,而數(shù)組名代表一個固定的值(數(shù)組首元素的地址),不能改變。

對7.4.17.4.27.4.3函數(shù)指針057576如果在程序中定義了一個函數(shù),在編譯時,編譯系統(tǒng)為函數(shù)代碼分配一段存儲空間,這段存儲空間的起始地址,稱為這個函數(shù)的指針。5.1函數(shù)指針7.5.17.5.27.5.37.5.45.1指針變量的定義定義p是指向函數(shù)的指針變量,它可以指向類型為整型且有兩個整型參數(shù)的函數(shù)。p的類型用int(*)(int,int)表示。77例如:int(*p)(int,int);7.5.17.5.27.5.37.5.4解決方法:1.通過函數(shù)名調(diào)用函數(shù)。2.通過指針變量訪問它所指向的函數(shù)。78問題:用函數(shù)求整數(shù)a和b中的大者。5.2指針變量的操作7.5.17.5.27.5.37.5.479(1)通過函數(shù)名調(diào)用函數(shù)#include<stdio.h>intmain(){intmax(int,int);inta,b,c;printf("pleaseenteraandb:");scanf("%d,%d",&a,&b);c=max(a,b);printf(“%d,%d,max=%d\n",a,b,c);return0;}//函數(shù)聲明//通過函數(shù)名調(diào)用函數(shù)5.2指針變量的操作7.5.17.5.27.5.37.5.480intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}//定義max函數(shù)5.2指針變量的操作7.5.17.5.27.5.37.5.481運行結(jié)果:5.2指針變量的操作7.5.17.5.27.5.37.5.482(2)通過指針變量訪問它所指向的函數(shù)#include<stdio.h>intmain(){intmax(int,int);

int(*p)(int,int);

inta,b,c;

p=max;printf("pleaseenteraandb:");scanf("%d,%d",&a,&b);

c=(*p)(a,b);printf(“%d,%d,max=%d\n",a,b,c);return0;}//定義指向函數(shù)的指針變量p//使p指向max函數(shù)//通過指針變量調(diào)用max函數(shù)5.2指針變量的操作7.5.17.5.27.5.37.5.483intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}5.2指針變量的操作7.5.17.5.27.5.37.5.484運行結(jié)果:5.2指針變量的操作7.5.17.5.27.5.37.5.4定義指向函數(shù)的指針變量(即函數(shù)指針)的一般形式為

數(shù)據(jù)類型(*指針變量名)(函數(shù)參數(shù)表列);

85例如:int(*p)(inta,intb);5.3函數(shù)指針7.5.17.5.27.5.37.5.486判定指針變量是指向函數(shù)的指針變量的方法:1.首先,看變量名的前面有無“*”號,如*p。如果有,則是指針變量而不是普通變量。2.其次,看變量名的后面有無圓括號,內(nèi)有形參的類型。如果有,就是指向函數(shù)的指針變量,這對圓括號是函數(shù)的特征。注意:“*指針變量名”要用圓括號括起來(因為“*”優(yōu)先級的關(guān)系。)5.3函數(shù)指針7.5.17.5.27.5.37.5.487易錯易混點1.定義指向函數(shù)的指針變量,并不意味著這個指針變量可以指向任何函數(shù),它只能指向在定義時指定的類型的函數(shù)。如“int(*p)(int,int);”表示指針變量p指向函數(shù)返回值為整型且有兩個整型參數(shù)的函數(shù)。2.“p=max;“是用指針調(diào)用函數(shù),把max函數(shù)的入口地址賦給了指針變量p(給函數(shù)指針變量賦值)?!眕=max(a,b);”是將調(diào)用max函數(shù)所得到的函數(shù)值賦給p。5.3函數(shù)指針7.5.17.5.27.5.37.5.488問題:輸入兩個整數(shù),然后讓用戶選擇1或2,選1時調(diào)用max函數(shù),輸出二者中的大數(shù),選2時調(diào)用min函數(shù),輸出二者中的小數(shù)。5.3函數(shù)指針7.5.17.5.27.5.37.5.489#include<stdio.h>intmain(){intmax(int,int);intmin(intx,inty);int(*p)(int,int);inta,b,c,n;scanf("%d,%d",&a,&b);scanf(“%d”,&n);//定義指向函數(shù)的指針變量5.3函數(shù)指針7.5.17.5.27.5.37.5.490if(n==1)p=max;elseif(n==2)p=min;c=(*p)(a,b);printf("a=%d,b=%d\n",a,b);if(n==1)printf("max=%d\n",c);elseprintf("min=%d\n",c);return0;}//調(diào)用p指向的函數(shù)5.3函數(shù)指針7.5.17.5.27.5.37.5.491intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}

intmin(intx,inty){intz;if(x<y)z=x;elsez=y;return(z);}5.3函數(shù)指針7.5.17.5.27.5.37.5.492運行結(jié)果:5.3函數(shù)指針7.5.17.5.27.5.37.5.493指向函數(shù)的指針變量的一個重要用途:把函數(shù)的地址作為參數(shù)傳遞到其他函數(shù)(指向函數(shù)的指針可以作為函數(shù)參數(shù),把函數(shù)的入口地址傳遞給形參,這樣就能夠在被調(diào)用的函數(shù)中使用實參函數(shù))。5.4函數(shù)指針作函數(shù)參數(shù)7.5.17.5.27.5.37.5.494……intmain(){……fun(f1,f2)……}voidfun(int(*x1)(int),int(*x2)(int,int)){inta,b,i=3,j=5;a=(*x1)(i);b=(*x2)(i,j);}相當于a=f1(i);相當于b=f2(i,j);5.4函數(shù)指針作函數(shù)參數(shù)7.5.17.5.27.5.37.5.495問題:有兩個整數(shù)a和b,由用戶輸入1,2或3。如輸入1,程序就給出a和b中大者,輸入2,就給出a和b中小者,輸入3,則求a與b之和。

5.4函數(shù)指針作函數(shù)參數(shù)7.5.17.5.27.5.37.5.496#include<stdio.h>intmain(){intfun(intx,inty,int(*p)(int,int));intmax(int,int);intmin(int,int);intadd(int,int);inta=34,b=-21,n;printf("pleasechoose1,2or3:");scanf(“%d”,&n);if(n==1)fun(a,b,max);elseif(n==2)fun(a,b,min);elseif(n==3)fun(a,b,add);return0;}//fun函數(shù)聲明5.4函數(shù)指針作函數(shù)參數(shù)7.5.17.5.27.5.37.5.497intfun(intx,inty,int(*p)(int,int)){intresult;result=(*p)(x,y);printf(“%d\n”,result);}

intmax(intx,inty){intz;if(x>y)z=x;elsez=y;printf("max=");return(z);}輸入的選項為1時相當于max(x,y)輸入的選項為2時相當于min(x,y)輸入的選項為3時相當于add(x,y)5.4函數(shù)指針作函數(shù)參數(shù)7.5.17.5.27.5.37.5.498intmin(intx,inty){intz;if(x<y)z=x;elsez=y;printf("min=");return(z);}

intadd(intx,inty){intz;z=x+y;printf("sum=");return(z);}5.4函數(shù)指針作函數(shù)參數(shù)7.5.17.5.27.5.37.5.499運行結(jié)果:5.4函數(shù)指針作函數(shù)參數(shù)7.5.17.5.27.5.37.5.4返回指針值的函數(shù)06100定義返回指針值的函數(shù)的一般形式為

類型名*函數(shù)名(參數(shù)表列);101定義預(yù)警探索實戰(zhàn)7.6返回函數(shù)值指針的定義102注意:“*a”兩側(cè)沒有括號。括號“()”的優(yōu)先級高于“*”,所以a先與括號里的內(nèi)容結(jié)合。

函數(shù)前面的“*”表示此函數(shù)是指針型函數(shù)?!癷nt”表示返回的指針指向整型變量。例如int

*a(int

x,int

y);定義預(yù)警7.6返回函數(shù)值指針的定義探索實戰(zhàn)103問題:a個學生,每個學生有b門課程的成績。要求在用戶輸入學生序號以后,能輸出該學生的全部成績。用指針函數(shù)實現(xiàn)。7.6返回函數(shù)值指針的定義定義預(yù)警探索實戰(zhàn)1047.6返回函數(shù)值指針的定義定義預(yù)警探索演練105解題思路:定義二維數(shù)組score存放成績定義輸出某學生全部成績的函數(shù)search,它是返回指針的函數(shù),形參是行指針和整型主函數(shù)將score和要找的學號k傳遞給形參函數(shù)的返回值是&score[k][0](k號學生的序號為0的課程地址)在主函數(shù)中輸出該生的全部成績7.6返回函數(shù)值指針的定義定義預(yù)警探索實戰(zhàn)106#include<stdio.h>intmain(){floatscore[][4]={{60,70,70,90},{56,79,67,77},{34,77,90,66}};float*search(float(*pointer)[4],intn);float*p;inti,k;scanf(“%d”,&k);printf("ThescoresofNo.%dare:\n",k);p=search(score,k);

//返回k號學生課程首地址607070905679677734779066pointerpointer+1score數(shù)組7.6返回函數(shù)值指針的定義定義預(yù)警探索實戰(zhàn)107for(i=0;i<4;i++)printf(“%7.5.2f\t”,*(p+i));printf("\n");return0;}float*search(float(*pointer)[4],intn){float*pt;pt=*(pointer+n);return(pt);}//pt的值是&score[k][0]如果改成“pt=(*pointer+n);”,運行結(jié)果會是一樣的嗎?7.6返回函數(shù)值指針的定義定義預(yù)警探索實戰(zhàn)108運行結(jié)果:7.6返回函數(shù)值指針的定義定義預(yù)警探索實戰(zhàn)指針數(shù)組和多重指針071097.7.17.7.27.7.3110定義一維指針數(shù)組的一般形式為

類型名*數(shù)組名[數(shù)組長度];例如:int*p[4];類型名中包括符號“*”,如int*是表示指向整型數(shù)據(jù)的指針類型。7.1什么是指針數(shù)組111指針數(shù)組:一個數(shù)組的元素均為指針類型數(shù)據(jù),也就是說,指針數(shù)組中的每一個元素都存放一個地址,相當于一個指針變量。(比較適用于指向若干個字符串)注意:”int*p[4];”是一維指針數(shù)組的一般形式?!眎nt(*p)[4];”是一維數(shù)組的指針變量。7.7.17.7.27.7.37.1什么是指針數(shù)組112問題:將若干字符串按字母順序(由小到大)輸出。解題思路:定義一個指針數(shù)組,用各字符串對它進行初始化,然后用選擇法排序,但不是移動字符串,而是改變指針數(shù)組的各元素的指向。7.7.17.7.27.7.37.1什么是指針數(shù)組113#include<stdio.h>#include<string.h>intmain(){voidsort(char*name[],intn);voidprint(char*name[],intn);char*name[]={“Follow”,“Great”,“FORTRAN”,“Computer”};intn=4;sort(name,n);print(name,n);return0;}Follow\0Great\0FORTRAN\0Computer\07.7.17.7.27.7.37.1什么是指針數(shù)組114voidsort(char*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++)

{k=i;for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0)k=j;if(k!=i)

{temp=name[i];name[i]=name[k];

name[k]=temp;}}

}i=0時執(zhí)行后k變?yōu)?7.7.17.7.27.7.37.1什么是指針數(shù)組115Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]7.7.17.7.27.7.37.1什么是指針數(shù)組116voidsort(char*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++)

{k=i;for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0)k=j;if(k!=i)

{temp=name[i];name[i]=name[k];

name[k]=temp;}}

}7.7.17.7.27.7.37.1什么是指針數(shù)組117Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]7.7.17.7.27.7.37.1什么是指針數(shù)組118voidsort(char*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++)

{k=i;for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0)k=j;if(k!=i)

{temp=name[i];name[i]=name[k];

name[k]=temp;}}

}i=1時執(zhí)行后k變?yōu)?7.7.17.7.27.7.37.1什么是指針數(shù)組119voidsort(char*name[],intn)……if(k!=i)

{temp=name[i];name[i]=name[k];

name[k]=temp;}}

}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]7.7.17.7.27.7.37.1什么是指針數(shù)組120voidsort(char*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++)

{k=i;for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0)k=j;if(k!=i)

{temp=name[i];name[i]=name[k];

name[k]=temp;}}

}i=2時執(zhí)行后k變?yōu)?7.7.17.7.27.7.37.1什么是指針數(shù)組121voidsort(char*name[],intn)……if(k!=i)

{temp=name[i];name[i]=name[k];

name[k]=temp;}}

}Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]7.7.17.7.27.7.37.1什么是指針數(shù)組122voidprint(char*name[],intn){inti;for(i=0;i<n;i++)printf(“%s\n”,name[i]);}運行結(jié)果:7.7.17.7.27.7.37.1什么是指針數(shù)組數(shù)組名name代表該指針數(shù)組的首元素地址。name的每一個元素是一個指針型變量。指向指針型數(shù)據(jù)的指針變量,簡稱為指向指針的指針。name+i是name[i]的地址。name+i也是指向指針的指針。123Follow\0Great\0FORTRAN\0Computer\0name[0]name[1]name[2]name[3]namepName數(shù)組字符串7.2指向指針數(shù)據(jù)的指針7.7.17.7.27.7.3124問題:有一個指針數(shù)組,其元素分別指向一個整型數(shù)組的元素,用指向指針數(shù)據(jù)的指針變量,輸出整型數(shù)組各元素的值。7.2指向指針數(shù)據(jù)的指針7.7.17.7.27.7.31257.2指向指針數(shù)據(jù)的指針7.7.17.7.27.7.3126#include<stdio.h>intmain(){inta[5]={1,3,5,7,9};int*num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};int**p,i;p=num;

&a[0]&a[1]&a[2]&a[3]&a[4]p13579//p是指向指針型數(shù)據(jù)的指針變量7.2指向指針數(shù)據(jù)的指針7.7.17.7.27.7.3127for(i=0;i<5;i++){printf("%d",**p);p++;}printf("\n");return0;}運行結(jié)果:7.2指向指針數(shù)據(jù)的指針7.7.17.7.27.7.3128程序分析:開始時p的值是&num[0],*p是num[0]的值,即&a[0],*(*p)是a[0]的值。因此第1個輸出的是a[0]的值1。然后執(zhí)行p++,p就指向num[1],再輸出**p,就是a[2]的值3了。定義指針變量P指針型元素num[0]整型元素a[0]7.2指向指針數(shù)據(jù)的指針7.7.17.7.27.7.3129main函數(shù)的第一行的一般形式(無參數(shù)):

intmain()或intmain(void)括號中是空的或有“void”,表示main函數(shù)沒有參數(shù),調(diào)用main函數(shù)時不必給出實參。這是一般程序常采用的形式。7.2指向指針數(shù)據(jù)的指針7.7.17.7.27.7.3130有參數(shù)的main函數(shù):

intmain(intargc,char*argv[])argc(參數(shù)個數(shù))和argv(參數(shù)向量)就是main函數(shù)的形參,它們是程序的“命令行參數(shù)”。argv是*char指針數(shù)組,數(shù)組中每一個元素(其值為指針)指向命令行中的一個字符串。7.3指針數(shù)組做main的形參7.7.17.7.27.7.3131通常main函數(shù)和其他函數(shù)組成一個文件模塊,有一個文件名。用戶執(zhí)行這個可執(zhí)行文件,操作系統(tǒng)就調(diào)用main函數(shù),然后由main函數(shù)調(diào)用其他函數(shù),從而完成程序的功能。對這個文件進行編譯和連接,得到可執(zhí)行文件(后綴為.exe)。7.3指針數(shù)組做main的形參7.7.17.7.27.7.3132main函數(shù)的形參是從哪里傳遞給它們的呢?

答:顯然形參的值不可能在程序中得到。main函數(shù)是操作系統(tǒng)調(diào)用的,實參只能由操作系統(tǒng)給出。在操作系統(tǒng)狀態(tài)下,實參是和執(zhí)行文件的命令一起給出。7.3指針數(shù)組做main的形參7.7.17.7.27.7.3133命令行的一般形式:命令名參數(shù)1參數(shù)2……參數(shù)n命令名是可執(zhí)行文件名(包含main函數(shù))例如:file1ChinaBeijingfile1為可執(zhí)行文件名,China和Beijing是調(diào)用main函數(shù)的實參。7.3指針數(shù)組做main的形參7.7.17.7.27.7.3134命令行的參數(shù)均是字符串,這些字符串的首地址構(gòu)成一個指針數(shù)組。argv[0]argv[1]argv[2]file1\0Beijing\0China\0argv7.3指針數(shù)組做main的形參7.7.17.7.27.7.3135#include<stdio.h>intmain(intargc,char*argv[]){while(argc>1){++argv;

printf(“%s\n”,*argv);--argc;}return0;}在VC++環(huán)境下編譯、連接后,“工程”—“設(shè)置”—“調(diào)試”—“程序變量”中輸入“ChinaBeijing”,再運行就可得到結(jié)果7.3指針數(shù)組做main的形參7.7.17.7.27.7.3動態(tài)存儲分配081367.8.17.8.27.8.31378.1什么是內(nèi)存的動態(tài)分配非靜態(tài)的局部變量是分配在內(nèi)存中的動態(tài)存儲區(qū)的,這個存儲區(qū)是一個稱為棧的區(qū)域。C語言還允許建立內(nèi)存動態(tài)分配區(qū)域,以存放一些臨時用的數(shù)據(jù),這些數(shù)據(jù)需要時隨時開辟,不需要時隨時釋放。這些數(shù)據(jù)是臨時存放在一個特別的自由存儲區(qū),稱為堆區(qū)。138對內(nèi)存的動態(tài)分配是通過系統(tǒng)提供的庫函數(shù)來實現(xiàn)的,主要有malloc,calloc,free,realloc這4個函數(shù)。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.3139其作用是在內(nèi)存的動態(tài)存儲區(qū)中分配一個長度為size的連續(xù)空間。函數(shù)的值是所分配區(qū)域的第一個字節(jié)的地址,或者說,此函數(shù)是一個指針型函數(shù),返回的指針指向該分配域的開頭位置。1.malloc函數(shù)原型為void*malloc(unsignedintsize);8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.3140例如:malloc(100);開辟100字節(jié)的臨時分配域,函數(shù)值為其第一個字節(jié)的地址。注意:指針的基類型為void,即不指向任何類型的數(shù)據(jù),只提供一個地址。如果此函數(shù)未能成功地執(zhí)行(例如內(nèi)存空間不足),則返回空指針(NULL)。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.31412.calloc函數(shù)原型為

void*calloc(unsignedn,unsignedsize);其作用是在內(nèi)存的動態(tài)存儲區(qū)中分配n個長度為size的連續(xù)空間,這個空間一般比較大,足以保存一個數(shù)組。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.3142

例如;p=calloc(50,4);開辟50×4個字節(jié)的臨時分配域,把起始地址賦給指針變量p。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.31433.free函數(shù)原型為

voidfree(void*p);其作用是釋放指針變量p所指向的動態(tài)空間,使這部分空間能重新被其他變量使用。p應(yīng)是最近一次調(diào)用calloc或malloc函數(shù)時得到的函數(shù)返回值。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.3144例如:free(p);釋放指針變量p所指向的已分配的動態(tài)空間。free函數(shù)無返回值。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.31454.realloc函數(shù)原型為void*realloc(void*p,unsignedintsize);如果已經(jīng)通過malloc函數(shù)或calloc函數(shù)獲得了動態(tài)空間,想改變其大小,可以用recalloc函數(shù)重新分配。用realloc函數(shù)將p所指向的動態(tài)空間的大小改變?yōu)閟ize。p的值不變。如果重分配不成功,返回NULL。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.3146例如:realloc(p,50);將p所指向的已分配的動態(tài)空間改為50字節(jié)。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.3147總結(jié):以上4個函數(shù)的聲明在stdlib.h頭文件中,在用到這些函數(shù)時應(yīng)當用“#include<stdlib.h>”指令把stdlib.h頭文件包含到程序文件中。將p所指向的已分配的動態(tài)空間改為50字節(jié)。8.2怎樣建立內(nèi)存的動態(tài)分配7.8.17.8.27.8.3148問題:建立動態(tài)數(shù)組,輸入5個學生的成績,另外用一個函數(shù)檢查其中有無

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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

提交評論