Ⅰ c語言函數指針問題
typedef struct StateStruct {
void (*FuncPtr)( void * ptr ) f;
}SS;
//定義了一個新的類型,這個類型是個結構體,類型名是SS
//下面聲明一個SS類型的變數
SS s;
//s就是一個SS類型的變數
void (*FuncPtr)( void * ptr );
//是一個類型名,類型是FuncPtr,這是一個函數指針類型,這個函數指針類型是返回值是void,接受一個void*的指針地址的參數。
//一般使用typedef語法來用
typedef void (*FuncPtr)( void * ptr );
typedef struct StateStruct {
FuncPtr fp;
}SS;
void f(void *ptr)
{
}
//函數f就是一個funcPtr類型的函數。
//可以以下面的方法賦值:
s.fp = f;
const SS St_StateInit = { (void (*)(void *))State_Init };
//用下面的寫法會好看很多
const SS St_StateInit = { (FuncPtr)State_Init };
//這是用State_Init來初始化fp的值。
Ⅱ C語言指向函數指針問題
#include
<stdio.h>
void
main()
{
int
max(int
,int
);
int
(*p)(int
,int);
p=max;
//此處利用
p=max是正確的指向函數的指針的用法,p指向max的入口地址
//此處用*p=max得到相同結論,為什麼呢?因為你這樣賦值之後*p的內容就是max
//所以在執行(*p)(q,w)它時其實是執行的(max)(q,w),如果是p=max此時執行(*p)(q,w)是等價於執行max(q,w)。
int
q,w;
printf("please
input
the
two
numbers:\n");
scanf("%d%d",&q,&w);
printf("the
larger
number
is:%d",(*p)(q,w));
}
////////////////////////////////////
int
max(int
a,int
b)
{
if(a>b)
return
a;
else
return
b;
}
Ⅲ C語言中函數指針用法
函數在內存中有一個物理位置,而這個位置是可以賦給一個指針的。一零點函數的地址就是該函數的入口點。因此,函數指針可被用來調用一個函數。函數的地址是用不帶任何括弧或參數的函數名來得到的。(這很類似於數組地址的得到方法,即,在只有數組名而無下標是就得到數組地址。)
怎樣說明一個函數指針變數呢 ?
為了說明一個變數 fn_pointer 的類型是"返回值為 int 的函數指針", 你可以使用下面的說明語句:
int (*fn_pointer) ();
為了讓編譯器能正確地解釋這句語句, *fn_pointer 必須用括弧圍起來。若漏了這對括弧, 則:
int *fn_pointer ();
的意思完全不同了。fn_pointer 將是一個函數名, 其返回值為 int 類型的指針。
2:函數指針變數
在C語言中規定,一個函數總是佔用一段連續的內存區, 而函數名就是該函數所佔內存區的首地址。 我們可以把函數的這個首地址 ( 或稱入口地址 ) 賦予一個指針變數, 使該指針變數指向該函數。然後通過指針變數就可以找到並調用這個函數。我們把這種指向函數的指針變數稱為 " 函數指針變數 " 。
函數指針變數定義的一般形式為:
類型說明符 (* 指針變數名 )();
其中 " 類型說明符 " 表示被指函數的返回值的類型。 "(* 指針變數名 )" 表示 "*" 後面的變數是定義的指針變數。 最後的空括弧表示指針變數所指的是一個函數。
例如: int (*pf)();
表示 pf 是一個指向函數入口的指針變數,該函數的返回值 ( 函數值 ) 是整型。
下面通過例子來說明用指針形式實現對函數調用的方法。
int max(int a,int b)
{
if(a>b)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 ,它的返回值指向一個字元串。該函數中定義了一個靜態指針數組 name 。 name 數組初始化賦值為八個字元串,分別表示各個星期名及出錯提示。形參 n 表示與星期名所對應的整數。在主函數中, 把輸入的整數 i 作為實參, 在 printf 語句中調用 day_name 函數並把 i 值傳送給形參 n 。 day_name 函數中的 return 語句包含一個條件表達式, n 值若大於 7 或小於 1 則把 name[0] 指針返回主函數輸出出錯提示字元串 "Illegal day" 。否則返回主函數輸出對應的星期名。主函數中的第 7 行是個條件語句,其語義是,如輸入為負數 (i<0) 則中止程序運行退出程序。 exit 是一個庫函數, exit(1) 表示發生錯誤後退出程序, exit(0) 表示正常退出。
應該特別注意的是函數指針變數和指針型函數這兩者在寫法和意義上的區別。如 int(*p)() 和 int *p() 是兩個完全不同的量。 int(*p)() 是一個變數說明,說明 p 是一個指向函數入口的指針變數,該函數的返回值是整型量, (*p) 的兩邊的括弧不能少。
int *p() 則不是變數說明而是函數說明,說明 p 是一個指針型函數,其返回值是一個指向整型量的指針,*p 兩邊沒有括弧。作為函數說明, 在括弧內最好寫入形式參數,這樣便於與變數說明區別。 對於指針型函數定義,int *p() 只是函數頭部分,一般還應該有函數體部分。
main()
{
int i;
char *day_name(int n);
printf("input Day No:/n");
scanf("%d",&i);
if(i<0) 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((n<1||n>7) ? 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;i<3;i++)
printf("%d,%d,%d/n",a[i][2-i],*a[i],*(*(a+i)+i));
for(i=0;i<3;i++)
printf("%d,%d,%d/n",*pa[i],p[i],*(p+i));
}
本常式序中, pa 是一個指針數組,三個元素分別指向二維數組 a 的各行。然後用循環語句輸出指定的數組元素。其中 *a[i] 表示 i 行 0 列元素值; *(*(a+i)+i) 表示 i 行 i 列的元素值; *pa[i] 表示 i 行 0 列元素值;由於 p 與 a[0] 相同,故 p[i] 表示 0 行 i 列的值; *(p+i) 表示 0 行 i 列的值。讀者可仔細領會元素值的各種不同的表示方法。 應該注意指針數組和二維數組指針變數的區別。 這兩者雖然都可用來表示二維數組,但是其表示方法和意義是不同的
Ⅳ 求教c語言中的函數指針問題
PITE_RET (*PITE_TaskFunction)(PITE_MESSAGE *Msg); ==>
unsigned char (*PITE_TaskFunction)(PITE_MESSAGE *Msg);
上邊是函數指針聲明的一種:
type (*pointer)(parameter list);
pointer:為函數指針變數名 (這里是:PITE_TaskFunction)
type: 為指向函數的返回值類型 (這里是:unsigned char)
parameter list:為指向函數的參數類型 (這里是:PITE_MESSAGE *Msg)--參數是一個結構體類型的指針。
這樣拆開是不是明白一點了。
Ⅳ 關於C語言中指針函數的問題
不行, 原因是found函數已經聲明成返回一個int指針的函數了,如果不聲明p為指針則在p=founc(a,n)時會因為類型不匹配而報錯。兩種方法可以解決:1,直接省略掉變數p,在printf語句中直接用printf("%d", *found(a,n));來輸出結果;2,修改found函數為:<pre t="code" l="cpp">int found(int b[10], int n)
{
return b[n-1];
}則p可以直接聲明為int, 且賦值時用p=found(a,n); 輸出時用printf("%d", p);可以看到這樣改動的比較多。
Ⅵ c語言,函數里的指針問題
這個其實很好理解
只需要把%s,%c,%p放在一起看
首先%s是最常見的很好理解,就是告訴程序後面的變數是一個字元串,在C語言中也就是字元數組,類型是char*或者char[],換句話說,你告訴程序我會給你一個指針,你去讀這個指針指向的值。
然後%c是告訴程序後面的變數是個字元,類型是char,差別已經很明顯了,這時候你告訴程序我給你提供一個字元,你給我在%c處列印出來。然而你給的卻是一個指針,那程序就直接把你給的指針指向的地址本身當成字元列印出來了。但是一個地址肯定不止一個位元組,也就是說超過了char應該有的大小,這時候程序會直接忽略了超出大小的部分,只讀第一個位元組。
如果你同時使用%p,告訴程序,你會提供一個指針,直接把這個指針指向的地址給我列印出來。把輸出的地址最後兩位的16進制數查ascii表,換算成字元,你會發現,剛好就是前面%c列印出的字元。
Ⅶ C語言函數及指針問題.
這個理解起來其實很簡單
只要記住一點,實參和形參不在一個內存地址中就可以,改變形參不會改變實參的
但是有一個例外,就是在聲明子函數是,參數帶&,這表示實參形參公用一個內存地址
在調用x1函數時,i j會另外申請內存地址,那麼交換了ij,但是ab所在的內存地址的內容是不會改變的
調用x2時,傳遞過去的是ab的內存地址,並且在子函數中,交換了ab內存地址中的內容,那麼ab就交換了
這個主意兩點
1,交換了ab內存地址(也就是指針)中的內容,但是你看在子函數中,指針是沒有交換的,所以說傳遞過去的參數是沒有改變,只是改變了指向的地址中的內容
2,要是在子函數中聲明的c是指針,如果用c=i;i=j;j=c,那麼只是交換了指針,而指針指向的內容還是沒有改變,並且在主函數中,這兩個參數指針還是沒有改變。道理同第一個,因為實參和形參是占不同的內存地址,
Ⅷ 關於C語言指針函數的問題
char*connect(char*dst,char*src)
{
char*q,*p;
for(p=dst;*p;p++);//將p指針移動到dst數組的結束符0的位置
for(q=src;*q;q++,p++)//dst從結束符開始,src從首地址開始,一一對應傳值
*p=*q;
*p=0;
returndst;
}
Ⅸ c語言指向函數的指針問題
首先,這個代碼連編譯的過不了
單從你主函數的x=sub(p,q,3),我也不知道你那是q還是9。
忽略編程的角度,單從題目的大意,把你的q當做是9
x = sub(p,9,3) = funa(9,3) = 9+3 = 12;
x += sub(funb,8,3),x = x+funb(8,3) = 12 + (8-3) = 17
結果是17
Ⅹ 【求助】關於C語言中指向函數的指針的問題(高手進!)
/* 一 */
#include<stdio.h>
int f2(float c)
{
printf("%f\n",c);
}
void main()
{
int (*f)(); // 錯誤: 函數的形參是函數類型的一部分(返回值不是) 改成int (*f)(float);就好了。
float c=5;
printf("%f\n",c);
f=f2;
f(c);
getch();
}
/* main */ //修改後:(為什麼這個卻可以?)
/*
#include<stdio.h>
int f2(float *c)
{
printf("%f\n",*c);
}
void main()
{
int (*f)(); // 這其實也是個錯誤,只不過被另一個隱式規則所掩蓋,那就是形參的長度:
//指針的長度是C編譯器默認的整型的長度,但float不是。
float *c,a=5;
c=&a;
printf("%f\n",*c);
f=f2;
(*f)(c); // 此處,(*f)(c) 與 f(c)語法上完全等價。不同的是 (*f)(c)暴露了你是生手。
// 樓上的兩個回答也暴露了他們也是生手。不同的是,他們自以為不是。
getch();
}/* main */
樓主一定記住:
1. 函數的形參是函數類型的一部分,但返回值不是。
2.指針的類型必須完整。函數指針的類型信息包括入參的信息
3. 設f是函數指針,(*f)(c) 與 f(c)完全等價。但技術人員用後者。
原因 此時,操作符 () 與 []類似,已經解除引用。
(*f)(c) 的存在是編譯器設計者的寬容。
-------------------------------------------------------------------
附件:microsoft C++ 匯編結果,供比較:
// 匯編:原型為 int (*f)();時的調用:
; 33 : //int (*f)(float);
; 34 : int (*f)();
; 35 : float c=5;
mov DWORD PTR _c$[ebp], 1084227584 ; 40a00000H
; 36 : printf("%f\n",c);
fld DWORD PTR _c$[ebp]
sub esp, 8
fstp QWORD PTR [esp]
push OFFSET FLAT:??_C@_03FBAH@?$CFf?6?$AA@ ; `string'
call _printf
add esp, 12 ; 0000000cH
; 37 : f=f2;
mov DWORD PTR _f$[ebp], OFFSET FLAT:_f2
; 38 : f(c);
fld DWORD PTR _c$[ebp]
mov esi, esp
sub esp, 8
fstp QWORD PTR [esp]
call DWORD PTR _f$[ebp]
add esp, 8
cmp esi, esp
call __chkesp
// 匯編:原型為 int (*f)(float);時的調用:
; 33 : int (*f)(float);
; 34 : //int (*f)();
; 35 : float c=5;
mov DWORD PTR _c$[ebp], 1084227584 ; 40a00000H
; 36 : printf("%f\n",c);
fld DWORD PTR _c$[ebp]
sub esp, 8
fstp QWORD PTR [esp]
push OFFSET FLAT:??_C@_03FBAH@?$CFf?6?$AA@ ; `string'
call _printf
add esp, 12 ; 0000000cH
; 37 : f=f2;
mov DWORD PTR _f$[ebp], OFFSET FLAT:_f2
; 38 : f(c);
mov esi, esp
mov eax, DWORD PTR _c$[ebp]
push eax
call DWORD PTR _f$[ebp]
add esp, 4
cmp esi, esp
call __chkesp