函數指針告訴CPU下一步需要執(zhí)行哪里的代碼的指針, 一數組十分相像.
創(chuàng)新互聯是一家集網站建設,江北企業(yè)網站建設,江北品牌網站建設,網站定制,江北網站建設報價,網絡營銷,網絡優(yōu)化,江北網站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯網需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網站。
#include?stdio.h
void?function(int?i,?double?d)????//一個函數的聲明
{
printf("函數運行,?%d,?%lf\n",?i,?d);
}
void?AnotherFunction(int?i,?double?d)????//另外一個函數聲明
{
printf("又一個函數運行,?%d,?%lf\n",?i,?d);
}
int?main()
{
void?(*pFun)(int,?double);????//定義了一個函數指針
int?(*p)(int?,?double);????//用于調試的函數指針
pFun?=?function;????//讓這個函數指針指向第一個函數
pFun(10,?10.101);????//通過這個函數指針來調用第一個函數
pFun?=?AnotherFunction;????//讓這個函數指針指向第二個函數
pFun(20,?20.202);????//通過這個函數指針來調用第二個函數
//若將以下代碼取消注釋,?就會產生錯誤
/*
p?=?function;
p?=?AnotherFunction;
//原因很簡單,?因為p是必須指向一個返回值為int,?第一個參數為int,?第二個參數為double的函數,?但是在此代碼中定義的函數返回值是void
*/
//這個實驗中,?直接用函數名來賦值了,?是因為函數名其實就是這個函數的指針
//而在平常調用函數時,?都要加上(),?如:printf("");
//這里,?"()"就相當于'*'(就是取值運算符),?printf是函數指針,?就相當于是數組名,?即數組的首地址
return?0;
}
加個注釋吧:
/*
函數x
參數1:?類型?int?未標注形參
參數2:?類型?void(*)(int)?形參y
返回值:?類型?void(*)(int)
*/
void(*x(int,void(*y)(int)))(int);
其中 “void(*)(int)" 代表接收一個int參數返回類型為void的函數指針類型,比如:
void?foo(int?i)
{
printf("%d",?i);
}
所以你可以這樣調用它:
...
void?(*pf)(int);
int?i?=?0;
pf?=?x(i,?foo);
...
函數指針是指向函數的指針變量。 因而“函數指針”本身首先應是指針變量,只不過該指針變量指向函數。這正如用指針變量可指向整型變量、字符型、數組一樣,這里是指向函數。
函數指針有兩個用途:調用函數和做函數的參數。
函數指針的聲明方法為:
返回值類型 ( *?指針變量名) ([形參列表]);
如:
int func(int x); /* 聲明一個函數 */
int (*f) (int x); /* 聲明一個函數指針 */
f=func; /* 將func函數的首地址賦給指針f */
或者使用下面的方法將函數地址賦給函數指針:
f = func;
賦值時函數func不帶括號,也不帶參數,由于func代表函數的首地址,因此經過賦值以后,指針f就指向函數func(x)的代碼的首地址。
下面的程序說明了函數指針調用函數的方法:
#includestdio.h
int?max(int?x,int?y){return?(xy??x:y);}
int?main()
{
int?(*ptr)(int,?int);
int?a,?b,?c;
ptr?=?max;
scanf("%d%d",?a,?b);
c?=?(*ptr)(a,b);
printf("a=%d,?b=%d,?max=%d",?a,?b,?c);
return?0;
}
char *match (char*s,char ch1,char ch2)
函數各部分的含義:
第一個char,一般是代表函數的返回值是一個字符。但是它后面有一個*,應該把char和*連起來看,就是char*了。
那么,第一個就是char*,代表函數的返回值是一個字符指針(地址)。
match是函數的名字。
括號內是函數的參數,多個參數用逗號分隔。本例共有3個參數:char*s,char ch1,char ch2,第一個是s,類型為char*型(字符指針型),后兩個ch1、ch2都是char型(字符型)。
到這兒,你就知道去掉*match前的*為什么就不對了。
另外,括號里參數類型(如包含指針)跟函數返回值的類型無關。函數名前加不加*只與函數返回值的類型有關。
函數在內存中有一個物理位置,而這個位置是可以賦給一個指針的。一零點函數的地址就是該函數的入口點。因此,函數指針可被用來調用一個函數。函數的地址是用不帶任何括號或參數的函數名來得到的。(這很類似于數組地址的得到方法,即,在只有數組名而無下標是就得到數組地址。)
怎樣說明一個函數指針變量呢 ?
為了說明一個變量 fn_pointer 的類型是"返回值為 int 的函數指針", 你可以使用下面的說明語句:
int (*fn_pointer) ();
為了讓編譯器能正確地解釋這句語句, *fn_pointer 必須用括號圍起來。若漏了這對括號, 則:
int *fn_pointer ();
的意思完全不同了。fn_pointer 將是一個函數名, 其返回值為 int 類型的指針。
2:函數指針變量
在C語言中規(guī)定,一個函數總是占用一段連續(xù)的內存區(qū), 而函數名就是該函數所占內存區(qū)的首地址。 我們可以把函數的這個首地址 ( 或稱入口地址 ) 賦予一個指針變量, 使該指針變量指向該函數。然后通過指針變量就可以找到并調用這個函數。我們把這種指向函數的指針變量稱為 " 函數指針變量 " 。
函數指針變量定義的一般形式為:
類型說明符 (* 指針變量名 )();
其中 " 類型說明符 " 表示被指函數的返回值的類型。 "(* 指針變量名 )" 表示 "*" 后面的變量是定義的指針變量。 最后的空括號表示指針變量所指的是一個函數。
例如: int (*pf)();
表示 pf 是一個指向函數入口的指針變量,該函數的返回值 ( 函數值 ) 是整型。
下面通過例子來說明用指針形式實現對函數調用的方法。
int max(int a,int b)
{
if(ab)return a;
else return b;
}
main()
{
int max(int a,int b);
int(*pmax)();
int x,y,z;
pmax=max;
printf("input two numbers:/n");
scanf("%d%d",x,y);
z=(*pmax)(x,y);
printf("maxmum=%d",z);
}
從上述程序可以看出用,函數指針變量形式調用函數的步驟如下:
1. 先定義函數指針變量,如后一程序中第 9 行 int (*pmax)(); 定義 pmax 為函數指針變量。
2. 把被調函數的入口地址 ( 函數名 ) 賦予該函數指針變量,如程序中第 11 行 pmax=max;
3. 用函數指針變量形式調用函數,如程序第 14 行 z=(*pmax)(x,y); 調用函數的一般形式為: (* 指針變量名 ) ( 實參表 ) 使用函數指針變量還應注意以下兩點:
a. 函數指針變量不能進行算術運算,這是與數組指針變量不同的。數組指針變量加減一個整數可使指針移動指向后面或前面的數組元素,而函數指針的移動是毫無意義的。
b. 函數調用中 "(* 指針變量名 )" 的兩邊的括號不可少,其中的 * 不應該理解為求值運算,在此處它只是一種表示符號。
3:指針型函數
前面我們介紹過,所謂函數類型是指函數返回值的類型。 在C語言中允許一個函數的返回值是一個指針 ( 即地址 ) ,這種返回指針值的函數稱為指針型函數。
定義指針型函數的一般形式為:
類型說明符 * 函數名 ( 形參表 )
{
…… /* 函數體 */
}
其中函數名之前加了 "*" 號表明這是一個指針型函數,即返回值是一個指針。類型說明符表示了返回的指針值所指向的數據類型。
如:
int *ap(int x,int y)
{
…… /* 函數體 */
}
表示 ap 是一個返回指針值的指針型函數, 它返回的指針指向一個整型變量。下例中定義了一個指針型函數 day_name ,它的返回值指向一個字符串。該函數中定義了一個靜態(tài)指針數組 name 。 name 數組初始化賦值為八個字符串,分別表示各個星期名及出錯提示。形參 n 表示與星期名所對應的整數。在主函數中, 把輸入的整數 i 作為實參, 在 printf 語句中調用 day_name 函數并把 i 值傳送給形參 n 。 day_name 函數中的 return 語句包含一個條件表達式, n 值若大于 7 或小于 1 則把 name[0] 指針返回主函數輸出出錯提示字符串 "Illegal day" 。否則返回主函數輸出對應的星期名。主函數中的第 7 行是個條件語句,其語義是,如輸入為負數 (i0) 則中止程序運行退出程序。 exit 是一個庫函數, exit(1) 表示發(fā)生錯誤后退出程序, exit(0) 表示正常退出。
應該特別注意的是函數指針變量和指針型函數這兩者在寫法和意義上的區(qū)別。如 int(*p)() 和 int *p() 是兩個完全不同的量。 int(*p)() 是一個變量說明,說明 p 是一個指向函數入口的指針變量,該函數的返回值是整型量, (*p) 的兩邊的括號不能少。
int *p() 則不是變量說明而是函數說明,說明 p 是一個指針型函數,其返回值是一個指向整型量的指針,*p 兩邊沒有括號。作為函數說明, 在括號內最好寫入形式參數,這樣便于與變量說明區(qū)別。 對于指針型函數定義,int *p() 只是函數頭部分,一般還應該有函數體部分。
main()
{
int i;
char *day_name(int n);
printf("input Day No:/n");
scanf("%d",i);
if(i0) exit(1);
printf("Day No:%2d--%s/n",i,day_name(i));
}
char *day_n
ame(int n)
{
static char *name[]={ "Illegal day",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"};
return((n1||n7) ? name[0] : name[n]);
}
本程序是通過指針函數,輸入一個 1 ~ 7 之間的整數, 輸出對應的星期名。指針數組的說明與使用一個數組的元素值為指針則是指針數組。指針數組是一組有序的指針的集合。指針數組的所有元素都必須是具有相同存儲類型和指向相同數據類型的指針變量。
指針數組說明的一般形式為: 類型說明符 * 數組名 [ 數組長度 ]
其中類型說明符為指針值所指向的變量的類型。例如: int *pa[3] 表示 pa 是一個指針數組,它有三個數組元素, 每個元素值都是一個指針,指向整型變量。通??捎靡粋€指針數組來指向一個二維數組。 指針數組中的每個元素被賦予二維數組每一行的首地址,因此也可理解為指向一個一維數組。圖 6—6 表示了這種關系。
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *pa[3]={a[0],a[1],a[2]};
int *p=a[0];
main()
{
int i;
for(i=0;i3;i++)
printf("%d,%d,%d/n",a[i][2-i],*a[i],*(*(a+i)+i));
for(i=0;i3;i++)
printf("%d,%d,%d/n",*pa[i],p[i],*(p+i));
}
本例程序中, pa 是一個指針數組,三個元素分別指向二維數組 a 的各行。然后用循環(huán)語句輸出指定的數組元素。其中 *a[i] 表示 i 行 0 列元素值; *(*(a+i)+i) 表示 i 行 i 列的元素值; *pa[i] 表示 i 行 0 列元素值;由于 p 與 a[0] 相同,故 p[i] 表示 0 行 i 列的值; *(p+i) 表示 0 行 i 列的值。讀者可仔細領會元素值的各種不同的表示方法。 應該注意指針數組和二維數組指針變量的區(qū)別。 這兩者雖然都可用來表示二維數組,但是其表示方法和意義是不同的
/*
函數指針,關鍵是后面兩個字“指針”,顧名思義,是一個指向函數的指針
原理:函數在創(chuàng)建好了后,函數的代碼會在內存中占有個位置,這時我們創(chuàng)造一個指針來指向這個地址,這個指針就叫函數指針
函數指針不可以移動,想要移動指針的位置來指向函數的下一個指令的想法是錯誤的
函數指針的要求,
1,首先這個指針,要和函數的返回類型一樣
2,指針的*和名字,要用小括號括起來//不括起來就是指針函數了,意思就變成,函數返回一個指針了
3,最右邊的小括號里形參位置的類型,形參的個數,也要和函數定義時的形參一致,只要類型,不要形參名即可,
但是加上形參名也可以,沒毛病,看上去也更清晰
*/
#include
void swapchar(char *a, char *b)
{
char t;
t = *a;
*a = *b;
*b = t;
}
void swapchar2(char * a2, char * b2)
{
printf("this is swapchar2");
}
int main(void)
{
char chf = 'a', chg = 'j';
void(*p)(char * a, char * b);//定義函數指針、形參名字a、b可有可無,但有的話看上去更清晰,只要函數定義的類型、參數類型、以及參數個數,與這個指針一致,那么這個指針p,就可以指向它
p = swapchar;//p指針接管swapchar函數,只要給函數名字,就可以給過去了
printf("chf=%c,chg=%c ", chf, chg);
p(chf, chg);
printf("chf=%c,chg=%c ", chf, chg);
p = swapchar2;//這里把swapchar2函數的地址,給了p,這時p從swapchar地址,轉移到了swapchar2這里。
p(chf,chg);
return 0;
}
網頁題目:c語言函數指針ppt c語言函數指針賦值
URL鏈接:http://vcdvsql.cn/article2/heheoc.html
成都網站建設公司_創(chuàng)新互聯,為您提供網站設計、定制網站、營銷型網站建設、關鍵詞優(yōu)化、網頁設計公司、網站制作
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯