c語言可以用函數作為參數 c語言可以用函數作為參數嘛

c語言向函數傳遞函數作為參數

#include?stdio.h

我們提供的服務有:成都網站制作、網站建設、微信公眾號開發(fā)、網站優(yōu)化、網站認證、漢中ssl等。為上1000+企事業(yè)單位解決了網站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的漢中網站制作公司

//---子函數聲明---//?

int?func1();

int?func2(int?(*func1)());????????//形參為函數指針(即指向函數的指針)?

//---主函數---//?

int?main(){

printf("向函數二傳遞函數一,\n即函數一作為函數二的參數。\n");

printf("%d?",func1());

printf("%d\n",func2(func1));//注意函數名即為函數地址?。。。。?!?

}????????????????????????????????//實參為函數名func1或者func1,兩者等價,而非func1()?

//---子函數定義---//?

int?func1(){

return?1;

}

int?func2(int?(*func1)()){????????//形參為函數指針(即指向函數的指針)

return?func1()+1;

}

【C語言】函數作為函數參數

Question:在函數void function()中,需要將另外一個函數double input()的函數名作為參數。

typedef double (*P)(int);

Note:參數部分需要注意,函數input()所有的輸入參數類型都需要包含在內。

例如 double input(double u[5], int num, double x), 則在定義時寫作 typedef double (*P)(double*,int,double)。

此時,函數作為一種類型,可以直接被其他函數調用。

函數聲明中定義 void function(P input),調用function(input)即可。

也可以寫成

C語言中用函數做函數的形式參數的問題

※※※※※※※※※※※第一個問題的答復※※※※※※※※※※※※※※※

看明白了你的意思,

其實不知道你自己有沒有注意到,你所嘗試的方法,

如果用C語言來做的話,其實就是實現了C語言的部分面向對象的實現,

說是"部分"的原因是,這僅僅是實現了面向對象的“方法”。

如果想實現的話,準確的講,應該不是你所說的,將"函數"作為形參,

應該是將“函數指針”作為形參。

這個在回調(CallBack)函數設計時,使用的非常多,

簡單舉一個例子:

#include stdlib.h

#include stdio.h

int Do1()

{

return 0;

}

int Do2(int num)

{

printf("The num is: %d\n", num);

return 0;

}

void CallBack1(void (*ptr)())//指向函數的指針作函數參數

{

(*ptr)();

}

void CallBack2(int n, int (*ptr)())//指向函數的指針作函數參數,這里第一個參數是為指向函數的指針服務的,

{ //不能寫成void Caller2(int (*ptr)(int n)),這樣的定義語法錯誤。

(*ptr)(n);

return;

}

int main()

{

CallBack1(Do1); //相當于調用Do1();

CallBack2(50, Do2); //相當于調用Do2(50);

return 0;

}

※※※※※※※※※※※第一個問題的答復※※※※※※※※※※※※※※※

※※※※※※※※※※※補充問題的答復※※※※※※※※※※※※※※※

針對你的補充問題,解答如下:

這個是可變形參的實現,準確地說,不是通過數組實現的,而是通過棧實現的。

C語言中的printf,scanf就是最常見的可變形參函數,定義一個可變形參的函數很簡單,如void print(int n, ...) ,函數中對參數的處理主要是通過對棧進行操作,而c函數的實參都是自右向左壓入棧的. 主要的棧操作(都是宏)有va_list,va_start ,va_arg,va_end, 定義如下:

typedef char * va_list;

#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) ~(sizeof(int) - 1) )

#define va_start _crt_va_start

#define va_arg _crt_va_arg

#define va_end _crt_va_end

#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )

#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define _crt_va_end(ap) ( ap = (va_list)0 )

va_start(ap,v):主要是獲取可變參數列表的首地址,然后賦值給ap,近似ap=v+sizeof(v) (這里暫不考慮內存對齊和類型轉換)

va_arg(ap,t):取得返回類型t的可變參數值, 并使ap指向下一個參數: ap += sizeof(t),這里的t是可變參數的數據類型,如int,float之類

va_end(ap):給ap初始化

va_start(ap,v) va_arg(ap,t) va_end(ap)三者合用,保證程序的健壯性.

一個使用可變形參的簡單程序:

#include stdio.h

#include stdarg.h //包含va_list等定義

float sum( float first, ... ) //,...代表可變形參函數

{

float i=first,sum=0;

va_list maker; //va_list 類型數據可以保存函數的所有參數,做為一個列表一樣保存

va_start(maker,first); //設置列表的起始位置

while(i!=-1.0)

{

sum+=i;

i=va_arg(maker,float); //返回maker列表的當前值,并指向列表的下一個位置

}

return sum;

}

void main(void)

{

printf( "sum is: %f\n", sum( 2.0,8.0,8.5,-1.0 ) ); //函數調用

}

※※※※※※※※※※※補充問題的答復※※※※※※※※※※※※※※※

c語言中用函數做參數怎么用

數組元素就是下標變量,它與普通變量并無區(qū)別。 因此它作為函數實參使用與普通變量是完全相同的,在發(fā)生函數調用時,把作為實參的數組元素的值傳送給形參,實現單向的值傳送?!纠?-4】說明了這種情況。

【例8-7】判別一個整數數組中各元素的值,若大于0 則輸出該值,若小于等于0則輸出0值。編程如下:#include stdio.hvoid nzp(int v){ if(v0) printf("%d ",v); else printf("%d ",0);}int main(void){ int a[5],i; printf("input 5 numbers\n"); for(i=0;i5;i++){ scanf("%d",a[i]); nzp(a[i]); } return 0;}

本程序中首先定義一個無返回值函數nzp,并說明其形參v為整型變量。在函數體中根據v值輸出相應的結果。在main函數中用一個for語句輸入數組各元素,每輸入一個就以該元素作實參調用一次nzp函數,即把a[i]的值傳送給形參v,供nzp函數使用。

數組名作為函數參數

用數組名作函數參數與用數組元素作實參有幾點不同。

1) 用數組元素作實參時,只要數組類型和函數的形參變量的類型一致,那么作為下標變量的數組元素的類型也和函數形參變量的類型是一致的。因此,并不要求函數的形參也是下標變量。換句話說,對數組元素的處理是按普通變量對待的。用數組名作函數參數時,則要求形參和相對應的實參都必須是類型相同的數組,都必須有明確的數組說明。當形參和實參二者不一致時,即會發(fā)生錯誤。

2) 在普通變量或下標變量作函數參數時,形參變量和實參變量是由編譯系統(tǒng)分配的兩個不同的內存單元。在函數調用時發(fā)生的值傳送是把實參變量的值賦予形參變量。在用數組名作函數參數時,不是進行值的傳送,即不是把實參數組的每一個元素的值都賦予形參數組的各個元素。因為實際上形參數組并不存在,編譯系統(tǒng)不為形參數組分配內存。那么,數據的傳送是如何實現的呢?在我們曾介紹過,數組名就是數組的首地址。因此在數組名作函數參數時所進行的傳送只是地址的傳送,也就是說把實參數組的首地址賦予形參數組名。形參數組名取得該首地址之后,也就等于有了實在的數組。實際上是形參數組和實參數組為同一數組,共同擁有一段內存空間。

上圖說明了這種情形。圖中設a為實參數組,類型為整型。a占有以2000為首地址的一塊內存區(qū)。b為形參數組名。當發(fā)生函數調用時,進行地址傳送,把實參數組a的首地址傳送給形參數組名b,于是b也取得該地址2000。于是a,b兩數組共同占有以2000為首地址的一段連續(xù)內存單元。從圖中還可以看出a和b下標相同的元素實際上也占相同的兩個內存單元(整型數組每個元素占二字節(jié))。例如a[0]和b[0]都占用2000和2001單元,當然a[0]等于b[0]。類推則有a[i]等于b[i]。

【例8-8】數組a中存放了一個學生5門課程的成績,求平均成績。#include stdio.hfloat aver(float a[5]){ int i; float av,s=a[0]; for(i=1;i5;i++) s=s+a[i]; av=s/5; return av;}int main(void){ float sco[5],av; int i; printf("\ninput 5 scores:\n"); for(i=0;i5;i++) scanf("%f",sco[i]); av=aver(sco); printf("average score is %5.2f",av); return 0;}

本程序首先定義了一個實型函數aver,有一個形參為實型數組a,長度為5。在函數aver中,把各元素值相加求出平均值,返回給主函數。主函數main 中首先完成數組sco的輸入,然后以sco作為實參調用aver函數,函數返回值送av,最后輸出av值。 從運行情況可以看出,程序實現了所要求的功能。

3) 前面已經討論過,在變量作函數參數時,所進行的值傳送是單向的。即只能從實參傳向形參,不能從形參傳回實參。形參的初值和實參相同,而形參的值發(fā)生改變后,實參并不變化,兩者的終值是不同的。而當用數組名作函數參數時,情況則不同。由于實際上形參和實參為同一數組,因此當形參數組發(fā)生變化時,實參數組也隨之變化。當然這種情況不能理解為發(fā)生了“雙向”的值傳遞。但從實際情況來看,調用函數之后實參數組的值將由于形參數組值的變化而變化。為了說明這種情況,把【例5.4】改為【例5.6】的形式。

【例8-9】題目同【例8.7】。改用數組名作函數參數。#include stdio.hvoid nzp(int a[5]){ int i; printf("\nvalues of array a are:\n"); for(i=0;i5;i++){ if(a[i]0) a[i]=0; printf("%d ",a[i]); }}int main(void){ int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i5;i++) scanf("%d",b[i]); printf("initial values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); nzp(b); printf("\nlast values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); return 0;}

本程序中函數nzp的形參為整數組a,長度為5。主函數中實參數組b也為整型,長度也為5。在主函數中首先輸入數組b的值,然后輸出數組b的初始值。然后以數組名b為實參調用nzp函數。在nzp中,按要求把負值單元清0,并輸出形參數組a的值。 返回主函數之后,再次輸出數組b的值。從運行結果可以看出,數組b的初值和終值是不同的,數組b的終值和數組a是相同的。這說明實參形參為同一數組,它們的值同時得以改變。

用數組名作為函數參數時還應注意以下幾點:

①形參數組和實參數組的類型必須一致,否則將引起錯誤。

②形參數組和實參數組的長度可以不相同,因為在調用時,只傳送首地址而不檢查形參數組的長度。當形參數組的長度與實參數組不一致時,雖不至于出現語法錯誤(編譯能通過),但程序執(zhí)行結果將與實際不符,這是應予以注意的。

【例8.10】如把例8.9修改如下:#include stdio.hvoid nzp(int a[8]){ int i; printf("\nvalues of array aare:\n"); for(i=0;i8;i++){ if(a[i]0)a[i]=0; printf("%d ",a[i]); }}int main(void){ int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i5;i++) scanf("%d",b[i]); printf("initial values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); nzp(b); printf("\nlast values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); return 0;}

本程序與【例8.9】程序比,nzp函數的形參數組長度改為8,函數體中,for語句的循環(huán)條件也改為i8。因此,形參數組a和實參數組b的長度不一致。編譯能夠通過,但從結果看,數組a的元素a[5]、a[6]、a[7]顯然是無意義的。

③在函數形參表中,允許不給出形參數組的長度,或用一個變量來表示數組元素的個數。例如,可以寫為:

void nzp(int a[])

或寫為

void nzp( int a[], int n )

其中形參數組a沒有給出長度,而由n值動態(tài)地表示數組的長度。n的值由主調函數的實參進行傳送。由此,【例8-10】又可改為【例8-11】的形式。

【例8-11】復制純文本新窗口

#include stdio.hvoid nzp(int a[],int n){ int i; printf("\nvalues of array a are:\n"); for(i=0;in;i++){ if(a[i]0) a[i]=0; printf("%d ",a[i]); }}int main(void){ int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i5;i++) scanf("%d",b[i]); printf("initial values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); nzp(b,5); printf("\nlast values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); return 0;}

網站欄目:c語言可以用函數作為參數 c語言可以用函數作為參數嘛
分享地址:http://bm7419.com/article42/dohhiec.html

成都網站建設公司_創(chuàng)新互聯,為您提供網站營銷、品牌網站制作、、ChatGPT、全網營銷推廣服務器托管

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

網站優(yōu)化排名