日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

C语言函数指针的应用——自制谐波分析软件

發(fā)布時(shí)間:2025/3/11 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言函数指针的应用——自制谐波分析软件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 函數(shù)指針簡(jiǎn)介
  • 格式介紹
  • 顏色頭文件
  • 計(jì)算機(jī)仿真
    • 使用說(shuō)明
    • 完整代碼
    • 部分效果圖

函數(shù)指針簡(jiǎn)介

如果在一個(gè)大型C語(yǔ)言程序中要反復(fù)調(diào)用函數(shù),而調(diào)用的函數(shù)又不明確時(shí),函數(shù)指針就是一個(gè)非常有用的東西。如果你的函數(shù)體內(nèi)可以傳遞不同的函數(shù),那就非得用函數(shù)指針實(shí)現(xiàn)不可。下面我就用一個(gè)例子給大家分享一下C語(yǔ)言函數(shù)指針的妙用。

格式介紹

格式為:【基類型】(*function)([參數(shù)表列])
C語(yǔ)言函數(shù)指針就是一個(gè)指向函數(shù)地址的指針,它和普通的指針一樣也具有基類型,例如int *p,double *q,void *malloc與普通指針不同的是,它指向的不是特定類型的變量,而是函數(shù)地址,因此它后面有函數(shù)的參數(shù)表列。使用的時(shí)候需要注意,由于指針運(yùn)算符比括號(hào)運(yùn)算符的優(yōu)先級(jí)低,因此需要把(*function)括起來(lái)(否則就是返回指針的函數(shù))。C語(yǔ)言的語(yǔ)法比較復(fù)雜,舉一個(gè)函數(shù)指針的例子:

#include <stdio.h> #include <stdbool.h> int max(int a,int b);//最大值函數(shù) int min(int a,int b);//最小值函數(shù) int main() {int a,b;int (*p)(int,int);//函數(shù)指針pbool choice;char c[4];//字符串printf("Please enter two integer(separate by space): ");scanf("%d%d",&a,&b); printf("Please choose a function(0: max,1: min): ");scanf("%d%d",&choice);if(choice){p=min;c="min"}else {p=max;c="max"};//讓函數(shù)指針指向選擇的函數(shù)(地址)printf("%s=%d",c,p(a,b));//完成選擇函數(shù)的輸出return 0; }

函數(shù)指針主要有兩種使用方法:

  • 用函數(shù)指針指向某個(gè)函數(shù)做選擇(類似于上述的例子)
  • 當(dāng)做函數(shù)的參數(shù)傳遞(類似于下面的代碼),使程序模塊化更強(qiáng),耦合性更弱當(dāng)做函數(shù)的參數(shù)傳遞,使程序模塊化更強(qiáng),耦合性更弱
  • 下面是我編寫的一個(gè)計(jì)算一個(gè)指定方波的程序,里面的雙線性積分函數(shù)對(duì)每一次諧波變量(int n)都一個(gè)返回諧波分量double amplify,在這里用到了函數(shù)指針,傳遞一個(gè)方波的函數(shù)給這個(gè)積分函數(shù),如果以后這個(gè)函數(shù)不是方波而是其他函數(shù),增添和修改代碼都會(huì)非常方便!
    在程序里面我指定的值是電力電子課程里面的三相全橋整流電路帶阻感性負(fù)載的變壓器二次側(cè)電流波形的方波(一周期脈動(dòng)6次的交流電平),方波應(yīng)該沒有2次和3次諧波,這樣只剩下了1次諧波和6k±1(k∈N*)次諧波,每次諧波含有率(和1次諧波的比值)為1/(6k±1),可以看到后面附圖里面確實(shí)非常準(zhǔn)確,1,0.2,0.14286,…分別是1,1/5,1/7,…!
    如果我們分析三相電壓型橋式逆變電路的Unn’中點(diǎn)電壓波形(一周期脈動(dòng)6次的交流方波信號(hào)),可以得出同樣的結(jié)果。為了讓輸出的諧波分析更加的美觀,我們讓諧波含有率低于1e-4的所有的次諧波都標(biāo)藍(lán),剩下的白色的才是真正含有的諧波,供我們進(jìn)行計(jì)算機(jī)仿真實(shí)驗(yàn)驗(yàn)證。

    顏色頭文件

    以下鏈接為C語(yǔ)言彩色打印字符的相關(guān)頭文件及其說(shuō)明:

    【博客鏈接】

    計(jì)算機(jī)仿真

    使用說(shuō)明

    在程序的開始界面輸入時(shí)刻表和對(duì)應(yīng)的電平表,輸入分析基頻以及最高的分析諧波次數(shù),程序即可進(jìn)入運(yùn)算狀態(tài)。由于使用的是CFT(連續(xù)傅里葉積分),可能計(jì)算會(huì)有點(diǎn)慢,大概3秒算10次諧波。如果諧波含有率很低會(huì)用藍(lán)色標(biāo)識(shí)出來(lái),其余的諧波用白色標(biāo)注,代表實(shí)質(zhì)有的諧波含量,方便大家發(fā)現(xiàn)規(guī)律。輸入時(shí)刻表列和電平表列的規(guī)則如下:
    如果一個(gè)方波的電平以-1和1兩個(gè)電平變化,并且周期為π,則輸入周期為π,改變電平的時(shí)刻表列為0(不包括2個(gè)端點(diǎn)),電平表列為-1 1.
    如果一個(gè)方波的電平以-1,0,1,0,-1,0,…變化,正負(fù)電平的持續(xù)時(shí)間是0電平的2倍,周期為π,則電平的時(shí)刻表列為-5π/12,-π/12,π/12,5π/12(不包括2個(gè)端點(diǎn)),電平表列為0 -1 0 1 0。
    由于輸入的時(shí)刻表列不包括兩個(gè)端點(diǎn),因此時(shí)刻表列總是比電平表列多一個(gè)數(shù)值,但是如果時(shí)刻表列加上2個(gè)端點(diǎn)時(shí)刻,正好形成和電平表列數(shù)目一樣多的時(shí)間段和電平表列相對(duì)應(yīng)。輸入規(guī)則就是這樣的。

    完整代碼

    //#include <stdio.h> //color.h已包括 #include <math.h> #include <ctype.h> #include <malloc.h> //#include <windows.h> //color.h已包括 #include "color.h" #define pi 3.14159265 double amplify(double (*function)(double x),int n);//雙線性積分函數(shù),參數(shù)為函數(shù)指針、上界、下界 double RMS(double (*function)(double x));//對(duì)一個(gè)函數(shù)在周期內(nèi)求有效值 double square_wave(double x); double period;//被分析方波的周期 double time[30]={0};//方波的時(shí)間時(shí)刻數(shù)組,首地址是從0附近的周期最左邊的坐標(biāo)開始的依次改變的電平處的值,只保留一個(gè)周期的 double level[30]={0};//方波的電平數(shù)組,表示與時(shí)間區(qū)別對(duì)應(yīng)的電平 int fund_f;//指定傅里葉分解時(shí)的基頻 int count=0;//統(tǒng)計(jì)輸入個(gè)數(shù) //以上為聲明 int main() {char t;//用于檢測(cè)字符是否數(shù)字,實(shí)現(xiàn)動(dòng)態(tài)輸入 int i=0;//掃描計(jì)數(shù)偏移量int Nc;//截止諧波次數(shù) double *AP=NULL;//用于存放幅值數(shù)組的指針 //以上為定義變量部分 printf("***對(duì)用戶定義的方波進(jìn)行傅里葉級(jí)數(shù)展開***\n請(qǐng)輸入方波的周期: ");scanf("%lf",&period);fflush(stdin);printf("請(qǐng)輸入方波的在(-T/2,T/2)周期改變電平的時(shí)間時(shí)刻(不含±T/2的時(shí)刻,用空格分隔):\n");while((t=getchar())!='\n'){if(isdigit(t)||t=='-')//浮點(diǎn)數(shù)都是以負(fù)號(hào)或者數(shù)字開頭的 {ungetc(t,stdin);scanf("%lf",time+i);//掃描的浮點(diǎn)數(shù)一次存入 count++;//統(tǒng)計(jì)輸入時(shí)間節(jié)點(diǎn)的個(gè)數(shù) i++; }} *(time+i+1)=period/2;printf("請(qǐng)輸入方波的在上述改變時(shí)間時(shí)刻對(duì)應(yīng)的電平值\n【說(shuō)明】第一個(gè)電平對(duì)應(yīng)(-T/2,t0),最后一個(gè)電平對(duì)應(yīng)(tn,T/2),用空格分隔:\n");fflush(stdin);//循環(huán)結(jié)束,刷新標(biāo)準(zhǔn)輸入口 i=0;//偏移量清零 while((t=getchar())!='\n'){if(isdigit(t)||t=='-')//浮點(diǎn)數(shù)都是以負(fù)號(hào)或者數(shù)字開頭的 {ungetc(t,stdin);scanf("%lf",level+i);//掃描的浮點(diǎn)數(shù)一次存入 i++;}} fflush(stdin);//循環(huán)結(jié)束,刷新標(biāo)準(zhǔn)輸入口 printf("請(qǐng)輸入傅里葉分解的基頻: ");scanf("%d",&fund_f);printf("請(qǐng)輸入分析的諧波最高次數(shù): ");scanf("%d",&Nc);AP=(double *)calloc(Nc,sizeof(double));if(AP==NULL){printf("\n\r意外錯(cuò)誤:內(nèi)存分配失敗!\n");return 1;}printf("\n\r動(dòng)態(tài)內(nèi)存分配成功!\n");for(i=0;i<=Nc;i++){AP[i]=amplify(square_wave,i);printf("\r正在計(jì)算中...%.2lf%%",100*(float)i/Nc);}printf("\n\r|諧波次數(shù):\t振幅\n");for(i=0;i<=Nc;i++){printf("|%d:\t%8.5lf",i,AP[i]);if((i+1)%5==0)printf("\n");}printf("\n\r|諧波含有率如下:\n");for(i=0;i<=Nc;i++){if(AP[i]/AP[1]<1e-4){setcolor(LIGHTBLUE);//無(wú)該次諧波的顯示為黃色 printf("|%d:\t%7.3lf%%",i,100*AP[i]/AP[1]);}else{setcolor(WHITE);//有該次諧波顯示為藍(lán)色 printf("|%d:\t%7.3lf%%",i,100*AP[i]/AP[1]); } if((i+1)%5==0)printf("\n");}setcolor(WHITE);//還原默認(rèn)色 printf("\n\rRMS=%7.4lf,Fundamental=%7.4lf",RMS(square_wave),AP[1]);system("pause");return 0; } //根據(jù)電平數(shù)組和時(shí)間間隔數(shù)組查找對(duì)應(yīng)時(shí)間的方波的電平 double square_wave(double x) {int i;for(i=0;i<count;i++){if(x<*(time+i))return *(level+i);}return *(level+count);//如果均不是,返回level數(shù)組的最后一個(gè)值,即[tn,T/2]的值 } double amplify(double (*function)(double x),int n) {double sin_integral=0,cos_integral=0;//積分值double x0,x1;//雙線性積分需要兩個(gè)變量迭代計(jì)算for(x1=-period/2;x1<period/2;x0=x1,x1+=1e-5){sin_integral+=0.5*1e-5*((*function)(x1)*sin(n*2*pi*fund_f*x1/period)+(*function)(x0)*sin(n*2*pi*fund_f*x0/period));cos_integral+=0.5*1e-5*((*function)(x1)*cos(n*2*pi*fund_f*x1/period)+(*function)(x0)*cos(n*2*pi*fund_f*x0/period));} return sqrt(pow(sin_integral,2)+pow(cos_integral,2))/period; } double RMS(double (*function)(double x)) {double integral=0;double x0,x1;//采用雙線性積分for(x1=-period/2;x1<period/2;x0=x1,x1+=1e-5){integral+=0.5*1e-5*(pow((*function)(x1),2)+pow((*function)(x0),2)); }return sqrt(integral/period); }

    部分效果圖


    希望本文對(duì)您有幫助,謝謝閱讀。

    總結(jié)

    以上是生活随笔為你收集整理的C语言函数指针的应用——自制谐波分析软件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。