前言:一篇好文章的誕生,需要你不斷地搜集資料、整理思路,本站小編為你收集了豐富的c語言函數(shù)主題范文,僅供參考,歡迎閱讀并收藏。
指導(dǎo)教師:__________ 成績:__________
實驗四 函數(shù)
一、 實驗?zāi)康?/p>
1、掌握函數(shù)定義、調(diào)用和聲明的方法
2、掌握實參和形參之間的傳遞方式
3、函數(shù)的嵌套調(diào)用
二、 實驗內(nèi)容
1、 寫一個函數(shù),將兩個字符串連接。(習(xí)題8.6)
2、 編寫一個函數(shù),由實參傳來一個字符串,統(tǒng)計此字符串中字母、數(shù)字、空格和其他字符的個數(shù),在主函數(shù)中輸入字符串以及輸出上述的結(jié)果。(習(xí)題8.9)
3、 請將實驗三中的實驗內(nèi)容三改正后,再改寫成函數(shù)形式(排序部分)。
物理實驗報告 ·化學(xué)實驗報告 ·生物實驗報告 ·實驗報告格式 ·實驗報告模板
關(guān)鍵詞 多態(tài)性;面向?qū)ο?;函?shù)重載;運算符重載
中圖分類號TP39 文獻(xiàn)標(biāo)識碼A 文章編號 1674-6708(2011)40-0196-02
0 引言
多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計的重要特征之一,它與封裝性和繼承性共同組成面向?qū)ο蟮某绦蛟O(shè)計的三大基本特征,在函數(shù)重載中,同一個函數(shù)名可對應(yīng)若干種不同的實現(xiàn),依據(jù)函數(shù)參數(shù)的類型、個數(shù)和順序來確定某個實現(xiàn)。在運算符重載中,同一個運算符對應(yīng)著很多種功能,這些功能是通過函數(shù)來定義的,依據(jù)操作數(shù)的類型來確定應(yīng)選運算符的功能。我們接觸的還有另一種是指同樣的消息被不同類的對象接受時產(chǎn)生完全不同的實現(xiàn),該情況大多產(chǎn)生在多類繼承中不同類中的相同說明的成員函數(shù)的多態(tài)行為。其中多態(tài)性分為專用多態(tài)和通用多態(tài),專用多態(tài)分為強(qiáng)制多態(tài)和重載多態(tài);通用多態(tài)分為參數(shù)多態(tài)和包含多態(tài)。其中重載是實現(xiàn)C++多態(tài)性的一種十分重要的機(jī)制,成為重載多態(tài),即為程序正文中相同作用域內(nèi)的同一個標(biāo)識符賦予不同的操作語義,實質(zhì)上就是實現(xiàn)了程序空間到代碼空間的一對多映射。
1 函數(shù)重載
簡單地說函數(shù)重載就是賦給同一個函數(shù)名多個含義。在我們學(xué)的C++中函數(shù)重載分為普通函數(shù)的重載和成員函數(shù)的重載,也就是說我們所學(xué)的函數(shù)重載可以以兩種不同的方式來實現(xiàn),就是我們所說的普通函數(shù)的重載和成員函數(shù)的重載。
1.1 普通函數(shù)的重載
例1:
#include
float min(float x,float y){return x>y?x:y;}//求2個浮點型小數(shù)的最小值
float min(float x,float y,float z) {return x>y?(x>z?x:z):(y>z?y:z);}
//求3個浮點型小數(shù)的最小值
void main( )
{
cout
}
運行的結(jié)果:1.2,3.2
上一例題中,兩個函數(shù)都是普通的函數(shù)重載,由于主函數(shù)中調(diào)用的兩個函數(shù)對應(yīng)的參數(shù)個數(shù)不同,所以通過形參和實參的結(jié)合,我們得到了運行的結(jié)果。
1.2 成員函數(shù)的重載
例2:
#include
class A
{
public:
A( ): a(0){cout
A(int x): a(x){cout
private:int a;
};
void main( )
{ A a1,a2(3); }
運行結(jié)果為: Default Constructing 0
Constructing 3
這是一個很常見的習(xí)題,該函數(shù)調(diào)用了構(gòu)造函數(shù)的兩種形式,有參和無參,對應(yīng)于主函數(shù)中帶有不同形式參數(shù)的函數(shù),我們得到不同的結(jié)果。
2 運算符重載
運算符重載就是就是賦予已有的運算符多重含義,即多種功能。C++語言中通過重新定義運算符,使它能夠用于特定類的對象執(zhí)行的特定的功能。一般情況下運算符重載有兩種形式,重載為類的成員函數(shù)和重載為有元函數(shù)兩種。
2.1 重載為類的成員函數(shù)
例1:
#include
class complex
{
Public:complex(){real=imag=0;}
complex(double r,double i){real=r;imag=I;}
complex operator +(const complex &c);
complex operator -(const complex &c);
friend void print(const complex &c);
Private:double real,imag;
};
inline complex complex::operator +(const complex &c)
{return complex (real+c.rael,imag+c.imag);}
inline complex complex::operator -(const complex &c)
{return complex (real-c.rael,imag-c.imag);}
void print (const complex &c);
{
if (c.imag
cout
else
cout
}
void main()
{
complex c1(2.0,3.0),c2(4.0,-2.0),c3;
c3=c1+c2;
print(c3);
cout
c3=c1-c2;
cout
print(c3);
}
執(zhí)行該程序的輸出結(jié)果:
c1+c2=6+1i;
c1-c2=-2+5i;
2.2 重載為有元函數(shù)
執(zhí)行的結(jié)果同例1,兩種運算符比較,我們知道單目運算符最好被重載為成員函數(shù),雙目運算符最好被重載為有元函數(shù)。
3 結(jié)論
以上我們總結(jié)了函數(shù)重載和運算符重載的區(qū)別和特點。眾所周知,重載是為了以不同的方式來實現(xiàn)函數(shù),我們?nèi)绻炀毜膽?yīng)用這門技術(shù),可以提高程序的運行效率和可讀性,通過學(xué)習(xí),使我們更透徹地理解了C++的多態(tài)性問題。
參考文獻(xiàn)
[1]譚浩強(qiáng).C語言程序設(shè)計[M].3版.北京:清華大學(xué)出版社,2005,8.
[關(guān)鍵詞]Java JNT C DLL
在現(xiàn)今的軟件開發(fā)領(lǐng)域中,Java以其跨平臺的優(yōu)勢得到大量的應(yīng)用,其代碼可以一次編譯多處執(zhí)行。但這種特性給Java帶來了一定的局限性,幸好Java提供了完備的C/C++語言接口,這樣我們可以利用C語言的強(qiáng)大功能實現(xiàn)Java難以實現(xiàn)的功能,在一定程序上消除Java的局限性和低效率。
一、創(chuàng)建DLL文件
使用某一種C/C++開發(fā)工具創(chuàng)建Dll文件,實現(xiàn)某一功能,供JAVA調(diào)用,例如本文在此使用Visual studio 2005創(chuàng)建一個名為testdll的動態(tài)庫文件。
二、使用JNI
JNI是Java Native Interface的縮寫,中文為JAVA本地調(diào)用。它允許Java代碼和其他語言寫的代碼進(jìn)行交互。
1.JAVA類
在JAVA程序中,首先需要在類中聲明所調(diào)用的庫名稱,如下:
static {
System.loadLibrary(“testdll”); //加載動態(tài)庫,testdll為DLL文件名稱
}
還需要對將要調(diào)用的方法做本地聲明,關(guān)鍵字為native。并且只需要聲明,而不需要具體實現(xiàn)。如下:
public native static void set(int i);
public native static int get();
然后編譯該JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就會生成C/C++的頭文件。
例如程序testdll.java,內(nèi)容為:
public class testdll { static { System.loadLibrary(“testdll”); } public native static int get(); public native static void set(int i); public static void main(String[] args) { testdll test = new testdll(); test.set(10); System.out.println(test.get()); } }
用javac testdll.java編譯它,會生成testdll.class。
再用javah testdll,則會在當(dāng)前目錄下生成testdll.h文件,這個文件需要被C/C++程序調(diào)用來生成所需的庫文件。
2.C/C++
創(chuàng)建C/C++項目需要增加的頭文件有jni.h、jni_md.h這兩個文件是JNI中必須的;還有就是增加testdll.h。
對于已生成的.h頭文件,C/C++所需要做的,就是把它的各個方法具體的實現(xiàn)。然后編譯連接成庫文件即可。再把庫文件拷貝到JAVA程序的路徑下面,就可以用JAVA調(diào)用C/C++所實現(xiàn)的功能了。
接上例子。我們先看一下testdll.h文件的內(nèi)容:
#include #ifndef _Included_testdll #define _Included_testdll #ifdef __cplusplus extern "C" { #endif JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass); JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint); #ifdef __cplusplus } #endif #endif
在具體實現(xiàn)的時候,我們只關(guān)心兩個函數(shù)原型 JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);和 JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);這里JNIEXPORT和JNICALL都是JNI的關(guān)鍵字,表示此函數(shù)是要被JNI調(diào)用的。而jint是以JNI為中介使JAVA的int類型與本地的int溝通的一種類型,我們可以視而不見,就當(dāng)做int使用。函數(shù)的名稱是JAVA_再加上java程序的package路徑再加函數(shù)名組成的。參數(shù)中,我們也只需要關(guān)心在JAVA程序中存在的參數(shù),至于JNIEnv*和jclass我們一般沒有必要去碰它。
下面我們用testdll.cpp文件具體實現(xiàn)這兩個函數(shù):#include "testdll.h" int i = 0; JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass) { return i; } JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j) { i = j+5; }
編譯連接成庫文件,這里就是testdll.dll。把testdll.dll拷貝到testdll.class的目錄下,java testdll運行它,就可以觀察到結(jié)果了。
三、總結(jié)
使用JNI可以在JAVA中調(diào)用其它語言編寫的代碼,在一定程度上消除JAVA的局限性和低效率。
參考文獻(xiàn):
【關(guān)鍵詞】C語言 函數(shù) 類比教學(xué)法
【基金項目】防災(zāi)科技學(xué)院重點教研項目2012A04;防災(zāi)科技學(xué)院第一批精品建設(shè)課程。
【中圖分類號】G42 【文獻(xiàn)標(biāo)識碼】A 【文章編號】2095-3089(2013)06-0165-02
形象類比法屬于講授教學(xué)方法的一種,即借助于兩類不同本質(zhì)事物之間的相似性,通過比較,形象地將一種已經(jīng)熟悉或掌握的特殊對象推移到另一種新的特殊對象上去的推理手段,也是教學(xué)中創(chuàng)設(shè)真實生動情景的有效工具之一。
C語言對于初學(xué)者而言,有一定的難度,學(xué)生在學(xué)習(xí)計算機(jī)方面存在比較大的弱點,思維邏輯能力不夠強(qiáng),空間視覺不夠敏感。書中涉及到的一些抽象的理論知識,學(xué)生理解起來很難。為了幫助學(xué)生更好的理解抽象理論知識,在教學(xué)過程中,恰當(dāng)?shù)牟捎靡恍╊惐葘嵗齺韼椭鷮W(xué)生理解并提高學(xué)習(xí)的興趣。
在C語言學(xué)習(xí)過程中,從前面簡單的結(jié)構(gòu)化思想轉(zhuǎn)化到函數(shù)的模塊化設(shè)計思想,因為知識的抽象性,學(xué)到函數(shù)這一章,很多同學(xué)反映學(xué)起來很困難,有一部分同學(xué)從這一章開始“知難而退”,放棄繼續(xù)學(xué)習(xí)C語言。結(jié)合自己的多年實踐教學(xué)經(jīng)驗,試從幾個形象的例子類比來闡述如果理解復(fù)雜抽象的函數(shù)理論概念。
一、函數(shù)的概念
模塊化編程是指將一個龐大的程序劃分為若干個功能獨立的模塊,對各個模塊進(jìn)行獨立開發(fā),每一個模塊用來實現(xiàn)一個特定的功能,然后再將這些模塊統(tǒng)一合并為一個完整的程序。模塊化編程使程序易于維護(hù)和提高程序段的利用率,這是C語言面向過程的編程方法,可以縮短開發(fā)周期,提高程序的可讀性和可維護(hù)性。模塊的功能,在C語言中,由函數(shù)完成。函數(shù)的工作原理:分而治之!一個C程序可由一個主函數(shù)main和若干個函數(shù)構(gòu)成。
一個C程序的執(zhí)行:從主函數(shù)開始,在main函數(shù)中調(diào)用其他函數(shù),其他函數(shù)也可以互相調(diào)用。主函數(shù)一般都很簡單,起到“驅(qū)動”的作用,把功能的實現(xiàn)都放在子函數(shù)里,一個子函數(shù)能做一件或者更多的事,可以說“主函數(shù)就是驅(qū)動程序,是用來驅(qū)動其它子程序(函數(shù)),更是整個完整程序的入口?!比绻阋M(jìn)入一個房子,你就必須先找到門,從門里才能進(jìn)到屋子里去。C語言的主函數(shù),就是你要運行的程序的“門”,不經(jīng)過它,你就進(jìn)不了房子。
music( )//音樂播放
{……}
movie( )//影視播放
{……}
online( )/*等等一序列子程序,這些子程序都需要main( )函數(shù)來驅(qū)動*/
{……}
void main( )
{
music( );
movie( );
online( );
}
程序模塊化,使程序開發(fā)更容易管理,函數(shù)把較大的任務(wù)分解成較小的任務(wù)。比如:以前作坊式的制衣流程:先紡紗織布,然后剪裁制衣,之后制作扣子縫制完成制衣。這些工作由一個家庭作坊獨立完成。類似于在C語言中由主函數(shù)完成所有的工作?,F(xiàn)在的制衣流程:專業(yè)的織布公司、專業(yè)的制衣公司、生產(chǎn)加工扣子、拉鏈等輔料的公司。每一個公司類似于一個獨立的“子函數(shù)”。
二、向函數(shù)傳遞值
如果函數(shù)的參數(shù)是基本類型變量和構(gòu)造類型變量,則傳遞值的拷貝。
例如制衣公司現(xiàn)在需要1萬條白色長30cm的銅拉鏈,他將把這些數(shù)值告訴加工輔料公司,加工輔料公司進(jìn)行加工生產(chǎn),即制衣公司“調(diào)用”加工輔料公司。這里的1萬條、白色、30cm及銅質(zhì)這四個信息屬于傳遞的“參數(shù)”。這些參數(shù)對于制衣公司來說屬于是“實參”,對于加工輔料公司來說屬于“形參”。參數(shù)相當(dāng)于公司之間的一份協(xié)議,它們的數(shù)據(jù)類型必須是一致的。制衣公司因為需求可以改變“實參”,例如改成加工2萬條白色長30cm的銅拉鏈,這時“實參”改變的時候,“形參”也跟著改變;但是,加工輔料的公司沒有自行改變制衣公司實參的權(quán)利,這就是函數(shù)的“形參”改變,“實參”不變的原則。
void Clothing_com( )//制衣公司
{
……
Accessories_com (1000,white,30,copper);//實參
……
}
void Accessories_com (int num,char color[10],float lenth,char quality[10])
//輔料公司,形參num:拉鏈數(shù)量;color:拉鏈顏色;lenth:拉鏈長度;quality:拉鏈質(zhì)地
{ …… }
void main( )
{
Clothing_com( );
}
同一個函數(shù)可以被一個或多個函數(shù)調(diào)用任意多次,如加工輔料的公司可以和很多不同制衣公司合作。
三、向函數(shù)傳遞地址
如果參數(shù)是數(shù)組和指針變量,即地址,則傳遞地址值。
例如學(xué)校要鋪草坪,即學(xué)校“調(diào)用”草坪公司。一種方法是讓草坪公司在自己公司內(nèi)種植草坪,草坪成熟后送到學(xué)校來,學(xué)校自己完成草坪鋪種。一種方法是由草坪公司直接把草坪種植到校園里。
第一種方法,學(xué)校需要明確告訴草坪公司需要多大面積的草坪數(shù),函數(shù)傳遞值的拷貝。
char *Lawn_Com(float area)//草坪公司
{
char col_lawn[100];
for(int i=0;i
col_lawn[i]='*';//用*代表種植的草坪
return col_lawn;
}
void college( )//學(xué)校
{
char *college_lawn;
college_lawn=Lawn_Com(30);//30是形參,草坪公司把成熟的草坪送到學(xué)校的college_lawn。
}
void main( )
{
college( );
}
第二種方法里,學(xué)校需要明確告訴草坪公司在學(xué)校的哪個位置種植草坪,草坪公司直接派遣工作人員去“實參”所指示的“地址”種植草坪就可以了,函數(shù)參數(shù)傳遞的是地址。當(dāng)函數(shù)參數(shù)傳遞的是地址值時,通過地址找到實參,然后直接對實參進(jìn)行操作。
void Lawn_Com(char col_lawn[30])//草坪公司
{
for(int i=0;i
col_lawn[i]='*';//用*代表種植的草坪
}
void college( )//學(xué)校
{
char college_lawn[30];
Lawn_Com(college_lawn);//草坪公司到學(xué)校的college_lawn
}
void main( )
{
college( );
}
四、函數(shù)的返回值
函數(shù)的返回值就是把函數(shù)執(zhí)行完之后的結(jié)果帶回給主調(diào)函數(shù)。函數(shù)可以有返回值,也可以沒有返回值。
如學(xué)?!罢{(diào)用”草坪公司鋪設(shè)草坪,在第一種方法中,學(xué)校要求草坪公司在其公司內(nèi)部鋪種草坪,把鋪種成熟后草坪作為“返回值”送到學(xué)校,學(xué)校自己把草坪種到校園里,這是有返回值的函數(shù)。而在第二種方法中,學(xué)校要求草坪公司直接把草坪種到校園里,草坪種完就完成任務(wù),草坪公司就不要再提交學(xué)校返回值了。
再如制衣公司“調(diào)用”輔料加工公司,輔料加工公司按照“實參”的要求把加工完的拉鏈成品作為“返回值”提交給制衣公司。
五、結(jié)束語
除了函數(shù)這一章外,筆者在C語言程學(xué)設(shè)計其他章節(jié)內(nèi)容的教學(xué)中均嘗試采用了形象的類比教學(xué)法,效果顯著。類比教學(xué)法要求教師具有高度的概括能力,將知識進(jìn)行歸納總結(jié),在教學(xué)過程中,讓學(xué)生將實際應(yīng)用和生活所熟悉的事物與枯燥、抽象的概念理論進(jìn)行類比,培養(yǎng)學(xué)生分析和解決問題的能力,提高學(xué)生的學(xué)習(xí)興趣,讓學(xué)生喜歡C語言,學(xué)好C語言。
參考文獻(xiàn):
[1]譚浩強(qiáng).C程序多設(shè)計.第3版.清華大學(xué)出版社,2005
[2]韓瑩,豐繼林,單維鋒.C語言實訓(xùn)教程.第1版.清華大學(xué)出版社,2013.1
關(guān)鍵詞: 股票市場收益;原油價格;Copula函數(shù);相關(guān)性
中圖分類號:F830.91 文獻(xiàn)標(biāo)識碼: A文章編號:1003-7217(2016)02-0032-06
一、引 言
原油是當(dāng)今世界最主要的戰(zhàn)略能源之一,對國民經(jīng)濟(jì)和金融市場的發(fā)展具有重大意義。歷史表明國際原油價格的每一次大幅波動,都會給世界經(jīng)濟(jì)帶來巨大影響。從油價波動引起股市波動的機(jī)理來分析,對原油進(jìn)口國而言,油價上漲會提高國內(nèi)的物價水平,降低居民的實際收入水平,從而抑制居民消費,不利于經(jīng)濟(jì)增長,股市也會受到影響。油價上漲還會導(dǎo)致中下游企業(yè)成本的增加,企業(yè)利潤的減少會減弱生產(chǎn)積極性,不利于經(jīng)濟(jì)增長和股市的發(fā)展。同時,油價上漲必然導(dǎo)致生產(chǎn)企業(yè)減少石油的投入,降低企業(yè)的資本利用率,減少投資和資本存量,從而影響經(jīng)濟(jì)的增長,進(jìn)而造成股市波動。油價的波動對發(fā)展中國家的影響比對發(fā)達(dá)國家的影響要大得多,主要是因為這些經(jīng)濟(jì)體依附于能源密集型產(chǎn)業(yè),經(jīng)歷了快速經(jīng)濟(jì)增長,但能源使用效率低下[1]。鑒于新興經(jīng)濟(jì)體的石油消耗不斷增加,研究國際原油價格與股票市場收益的相關(guān)性具有顯著意義。最近幾年,“金磚五國”成為新興市場的典型代表:金磚五國以快速的經(jīng)濟(jì)增長速度和巨大的市場潛力著稱,逐漸成為世界經(jīng)濟(jì)增長的重要推動力量。因此,本文重點研究國際原油價格與金磚五國股市收益之間的相依結(jié)構(gòu)。
金洪飛,金犖[2]用VAR模型和二元GARCH模型研究了中美股市價格和國際石油價格的收益率及波動的溢出效應(yīng),實證結(jié)果表明中國股市價格與國際油價之間不存在任何方向的收益率溢出效應(yīng)和波動溢出效應(yīng),而國際油價對美國股市有負(fù)向先導(dǎo)作用,并且存在雙向的波動溢出。Kunlapath S[3]等用Copula函數(shù)研究了股票收益和油價回報之間的相互關(guān)系,排除了石油天然氣股票公司的股票指數(shù)以去除油價和石油天然氣公司的直接關(guān)系。研究結(jié)果表明,在大多數(shù)情況下,油價和股票指數(shù)之間存在弱依賴性,這與先前的研究結(jié)果一致,然而石油消耗國和生產(chǎn)國的油價與股市具有強(qiáng)相關(guān)性。戚倩F,朱洪亮[4]應(yīng)用VAR模型和誤差修正模型,研究了中美股市價格和國際石油價格間的關(guān)系及油價對中國股市板塊指數(shù)的影響,研究表明國際石油價格同中美股市指數(shù)都存在協(xié)整關(guān)系,在油價與美國股市指數(shù)的關(guān)系中,油價處于主導(dǎo)地位。Cuong C[5]使用非參Chiand Kplots和Copula函數(shù)分別刻畫了油價對中國和越南的相關(guān)性,國際油價與越南股市之間具有左尾相依性,與中國的結(jié)果相反。Xiaoqian Wen[6]利用Copula函數(shù)探討了在金融危機(jī)期間油價與股市之間是否具有傳染效應(yīng)。雖然目前存在較多對油價和股市之間的相關(guān)性研究,但是卻嚴(yán)重缺乏對金磚五國這樣的新興經(jīng)濟(jì)體的研究。因此,本文結(jié)合GARCH和Copula方法研究國際油價和金磚五國股市收益的相關(guān)性影響。
二、Copula理論與方法
(一)邊緣分布的估計
根據(jù)Copula理論,度量油價與股市收益之間的相關(guān)性,首先需要對油價和股市收益率分別建立一個邊緣分布。用正態(tài)分布擬合金融時間序列的均值方程的殘差,其結(jié)果不是很符合實際情況。GARCHGED模型能較好的描述金融時間序列的時變波動、高峰、偏斜、厚尾等分布特性。為了提高模型的擬合效果,采用基于廣義誤差分布(GED)的AR(p)GARCH(1,1)模型描述邊緣分布。模型的均值方程和方差方程如下:
由表1可知,除了油價的均值為負(fù)數(shù)之外,金磚五國股市收益率均值均為正數(shù),但數(shù)值都較小,均在零附近。俄羅斯的標(biāo)準(zhǔn)差比較小,其他幾個市場的標(biāo)準(zhǔn)差較大。偏度顯示正向沖擊對于巴西和印度市場更為常見,而負(fù)向沖擊對于其他市場更為常見。
得出油價和股市的收益率峰度都大于6,遠(yuǎn)遠(yuǎn)大于正態(tài)分布的3,峰度最高的是俄羅斯股票市場,其值達(dá)到了22.9。從統(tǒng)計結(jié)果可知收益率服從尖峰、厚尾分布。JB統(tǒng)計量明顯拒絕收益正態(tài)性假設(shè),LM檢驗表明變量存在ARCH效應(yīng)。
表2給出了國際油價與金磚五國股市收益的相關(guān)系數(shù)結(jié)果??傮w來看,油價和金磚五國股市的相關(guān)關(guān)系比較強(qiáng)。其中,Pearson線性相關(guān)、Spearman相關(guān)和Kendall相關(guān)的最大值分別是0.6870、0.5835和0.4585,除了油價與中國的相關(guān)系數(shù)較小之外,其他四國相關(guān)系數(shù)較大,說明油價與其他四國股市具有中等相關(guān)關(guān)系。這是因為巴西是石油開采大國,而石油更是作為俄羅斯的經(jīng)濟(jì)命脈存在,南非的礦產(chǎn)資源非常豐富,卻唯獨缺少石油這種戰(zhàn)略資源。亞太地區(qū)近10年經(jīng)濟(jì)快速增長,可以抵消油價對股市的負(fù)向沖擊。
為了提高模型的擬合效果,采用基于廣義誤差分布(GED)的AR(p)-GARCH(1,1)模型對油價和股市收益率進(jìn)行建模,滯后階數(shù)選取0至10階,由AIC準(zhǔn)則確定滯后階數(shù)。表3給出了收益序列邊緣分布的估計結(jié)果,GED分布的參數(shù)均小于2,說明尾部比正態(tài)分布的尾部更厚,反映收益率序列所得殘差項的尖峰厚尾特征,也表明GED分布能夠很好地描述收益率一般具有的非正態(tài)分布特征[8]。從結(jié)果可知,大部分估計系數(shù)和t統(tǒng)計量在1%的顯著性水平下是顯著的。表4是收益序列邊緣分布模型檢驗結(jié)果。LB檢驗主要是檢驗序列是否為白噪聲過程,由殘差序列的自相關(guān)系數(shù)計算而得,檢驗結(jié)果接受原假設(shè),在滯后1,5,10階沒有自相關(guān);LM檢驗表明殘差的平方項在滯后1,5,10階沒有自相關(guān);KS統(tǒng)計量是根據(jù)估計得到的邊緣分布,對原序列做概率積分變換后再運用KS檢驗方法得到的,其目的是檢驗變換后的序列是否服從(0,1)均勻分布。KS檢驗結(jié)果表明每個邊緣分布服從(0,1)的均勻分布。
當(dāng)邊緣分布確定后,利用靜態(tài)正態(tài)、Clayton、Gumbel、t Copula以及SJC Copula和時變SJC Copula函數(shù)描述油價和金磚五國股市收益的相關(guān)結(jié)構(gòu)。Copula參數(shù)估計結(jié)果如表5所示。從正態(tài)Copula的估計系數(shù)來看,所有相關(guān)關(guān)系為正,油價與中國的相關(guān)程度最低,只有0.1042,油價與巴西的相關(guān)程度最高,顯然與表2描述的相關(guān)程度相似??紤]尾部的不對稱性,Clayton Copula的下尾相關(guān)系比較小,其中中國最小只有0.1274,但是對于Gumbel Copula的上尾相關(guān)系數(shù)而言,最大值有1.2477。SJC Copula的下尾和上尾系數(shù)都較小,但是下尾相關(guān)系數(shù)總體上大于上尾相關(guān)系數(shù)。因此當(dāng)下尾相關(guān)時,市場管理者更應(yīng)注重風(fēng)險的回避。根據(jù)表5可知,時變SJC Copula的AIC最小,用來刻畫油價與金磚五國股票市場相依結(jié)構(gòu)最為合適。
表6給出了國際油價WTI與金磚五國股市的尾部相關(guān)系數(shù)。正態(tài)Copula函數(shù)用于描述線性關(guān)系,沒有尾部相關(guān)性,尾部相關(guān)系數(shù)為0。從Clayton Copula和Gumbel Copula的尾部相關(guān)系數(shù)看出,油價與中國的尾部相關(guān)系數(shù)是最小的,而油價與巴西的尾部相關(guān)系數(shù)最大的。對于t Copula而言,因為它描述的是對稱分布,故下尾和上尾系數(shù)值是一樣的,油價與中國的尾部系數(shù)最小,這與表2的相關(guān)系數(shù)結(jié)果是一致的。從SJC Copula得出的結(jié)果可以看出,五個國家的下尾系數(shù)均大于上尾系數(shù),說明油價的下跌對股市的影響大于油價的上漲對股市的影響。
參數(shù)估計結(jié)果顯示油價與巴西的相關(guān)程度最高,因此對它們之間的相依結(jié)構(gòu)進(jìn)行分析。
圖1、2分別給出了基于SJC Copula的油價與巴西股市的非對稱結(jié)構(gòu)。2009年以前,時變SJC Copula的下尾系數(shù)和上尾系數(shù)分別維持在0.2054、0.1289附近,相關(guān)關(guān)系相對較弱;此后的幾年時間里,尾部相關(guān)程度明顯提高,時變SJC Copula的尾部相關(guān)系數(shù)總體上比靜態(tài)的尾部系數(shù)要大得多。同時還可以看出,油價與巴西股市收益的下尾系數(shù)要大于上尾系數(shù),說明下尾的相關(guān)性比上尾的相關(guān)性要高。
石油價格收益率與金磚五國股市的相關(guān)程度取決于這些國家是否為石油進(jìn)出口國家。2006年以前巴西一直是石油凈進(jìn)口國,此后開始抓緊陸地石油勘探和興建煉油設(shè)施,石油產(chǎn)量不斷增加,成為石油出口國。石油出口帶來的收益增加會給石油出口的收入帶來正向的影響。因此,股票市場的收益會受到來自國際原油價格的變動影響。俄羅斯是全球第二大石油出口國,財政收入大部分依賴于石油的收益。石油與股市之間的相關(guān)關(guān)系也比較明顯。從負(fù)的偏度可知,油價與俄羅斯股市之間存在負(fù)向的關(guān)系,油價的下跌比上漲更能引起股市的波動。俄羅斯在911事件之后的石油產(chǎn)量不斷上升,其他產(chǎn)油國卻顯著的減少產(chǎn)量。因此可以說石油是俄羅斯的經(jīng)濟(jì)命脈,俄羅斯經(jīng)濟(jì)收入與石油息息相關(guān)。印度和中國以及南非一直都是石油凈進(jìn)口國。從實證結(jié)果來看,石油與中國的相關(guān)程度最弱,印度次之。印度和中國都是非常大的經(jīng)濟(jì)體,從某種程度而言,印度和中國的股市取決于多種宏觀因素的影響, 而不會單一的受到油價波動的沖擊。伴隨著中國金融經(jīng)濟(jì)體制的不斷完善,中國證券市場更加規(guī)范和成熟,吸收和消化外來沖擊的能力得到進(jìn)一步增強(qiáng)[9]。這意味著中國經(jīng)濟(jì)具有強(qiáng)大的支撐和龐大的外匯儲備,在糟糕的環(huán)境下保護(hù)市場。隨著中國對外國投資者越來越開放,未來放開市場控制和匯率控制,這種弱相關(guān)程度可能會改變。
四、結(jié) 論
國際原油價格和股市之間的相關(guān)關(guān)系得到廣泛的關(guān)注。但是通常金融變量的分布是非正態(tài)的,線性相關(guān)顯然不太合適。本文采用Copula方法對油價與金磚五國股市收益之間的相關(guān)性進(jìn)行描述。研究結(jié)果表明國際原油價格與中國股市收益呈現(xiàn)微弱的相關(guān)關(guān)系,而與其他四國股市收益的相關(guān)關(guān)系較為明顯。對于Copula參數(shù)估計而言,由最優(yōu)AIC可知,使用時變SJC Copula描述模型更為合適。在金融全球化的趨勢下,不同國家或地區(qū)之間的金融市場的價格風(fēng)險相依性逐漸加強(qiáng)。研究油價與金磚五國股市之間的相依關(guān)系對國際資產(chǎn)定價,風(fēng)險管理和全球經(jīng)濟(jì)體的交互作用具有深刻的意義。首先,油價波動造成的非對稱相依關(guān)系幫助投資者和政策制定者應(yīng)對油價的變化,有助于謹(jǐn)慎投資,規(guī)避全球市場的風(fēng)險傳染。其次,投資者和決策者在國際金融市場上實現(xiàn)投資組合和資產(chǎn)配置多樣化,維護(hù)發(fā)展中國家的利益。最后,動態(tài)尾部相關(guān)性的研究結(jié)果對風(fēng)險管理也具有一定的指導(dǎo)作用,幫助政策制定者認(rèn)清方向,當(dāng)下尾相關(guān)性高于上尾相關(guān)性時,更應(yīng)該及時規(guī)避油價波動帶來的風(fēng)險沖擊,增強(qiáng)成員國進(jìn)一步加強(qiáng)合作的意愿。
參考文獻(xiàn):
[1] Bhar R, Nikolova B. Oil prices and equity returns in the BRIC countries[J]. World Economy, 2009, 32(7): 1036-1054.
[2]金洪飛, 金犖. 石油價格與股票市場的溢出效應(yīng)――基于中美數(shù)據(jù)的比較分析[J]. 金融研究, 2008,(2):83-97.
[3]Kunlapath S, Tatevik Z, David L,Wu X. Interdependence of oil prices and stock market indices:a copula approach[J]. Energy Economics, 2014, 44(4):331-339.
[4]戚倩F, 朱洪亮. 國際石油價格與中美股票市場影響關(guān)系的計量分析[J]. 金融理論與實踐, 2011,(7):82-87.
[5]Nguyen C C, Bhatti M I. Copula model dependency between oil prices and stock markets:evidence from China and vietnam[J]. Journal of International Financial Markets Institutions & Money, 2012, 22(4): 758-773.
[6]Wen X, Wei Y, Huang D. Measuring contagion between energy market and stock market during financial crisis: A copula approach[J]. Energy Economics, 2012, 34(5): 1435-1446.
[7]Andrew J, Patton. Modelling asymmetric exchange rate dependence[J]. Social Science Electronic Publishing, 2006, 47(2):527-556.
關(guān)鍵詞:冠脈內(nèi)支架植入術(shù);再狹窄; C反應(yīng)蛋白;纖溶酶原激活物抑制劑-1
中圖分類號:R815 R256.2 文獻(xiàn)標(biāo)識碼:B 文章編號:1672-1349(2011)08-0925-02
預(yù)防冠脈支架內(nèi)再狹窄是PCI必須面對的問題。再狹窄的基本病變包括炎癥反應(yīng)、平滑肌增生及細(xì)胞外基質(zhì)的積聚[1]。研究表明糖尿病是再狹窄的危險因素[2],并且糖尿病患者的纖溶活性受損,機(jī)體的炎性反應(yīng)激活,而纖溶與炎癥機(jī)制是滲透再狹窄病理過程中的兩個主要機(jī)制[3],其中血C反應(yīng)蛋白(CRP)、纖溶酶原激活物抑制劑-1(PAI-1)是反映纖溶機(jī)制與炎癥機(jī)制的常用指標(biāo),并已成為支架術(shù)后再狹窄強(qiáng)有力的預(yù)測指標(biāo)[4],噻唑烷二酮類(TZDs)吡格列酮是否可以通過抑制血CRP與PAI-1而抑制支架內(nèi)再狹窄?本研究旨通過觀察吡格列酮對這兩個因子的作用進(jìn)而在理論上推測對支架內(nèi)再狹窄方面的意義。
1 資料與方法
1.1 病例選擇 連續(xù)入選山西醫(yī)科大學(xué)第一醫(yī)院2007年5月―2008年1月心內(nèi)科行PCI術(shù)的2型糖尿病(T2DM)并使用胰島素治療的急性冠脈綜合征患者20例。排除標(biāo)準(zhǔn):既往有PCI史、接受過冠脈搭橋手術(shù)、心功能不全、肝腎功能異常、惡性腫瘤、感染、心肌炎、動脈夾層、血液病、伴有其他內(nèi)分泌疾病的患者。
1.2 方法
1.2.1 給藥方法 將入選20例患者隨機(jī)分為觀察組與對照組,各10例。觀察組在PCI后24 h內(nèi)加用鹽酸吡格列酮(艾可拓)15 mg/d,維持3個月,兩組均給予常規(guī)治療。
1.2.2 觀察指標(biāo) PCI術(shù)后24 h內(nèi)、1個月及3個月測定血清高敏C反應(yīng)蛋白(hs-CRP),血漿PAI-1含量。PAI-1測定:取清晨空腹肘靜脈血1.8 mL注入0.25%枸櫞酸鈉抗凝液0.2 mL試管中,離心。hs-CRP測定:取清晨空腹肘靜脈血2 mL,靜置,離心,收集上清液。二者均于-80 ℃保存直至檢測,由太陽生物技術(shù)有限公司提供的ELISA試劑盒測定。糖化血紅蛋白(HbA1c)與血脂采用全自動生化分析儀測定。
1.3 統(tǒng)計學(xué)處理 計量資料以均數(shù)±標(biāo)準(zhǔn)差(x±s)表示,采用t檢驗,樣本構(gòu)成比的比較采用χ2檢驗。多次測量數(shù)據(jù)的分析采用重復(fù)測量數(shù)據(jù)的兩因素多水平的方差分析。采用SPSS 13.0統(tǒng)計軟件進(jìn)行處理。
2 結(jié) 果
2.1 兩組一般臨床資料比較(見表1) 兩組一般資料比較差異無統(tǒng)計學(xué)意義(P>0.05)。
表1 兩組臨床資料比較
2.2 兩組hs-CRP、PAI-1及HbA1c變化(見表2~表5) 血清hs-CRP、HbA1c及血漿PAI-1濃度在不同時間點差別有統(tǒng)計學(xué)意義。詳見表2。血清hs-CRP濃度處理因素和時間之間無交互作用,而血清HbA1c及血漿PAI-1濃度處理因素和時間之間有交互作用;但處理因素僅對HbA1c有統(tǒng)計學(xué)意義。詳見表3~表5。即觀察組與對照組支架后三個指標(biāo)均有隨時間逐漸降低的趨勢,且血清HbA1c及血漿PAI-1濃度觀察組較對照組降低趨勢更明顯,但使用艾可拓僅會使血清HbA1c降低有干預(yù)作用。
2.3 不良反應(yīng) 在3個月的觀察期內(nèi)所有患者均未出現(xiàn)心絞痛、再發(fā)心肌梗死、急性或亞急性血栓形成、心源性死亡的不良心血管事件;也均未出現(xiàn)明顯低血糖及體重的增加、未有肝功能異常(谷丙轉(zhuǎn)氨酶水平≥正常上限的3倍)、腎功能及心功能的異常。吡格列酮組有3例出現(xiàn)輕微下肢水腫,未經(jīng)治療均于1個月內(nèi)消失。
3 討 論
冠心病患者血液中CRP及PAI-1水平是增高的[5]。而這二者可促進(jìn)冠脈支架術(shù)后再狹窄[3]。CRP可上調(diào)細(xì)胞間黏附分子-1、血管內(nèi)皮細(xì)胞黏附分子-1、E-選擇素,介導(dǎo)巨噬細(xì)胞吞噬未修飾的LDL。CRP可誘導(dǎo)內(nèi)皮細(xì)胞產(chǎn)生單核細(xì)胞趨化蛋白-1,增加單核細(xì)胞組織因子產(chǎn)生,而此因子是外源性凝血途徑的重要啟動因子,誘發(fā)血栓形成。CRP水平較高者炎癥局部釋放的某些血管收縮因子較多或血栓形成過程中血小板釋放的血栓素A2較多,誘發(fā)血栓形成;PAI-1可在局部減少纖溶酶原的激活,促進(jìn)病變血管內(nèi)纖維蛋白和細(xì)胞外基質(zhì)的堆積。
鹽酸吡格列酮屬于新型的TZDs,TZDs是PPARγ的人工合成配體,是一類新型的胰島素增敏劑,TZDs可以改善高胰島素和高血糖血癥,使胰島素抵抗緩解[6],改善脂質(zhì)代謝紊亂。對血管的作用包括改善血管內(nèi)皮功能,降低血壓,減少動脈粥樣硬化炎癥替代標(biāo)志[4],也可通過抑制前炎癥細(xì)胞因子,黏附分子和細(xì)胞外基質(zhì)蛋白的誘導(dǎo)生成,達(dá)到抗炎作用。C反應(yīng)蛋白是公認(rèn)的最常用的急性期蛋白。PAI-1除反應(yīng)纖溶活性外也作為一種急性反應(yīng)性蛋白,炎癥的消除對纖溶活性的改善也起重要作用[7]。理論上TZDs有降低血CRP、PAI-1水平,但從本研究觀察到合并T2DM并行PCI術(shù)的患者在術(shù)后3個月內(nèi)應(yīng)用鹽酸吡格列酮除會使HbA1c的下降更顯著,對于hs-CRP、PAI-1、血壓及血脂則沒有明顯干預(yù),可能的原因是:患者在觀察期內(nèi)堅持服用氯吡格雷及阿司匹林,皮下注射胰島素,服用他汀類藥物、血管緊張素轉(zhuǎn)換酶抑制劑或血管緊張素Ⅱ受體拮抗劑,嚴(yán)格控制血壓、血糖,并盡量使血脂達(dá)標(biāo),而血壓、血糖、血脂達(dá)標(biāo)及上述藥物本身均有利于降低患者血中的hs-CRP、PAI-1[8-10]。在這些因素的影響下加用鹽酸吡格列酮對于血糖的調(diào)節(jié)似乎作用較直接和有效,但對血壓、血脂、血hs-CRP及PAI-1的直接影響則較?。籘ZDs啟動的是一個基因調(diào)控的過程,3個月的觀察時間較短;再狹窄部位藥物濃度不足;PCI術(shù)后血hs-CRP、PAI-1還有一個自行回落過程對實驗結(jié)果有影響。
參考文獻(xiàn):
[1] 潘長江.血管支架內(nèi)再狹窄的機(jī)理研究進(jìn)展[J].中國介入影像與治療學(xué),2005,2(4):314-317.
[2] 王旭開,何作云.胰島素及IGF系統(tǒng)在冠狀動脈再狹窄形成中的作用[J].心血管病學(xué)進(jìn)展,2001,22(3):140-142.
[3] 劉海波,高潤霖.血清C反應(yīng)蛋白水平對冠心病介入治療術(shù)中及術(shù)后并發(fā)癥發(fā)生的預(yù)測價值[J].中國循環(huán)雜志,2000,15:264-265.
[4] 楊彬.氯沙坦在損傷血管重構(gòu)中的作用及其機(jī)制的探討[J].心臟雜志,2004,16(1):23-24;28.
[5] 朱西娥.糖尿病與冠心?。ㄉ希?[J].中國鄉(xiāng)村醫(yī)藥雜志,2002,9(11):57.
[6] 劉尊敬.PPARγ配體和相關(guān)血管病變的防治[J].國外醫(yī)學(xué):神經(jīng)病學(xué)神經(jīng)外科學(xué)分冊,2004,31(2):117-120.
[7] 周明術(shù).2型糖尿病患者急性時相反應(yīng)蛋白檢測的臨床意義[J].陜西醫(yī)學(xué)雜志,2005,34(11):1347-1349.
[8] 郭書紅.氯沙坦對原發(fā)性高血壓患者PAI-1、vWF、D-D的影響[J].中國廠礦醫(yī)學(xué),2006,19(3):199-202.
[9] 俞勻,朱大龍.PAI-1與代謝綜合征[J].國際內(nèi)分泌與代謝雜志,2006,26:49-51.
[10] 祁素霞.PAI-1、CRP與胰島素抵抗及2型糖尿病的關(guān)系[J].醫(yī)學(xué)綜述,2007,13(3):212-214.
作者簡介:趙宇卉(1976―),女,主治醫(yī)師,醫(yī)學(xué)碩士,現(xiàn)工作于山西省忻州市人民醫(yī)院(郵編:034000);陳還珍,工作于山西醫(yī)科大學(xué)第一醫(yī)院。
關(guān)鍵詞:面向?qū)ο?;代碼轉(zhuǎn)換;C/C++
中圖分類號:TP311文獻(xiàn)標(biāo)識碼:A文章編號:1009-3044(2008)35-2181-03
An Automated Solution to Develop Object-Oriented C Program
RAO Jun-wen, ZHU Hong-ming
(Software School, Tongji University, Shanghai 201804, China)
Abstract: There are already solutions to make C language support Object-Oriented feature, but in those solutions the code framework supporting that feature needs to be provided by developers. In this solution codes will be written in C++-like grammar, while inside codes will be converted into Object-Oriented C language code, so no gap between Object-Oriented feature and C language exists. This paper analyzed the mechanisms of supporting Object-Oriented feature by using C language and codes converting, and then compared performance of this solution to that of using C++, so its advantage would be proved.
Key words: Object Oriented; codes converting; C/C++
1 方案概述
1.1 當(dāng)前情況
嵌入式系統(tǒng)是當(dāng)前最熱門最有發(fā)展前景的IT應(yīng)用領(lǐng)域之一,然而不得不承認(rèn)的是,由于嵌入式領(lǐng)域硬件資源的限制,絕大多數(shù)的嵌入式軟件還是用C語言或匯編來實現(xiàn)的,這一現(xiàn)狀極大影響了開發(fā)人員的工作效率和質(zhì)量。眾所周之,C語言是一種不直接支持面向?qū)ο筇匦缘恼Z言,相對于C++等語言來說,其代碼編寫效率低,組織層次紛亂,封裝性差,不利于代碼重用。這樣的代碼,可讀性差,維護(hù)難度也很大。如果為避免這種情況而采用C++等支持面向?qū)ο筇匦缘木幊陶Z言又會顧此失彼。C++雖然支持面向?qū)ο筇匦?,但它所具有的其他特性,如虛函?shù)、多重繼承、模板、異常、RTTI等,增加了代碼的復(fù)雜性,使其占用更多硬件資源,降低代碼運行的效率,這些都會極大的影響嵌入式系統(tǒng)的性能和成本。因此,在實際應(yīng)用中使用C++開發(fā)嵌入式軟件的情況也較少。
下面本文將介紹一種不依賴編譯器的編程方案,它既具有C語言的執(zhí)行效率,又支持面向?qū)ο筇匦浴?/p>
1.2 特點
享受基本的面向?qū)ο筇匦?,同時享受C語言的效率。
1) 本方案支持“類”的概念,包括私有成員變量和成員函數(shù),并支持成員函數(shù)繼承和多態(tài)。
2) 類的定義是通過特殊的hpp頭文件來實現(xiàn)的,這個頭文件的編寫格式和C++基本相同。
3) 方案的重要部分是一個自動代碼轉(zhuǎn)換工具,它負(fù)責(zé)將hpp頭文件轉(zhuǎn)換成純C代碼。最終參加編譯的代碼都是純C代碼,因此,這個方案具有C語言所具有的代碼容量小和執(zhí)行效率高等特點。
4) 方案內(nèi)部使用C代碼框架實現(xiàn)類封裝,繼承和多態(tài)。
1.3 開發(fā)主要流程
(注:本文使用“demoClass”代表用戶定義的某一個“類”。“parentClass”代表這個類的父類。)
1) 編寫頭文件demoClass.hpp和源文件demoClass.c;
2) 轉(zhuǎn)換hpp頭文件代碼,生成中間C框架文件;
3) 編譯C文件,生成二進(jìn)制文件。
2 方案設(shè)計
2.1框架
demoClass.hpp:頭文件,用于存放類的定義信息。
demoClass.c:源文件,用于存放類成員函數(shù)的實現(xiàn)。
demoClass.h:公共頭文件,向外提供函數(shù)接口和數(shù)據(jù)定義。
demoClass_priv.h:私有頭文件,僅供類內(nèi)部的源文件使用,存放私有數(shù)據(jù)成員的定義及私有成員函數(shù)的聲明。
demoClass_info.c:源文件,用于存放類的信息結(jié)構(gòu)體,以及類的構(gòu)造函數(shù)定義。
testMain.c:測試文件,使用類的對象實例完成特定功能。
2.2源代碼編寫結(jié)構(gòu)設(shè)計
2.2.1頭文件 .hpp VS C++頭文件.h
1) 所有public函數(shù)須都是虛函數(shù),除了構(gòu)造和析構(gòu)函數(shù)。
2) 只支持private數(shù)據(jù)成員。
3) 與本類虛函數(shù)對應(yīng)的實體函數(shù)在private下聲明。
4) 用以重載父類函數(shù)的實體函數(shù)在private下聲明。
2.2.2源文件 .c VS .cpp
1) 添加#include "demoClass_priv.h"私有成員內(nèi)容。
2) 對象初始化函數(shù)和析構(gòu)函數(shù):
demoClassInit():對象初始化函數(shù),各函數(shù)指針初始化。
demoClassDelete():析構(gòu)函數(shù),完成“析構(gòu)”動作。
3) this: 成員函數(shù)指針;thisd: 數(shù)據(jù)成員指針
2.2.3 代碼范例
2.3 中間c代碼設(shè)計及其機(jī)制
代碼轉(zhuǎn)換工具將通過給予的hpp文件,自動生成C語言代碼框架,由他們實現(xiàn)各項面向?qū)ο蟮奶匦浴?/p>
2.3.1 類結(jié)構(gòu)
經(jīng)過轉(zhuǎn)換后的C代碼分別使用兩個結(jié)構(gòu)體存儲類的數(shù)據(jù)如圖2、圖3。
1) 使用demoClass 結(jié)構(gòu)體存儲函數(shù)指針集以及私有數(shù)據(jù)成員結(jié)構(gòu)體對象的地址。
Typedef struct {
void * pData;
errCode ( *Delete )(CMPHANDLE);
errCode ( *virtualFunc_parent1 )(CMPHANDLE);
errCode ( *virtualFunc_demo1 )(CMPHANDLE);} demoClass;
在成員函數(shù)內(nèi)部,“this”指針指向demoClass對象。而thisd 的內(nèi)容就是 this->pData。
2) 使用demoClass_data結(jié)構(gòu)體存儲私有數(shù)據(jù)成員,由于其定義只在demoClass.c中,它并不暴露給外部類。
Typedef struct {
int privParentData1;
int privDemoData1;} demoClass_data;
雖然在對象demoClass中保存了對象demoClass_data的地址,但由于后者的定義并未公開,外部并不知道這個地址空間存儲了哪些數(shù)據(jù),而成員函數(shù)是在demoClass.c中定義的,他們是“看”的見這張定義表的,所以只有本類的成員函數(shù)知道如何“按圖索驥”,這從一定程度上實現(xiàn)了隱藏類的私有成員。
3) 使用結(jié)構(gòu)體ClassInfo的對象來存儲每一個類的信息,包括類名,父類ClassInfo對象指針,demoClass和demoClass_data結(jié)構(gòu)體大小。每個類對應(yīng)的ClassInfo對象是這個類唯一的全局變量,任何時候用戶可以調(diào)用類對應(yīng)的“構(gòu)造函數(shù)”制造出一個對象實例。
4) “this”和thisd指針
為了能使類的成員函數(shù)訪問本類的其他成員函數(shù)以及本類的私有數(shù)據(jù),成員函數(shù)必須知道本對象的地址和數(shù)據(jù)成員地址,在C++中,這些是由C++編譯器內(nèi)部提供this指針來實現(xiàn)的;在本方案中,每個成員函數(shù)都以第一個參數(shù)作為一個固定的輸入?yún)?shù),來獲得本對象的地址,進(jìn)而獲得數(shù)據(jù)成員的地址。this是demoClass型指針,thisd是demoClass_data型指針,它們指向各自的結(jié)構(gòu)體對象。
5) 類的創(chuàng)建和消亡
① “構(gòu)造函數(shù)”demoClassNew()
demoClassNew()是這個對象唯一暴露在外的全局函數(shù)。用戶可以通過調(diào)用它來創(chuàng)建對象。
demoClass* demoClassNew()
{demoClass* h= (demoClass*)ObjCreateAlloc(&demoClassInfo);
demoClassInit(h);
return h;}
a. 所有的類都通過調(diào)用ObjCreateAlloc (ClassInfo *)來實際創(chuàng)建對象,它依據(jù)給定的ClassInfo數(shù)據(jù),獲得demoClass和demoClass?_data的結(jié)構(gòu)體大小,分別給它們分配內(nèi)存空間,并返回demoClass地址,而demoClass_data的地址則保存在demoClass之中。
ObjCreateAlloc()函數(shù)將在后文中介紹。
b. 類被創(chuàng)建之后,由demoClassInit()來進(jìn)行初始化,基本的動作包括函數(shù)指針和成員變量的初始化,還可以有用戶自定義的動作。
② “析構(gòu)函數(shù)”負(fù)責(zé)清理用完的數(shù)據(jù)或內(nèi)存,并最終釋放對象自己的內(nèi)存空間。
2.3.2 繼承
1) 派生類的數(shù)據(jù)繼承:成員函數(shù)指針和成員變量
派生類通過照搬基類數(shù)據(jù)的方式來實現(xiàn)函數(shù)和數(shù)據(jù)繼承。這種照搬的工作是由代碼轉(zhuǎn)換工具依據(jù)繼承關(guān)系完成的。在生成的C代碼中,用于存儲派生類數(shù)據(jù)的結(jié)構(gòu)體demoClass,其前端數(shù)據(jù)和基類結(jié)構(gòu)體parentClass的數(shù)據(jù)完全一 致 ,新 增 加 的 函數(shù)指針緊接其后。demoClass_data新增加的成員變量也同理。這樣,派生類就完全包含了一份與基類一致的公有函數(shù)指針和數(shù)據(jù)拷貝。當(dāng)然,這些函數(shù)指針可能指向與基類不同的函數(shù)實體,其數(shù)據(jù)成員也可能存儲不同的內(nèi)容,這取決于構(gòu)造函數(shù)的實現(xiàn)。
2) 構(gòu)造和析構(gòu)函數(shù)的繼承
派生類的構(gòu)造函數(shù)在自己的初始化函數(shù)開頭,先調(diào)用基類的初始化函數(shù),它負(fù)責(zé)初始化繼承自基類的成員,在這個階段,派生類被裝扮成基類的樣子。然后派生類執(zhí)行自己的初始化動作,在這個階段,派生類給新增加的函數(shù)成員和數(shù)據(jù)成員賦值,也可以修改來自基類的成員。
派生類的析構(gòu)函數(shù)也分成兩部分,先清理自己新增加的成員,然后在末尾調(diào)用基類的析構(gòu)函數(shù),來清理來自基類的成員,最終釋放自己占用的內(nèi)存。
3) 成員函數(shù)的繼承
與上節(jié)類似,被重載的成員函數(shù),其新的函數(shù)實體可以包含對基類成員函數(shù)的調(diào)用,也可以不調(diào)用,完全重寫。
2.3.3 封裝
1) 通過以上的結(jié)構(gòu)設(shè)計,C語言中間代碼實現(xiàn)了封裝性:
任何一個對象創(chuàng)建之后,只能通過這個對象的句柄訪問其公開的函數(shù)接口,外界看不見內(nèi)部的數(shù)據(jù),也無法通過合法的手段直接操作它們。而在對象創(chuàng)建之前,與這個類相關(guān)的全局元素只有兩個:全局變量demoClassInfo和全局函數(shù)demoClassNew( )。
2) 公共根類
在這套方案中,任何一個類的對象,其創(chuàng)建和消亡都會涉及到這個類基礎(chǔ)數(shù)據(jù)的處理,包括內(nèi)存的分配和內(nèi)部數(shù)據(jù)結(jié)構(gòu)的初始化,這些是中間代碼的內(nèi)容,用戶應(yīng)無需關(guān)心它們,因此我們建立一個公共的虛基類rootObj,用它來封裝這些內(nèi)部的操作。用戶如果要建立新的基類customClass,只需繼承這個虛基類,填寫好它對應(yīng)的初始化函數(shù)customInit( )和析構(gòu)函數(shù)customDelete()。根據(jù)代碼的繼承機(jī)制,新的類會遞歸調(diào)用對應(yīng)的構(gòu)造、析構(gòu)函數(shù),最終調(diào)用到虛基類rootObj的構(gòu)造、析構(gòu)函數(shù),從而最終完成類的創(chuàng)建和消亡。
① 前面已經(jīng)提到,類的構(gòu)造函數(shù)demoClassNew()分成ObjCreateAlloc()和demoClassInit()兩個部分。
ObjCreateAlloc()函數(shù)把所有的類都當(dāng)作虛基類來創(chuàng)建,包括給兩個結(jié)構(gòu)體分配內(nèi)存,并初始化pData指針。
CMPHANDLE ObjCreateAlloc(const ClassInfo* ci)
{rootObj* this;
rootObj_data* thisd;
this=malloc(ci->isize); //給demoClass分配內(nèi)存
//給demoClass_data分配內(nèi)存并把地址保存在pData中
this->pData = malloc(ci->dsize) ;
return this;}
② 虛基類的析構(gòu)函數(shù),負(fù)責(zé)釋放類結(jié)構(gòu)所占用的內(nèi)存
errCode rootObjDelete(CMPHANDLE h)
{ THIS_PTR_DEF;
free(h);
return SUCCESS;}
2.3.4 多態(tài)
本方案把所有成員函數(shù)都設(shè)置成虛函數(shù),在內(nèi)部通過函數(shù)指針的方式來實現(xiàn)。當(dāng)派生對象要重載基類對象的某個成員函數(shù)的時候,就把對應(yīng)的函數(shù)指針指向新的函數(shù)實現(xiàn)實體,這樣,一個同名的成員函數(shù),根據(jù)類的不同完成著不同的操作,從而實現(xiàn)了多態(tài)。
2.4 代碼轉(zhuǎn)換工具的工作
總結(jié)如下:根據(jù)給予的demoClass.hpp文件,
1) 生成demoClass.h文件:
① include 父類的頭文件parentClass.h。
② 生成demoClass結(jié)構(gòu)體,其中,把所有的成員函數(shù),轉(zhuǎn)換成同名的函數(shù)指針,如果有父類,則把父類的成員函數(shù)指針放在開頭。
③ 聲明demoClassInfo變量和demoClassNew()函數(shù)。
2) 生成demoClass_priv.h文件:
① include 父類的頭文件parentClass.h。
② 生成demoClass_data結(jié)構(gòu)體,其成員就是類的所有私有成員,如果有父類,則把父類的成員變量放在開頭。
③ 聲明父類的初始化和析構(gòu)函數(shù),及成員實體函數(shù)。
④ 聲明本類的初始化函數(shù)和成員實體函數(shù)。
3) 生成demoClass_info.c文件
① include本類的兩個頭文件 demoClass.h和demoClass_priv.h。
② 定義demoClassInfo變量,并賦值。
③ 定義本類的構(gòu)造函數(shù)demoClassNew()。
這個代碼轉(zhuǎn)換工具由perl語言編程實現(xiàn),可以集成在makefile中成為代碼預(yù)處理的一部分。
3 此方案和C++方案的對比
在linux環(huán)境下,功能完全相同的兩個程序:
4 結(jié)束語
通過此方案的轉(zhuǎn)換手段,可以在基本保持C語言性能的基礎(chǔ)上,開發(fā)出支持面向?qū)ο蟮腃程序,而且不增加開發(fā)人員的額外負(fù)擔(dān)。它大大提高了程序的可復(fù)用性和可維護(hù)性,為開發(fā)結(jié)構(gòu)更加復(fù)雜、代碼更加清晰易讀的嵌入式軟件系統(tǒng)提供了可能。在實際應(yīng)用中,采用此方案的軟件代碼明顯比用原C語言實現(xiàn)的同樣功能的代碼更加受開發(fā)人員的歡迎。
參考文獻(xiàn):
[1] 章遠(yuǎn)陽,楊芙清,邵維中.C++語言的面向?qū)ο筇匦苑治鯷J].計算機(jī)工程與應(yīng)用,1992(9).
[2] 張?zhí)?肖孫圣,倪宏.面向?qū)ο蠡咎匦缘腸語言實現(xiàn)[J].微計算機(jī)應(yīng)用,23(6).
關(guān)鍵詞:C語言程序設(shè)計;計算思維;抽象;自動化
美國卡內(nèi)基?梅隆大學(xué)的周以真教授在2006年系統(tǒng)地提出了計算思維的概念[1]:計算思維指的是運用計算機(jī)科學(xué)的基礎(chǔ)概念進(jìn)行問題求解、系統(tǒng)設(shè)計以及人類行為理解等一系列思維活動。其后,陳國良院士和李廉教授歸納出三種典型的科學(xué)思維,即以觀察和歸納為特征的實證思維,以推理和演繹為特征的邏輯思維,以抽象和自動化為特征的計算思維[2-3]。計算思維是計算機(jī)類課程的主要思維方式。
有關(guān)計算思維在程序設(shè)計類課程中的研究,已經(jīng)引起很多學(xué)者的興趣[4-6]。這些研究雖然從案例設(shè)計和項目過程等角度做了有益探索,但卻忽略了對計算思維本質(zhì)的討論。C語言程序設(shè)計課程中,我們采用李廉教授的觀點,即計算思維的本質(zhì)是抽象和自動化。抽象指的是使用符號系統(tǒng)對問題進(jìn)行精確而嚴(yán)格的描述;自動化指的是對這些符號系統(tǒng)施加一定操作并按照某種結(jié)構(gòu)自動地執(zhí)行。
一、C語言程序中的計算思維本質(zhì)之一:抽象
有些C語言程序設(shè)計課程教學(xué)的一開始就提倡使用案例教學(xué)。這雖然能夠使得學(xué)生可以迅速進(jìn)入實際編程環(huán)節(jié)并建立直觀感性認(rèn)識,但案例教學(xué)由于往往出現(xiàn)“程序就是編程工具”的工具論現(xiàn)象,導(dǎo)致出現(xiàn)“只知其然,而不知其所以然”的學(xué)習(xí)后果,不利于學(xué)生的后續(xù)發(fā)展。
對于C語言程序來說,抽象指的是使用符號系統(tǒng)對求解問題進(jìn)行精確而嚴(yán)格的描述,抽象的過程就是對實際系統(tǒng)建模的過程。實際上,程序是用來描述現(xiàn)實生活中某個實際存在的或不存在的系統(tǒng)。程序就是對系統(tǒng)的抽象。系統(tǒng)之所以存在,是因為系統(tǒng)具有一些關(guān)鍵特征和核心功能。程序中對系統(tǒng)特征進(jìn)行抽象的就是操作對象,對系統(tǒng)功能進(jìn)行抽象的就是函數(shù)。系統(tǒng)功能往往有多個且存在著復(fù)雜的調(diào)用關(guān)系。例如,求一個函數(shù)定積分的功能必然涉及求函數(shù)在某一個點的取值功能,如果該函數(shù)比較復(fù)雜且含有正弦、余弦和正切等三角函數(shù),還需要繼續(xù)調(diào)用求這些三角函數(shù)值的功能,形成多級調(diào)用;有時函數(shù)執(zhí)行過程中還需要調(diào)用本身,形成遞歸調(diào)用。
C語言程序中的操作對象分為變量和常量。常量是對系統(tǒng)中的取值不變的特征進(jìn)行抽象,如圓的圓周率;而變量是對系統(tǒng)中取值可以改變的特征進(jìn)行抽象,如圓的半徑。不管是哪類特征,都會有一個取值范圍以及所允許的操作。例如,對于課程成績,其取值范圍一般是從0~100,而允許對該特征進(jìn)行的操作可以是加法和減法等算術(shù)操作以及大于和小于等比較運算;而對于課程名字這一特征,就不能進(jìn)行加法和減法這樣的算術(shù)操作。C語言程序中用來對特征的取值范圍及允許的操作進(jìn)行抽象的概念是數(shù)據(jù)類型。C語言程序中的抽象模塊如表1所示。
現(xiàn)實生活中,經(jīng)常需要描述多個相同數(shù)據(jù)類型的一個系統(tǒng)特征,如所有同學(xué)的高等數(shù)學(xué)課程的成績,可以使用一維數(shù)組來進(jìn)行描述;而描述多個不同數(shù)據(jù)類型的多個系統(tǒng)特征,如學(xué)生的姓名、學(xué)生的身高和學(xué)生的年齡等,可以使用結(jié)構(gòu)體來進(jìn)行描述;如果要描述多個相同數(shù)據(jù)類型的多個系統(tǒng)特征,如全班所有同學(xué)的高等數(shù)學(xué)和大學(xué)英語課程的成績,則可以使用二維數(shù)組來進(jìn)行描述。
表1 C語言程序中的抽象模塊
C語言程序中的元素 現(xiàn)實生活中的元素
程序 系統(tǒng)
函數(shù) 系統(tǒng)功能
函數(shù)調(diào)用 功能調(diào)用
數(shù)據(jù)類型 常量 系統(tǒng)特征
變量
一維數(shù)組 多個相同類型的一個系統(tǒng)特征
多維數(shù)組 多個相同類型的多個系統(tǒng)特征
結(jié)構(gòu)體 多個不同類型的多個系統(tǒng)特征
鏈表或結(jié)構(gòu)體數(shù)組 多個不同類型的多個系統(tǒng)特征的集合
二、C語言程序中的計算思維本質(zhì)之二:自動化
計算思維的另一個本質(zhì)是自動化。自動化指的是對符號系統(tǒng)建模的各種元素施加一些操作,并按照某種順序的或非順序的結(jié)構(gòu)自動地執(zhí)行。對于C語言程序來說,自動化體現(xiàn)為函數(shù)內(nèi)部的語句在EIP寄存器加法操作支持下順序自動地執(zhí)行以及函數(shù)之間的調(diào)用在內(nèi)存堆棧區(qū)支持下自動地進(jìn)行跳轉(zhuǎn)。EIP是32位機(jī)的指令指針寄存器,用來存放下一條要執(zhí)行的指令的地址。EIP寄存器中增加值的大小需要根據(jù)實際存儲指令的大小來確定。
對于C語言程序來說,自動化過程中執(zhí)行的對象是語句。不同類型的語句,執(zhí)行的結(jié)果和效用是不一樣的。例如,一個變量定義語句“int a”的執(zhí)行結(jié)果是在內(nèi)存中分配4個字節(jié)的空間,一個返回語句“return t”的執(zhí)行結(jié)果是將程序的執(zhí)行流程返回到主調(diào)函數(shù)中。這些語句的組合構(gòu)成一個個函數(shù),程序的執(zhí)行就是在某個函數(shù)之中順序自動地執(zhí)行以及在多個函數(shù)之間來回自動地跳轉(zhuǎn)。
既然程序的執(zhí)行過程是在某個函數(shù)之中順序自動地執(zhí)行以及在多個函數(shù)之間來回自動地跳轉(zhuǎn),這種自動執(zhí)行需要有相應(yīng)的計算機(jī)軟件和硬件基礎(chǔ)。支持程序自動執(zhí)行的軟件基礎(chǔ)是操作系統(tǒng),支持程序自動執(zhí)行的硬件基礎(chǔ)是計算機(jī)硬件結(jié)構(gòu),即馮?諾依曼原理的程序存儲思想。當(dāng)用戶點擊執(zhí)行按鈕后,程序被提交給操作系統(tǒng)來執(zhí)行,可以不需要人為干預(yù)。此后,程序在操作系統(tǒng)中以進(jìn)程的方式出現(xiàn)。操作系統(tǒng)協(xié)調(diào)內(nèi)存、中央處理器和外存等硬件資源執(zhí)行該進(jìn)程。
函數(shù)中的語句之所以能夠一個接著一個順序地執(zhí)行,主要依賴于EIP寄存器的加法操作。當(dāng)一條指令執(zhí)行完成之后,EIP寄存器在原有內(nèi)容的基礎(chǔ)上再加上當(dāng)前指令所占存儲空間大小,其內(nèi)容便是下一條指令的地址。如此進(jìn)行下去,就可以一個一個順序地執(zhí)行函數(shù)中的語句。
程序控制之所以能夠在函數(shù)之間進(jìn)行跳轉(zhuǎn),主要依賴于操作系統(tǒng)管理的內(nèi)存堆棧區(qū)。內(nèi)存堆棧區(qū)是滿足“后進(jìn)先出”操作約束的存儲區(qū)。當(dāng)操作系統(tǒng)開始執(zhí)行用戶提交的C語言程序時,首先開始從main函數(shù)執(zhí)行,main函數(shù)的相關(guān)局部變量被壓入棧中;當(dāng)執(zhí)行到被調(diào)函數(shù)時,被調(diào)函數(shù)的相關(guān)局部變量再次被壓入棧中,程序控制轉(zhuǎn)移到被調(diào)函數(shù),且操作只能對當(dāng)前棧頂進(jìn)行,而此時棧頂存儲的就是被調(diào)函數(shù)的相關(guān)局部變量;而當(dāng)被調(diào)函數(shù)執(zhí)行結(jié)束時,被調(diào)函數(shù)的相關(guān)局部變量從棧中退出,程序控制轉(zhuǎn)移到main函數(shù)繼續(xù)執(zhí)行,此時棧頂存儲的是main函數(shù)的相關(guān)局部變量;當(dāng)main函數(shù)執(zhí)行結(jié)束時,main函數(shù)的局部變量從棧中退出,整個程序執(zhí)行結(jié)束。下列程序執(zhí)行時的堆棧變化過程示意如圖1所示。
#include "stdio.h"
double s(double r)
{ return r*r; }
int main()
{ double r;
double area;
r=2.0;
area= s(r);
printf("area=%f",area);
return 0;
}
圖1 函數(shù)調(diào)用過程的堆棧變化
自動化過程實際反映了C語言程序解決實際問題的算法流程。算法是解決某一問題的執(zhí)行步驟。一般而言,使用C語言進(jìn)行編程之前,需要進(jìn)行相應(yīng)的算法設(shè)計,即構(gòu)思解決實際問題的思路和步驟。一旦這些步驟變成C語言程序語句并形成一個完整的程序,就可以提交給操作系統(tǒng)自動地執(zhí)行這些步驟,這正是計算機(jī)解決問題的高效率的體現(xiàn)。
三、以計算思維為導(dǎo)向的C語言程序設(shè)計課程教學(xué)
1.教學(xué)內(nèi)容
針對計算思維的抽象和自動化兩大本質(zhì)特征,C語言程序設(shè)計課程的教學(xué)內(nèi)容需要在原有的基礎(chǔ)上特別強(qiáng)調(diào)一些針對性的觀點。例如,C語言中的各種數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)可以完成實際系統(tǒng)中各種不同元素的抽象,一個函數(shù)之中的順序語句自動執(zhí)行的基礎(chǔ)是EIP寄存器的加法操作,多個函數(shù)之間的來回自動跳轉(zhuǎn)的基礎(chǔ)是內(nèi)存堆棧區(qū)的支持等。具體強(qiáng)調(diào)的觀點如表2所示。
表2 教學(xué)內(nèi)容中需要強(qiáng)調(diào)的觀點
C語言程序設(shè)計
課程的內(nèi)容 強(qiáng)調(diào)的觀點
C語言概述 程序是對系統(tǒng)的抽象
抽象過程就是C語言的建模過程
自動化過程反映C語言的算法流程
數(shù)據(jù)類型、表達(dá)式和語句 操作對象是對系統(tǒng)特征的抽象
語句是系統(tǒng)自動化執(zhí)行的基本對象
控制結(jié)構(gòu) 控制結(jié)構(gòu)是問題求解步驟的抽象
函數(shù)中順序語句自動執(zhí)行的基礎(chǔ)是EIP寄存器的加法操作
數(shù)組 一維數(shù)組是對多個相同類型的一個系統(tǒng)特征的抽象,多維數(shù)組是對多個相同類型的多個系統(tǒng)特征的抽象
函數(shù) 函數(shù)是對系統(tǒng)功能的抽象
函數(shù)調(diào)用是功能調(diào)用的抽象
函數(shù)之間的來回自動跳轉(zhuǎn)的基礎(chǔ)是內(nèi)存堆棧區(qū)的支持
結(jié)構(gòu)體 結(jié)構(gòu)體是對多個不同類型的多個系統(tǒng)特征的抽象
指針 鏈表是多個不同類型的多個系統(tǒng)特征集合的抽象
2.教學(xué)方式
計算思維的本質(zhì)是抽象和自動化。C語言程
序設(shè)計課程一般都是面向大一新生,理解抽象和自動化進(jìn)而培養(yǎng)計算思維,對于還處在計算機(jī)學(xué)習(xí)起點的學(xué)生來說是比較困難的。
對于C語言程序來說,抽象過程實際就是運用C語言中各種符號對所描述系統(tǒng)的建模過程,培養(yǎng)抽象的計算思維方式就是培養(yǎng)使用C語言描述實際系統(tǒng)的思維過程。因此,可以通過啟發(fā)式教學(xué)方式引導(dǎo)學(xué)生思考如何使用C語言中的符號來描述系統(tǒng)??梢蕴岢鲞@樣的一系列問題:C語言中如何描述一個人的身高?如何綜合描述一個人的姓名、年齡和籍貫等?如何描述一個班中所有學(xué)生的高等數(shù)學(xué)成績?如何描述各路公共汽車站的網(wǎng)狀信息?通過啟發(fā)學(xué)生對這些問題的思考,讓學(xué)生所學(xué)的C語言中的各種符號不再“虛幻”,讓學(xué)生真正理解這些符號實際是一種建模元素,每種符號有著其特別的抽象描述能力。
對于C語言程序來說,理解自動化過程必須借助一些形象化的手段。例如,借助于Visual C++ 6.0平臺的單步調(diào)試功能,可以形象地演示上述C語言程序的自動化過程,如表3所示。
表3 C語言程序執(zhí)行過程中EIP和ESP寄存器內(nèi)容的變化
斷點 EIP寄存器內(nèi)容 ESP寄存器內(nèi)容 當(dāng)前棧頂函數(shù)
r=2.0;語句 00401068 0013FF24 main函數(shù)
area=s(r);語句 00401076 0013FF24 main函數(shù)
return r*r;語句 00401020 0013FF18 s函數(shù)
printf("area=%f",area);語句 00401089 0013FF24 main函數(shù)
從表3可以看出,隨著EIP寄存器內(nèi)容的增加,main函數(shù)中的語句順序自動執(zhí)行,即從語句“r=2.0”到語句“area=s(r)”再到語句“printf("area=%f",area)”。ESP寄存器是另一個重要的寄存器,它始終存放棧頂?shù)牡刂贰kS著main函數(shù)對s函數(shù)的調(diào)用開始,棧頂工作函數(shù)由main函數(shù)變化為s函數(shù);當(dāng)s函數(shù)調(diào)用結(jié)束后,棧頂工作函數(shù)又由s函數(shù)回到main函數(shù)。
3.考核內(nèi)容
針對C語言程序設(shè)計課程的計算思維培養(yǎng)要求,考核方式上必須從以考查語言的語法知識為主轉(zhuǎn)變?yōu)橐钥疾閷W(xué)生的系統(tǒng)建模能力和算法設(shè)計能力為主。
系統(tǒng)建模能力的考查主要針對計算思維的抽象特征。例如,可以給出各種系統(tǒng)特征,考查學(xué)生使用數(shù)據(jù)類型進(jìn)行描述的能力。
算法設(shè)計能力的考查主要針對計算思維的自動化特征。當(dāng)然,C語言程序設(shè)計課程中涉及的都是一些如迭代、枚舉和排序等簡單算法??蓪⑦@些算法封裝成各種函數(shù)來進(jìn)行調(diào)用,以考查函數(shù)中順序語句的執(zhí)行以及函數(shù)間的伴隨參數(shù)傳遞的跳轉(zhuǎn)來理解自動化過程。因此,必須以簡單算
法設(shè)計和函數(shù)調(diào)用為重點考核內(nèi)容,突出對函數(shù)接口設(shè)計和算法流程設(shè)計的考核。
參考文獻(xiàn):
[1] Jeannette M. Wing. Computational Thinking[J]. Communications of the ACM, 2006, 49(3):33-35.
[2] 陳國良. 計算思維[J]. 中國計算機(jī)學(xué)會通訊,2012,8(1):31-34.
[3] 李廉. 計算思維――概念與挑戰(zhàn)[J]. 中國大學(xué)教學(xué),2012(1):7-12.
[4] 張耀文. 基于計算思維的程序設(shè)計課程案例教學(xué)法研究[J]. 重慶電子工程職業(yè)學(xué)院學(xué)報,2012,21(3):149-150.
[5] 吳紹兵. 計算思維和程序設(shè)計能力的培養(yǎng)[J]. 計算機(jī)教育,2011(16):11-14.
摘要:現(xiàn)在單片機(jī)的程序設(shè)計,C51已經(jīng)得到廣泛的推廣和應(yīng)用,算是單片機(jī)的主流設(shè)計程序,甚至可以說作為單片機(jī)開發(fā)人員必須要掌握的一門語言了。本文簡要介紹了Franklin C51交叉編譯器的特點,較詳細(xì)地討論了C51語言程序設(shè)計的基本技巧及其與匯編語言程序的混合編程、中斷處理過程等實際問題。
關(guān)鍵詞:C51;C語言;編程
在研制單片機(jī)應(yīng)用系統(tǒng)時,匯編語言是一種常用的軟件工具。它能直接操作硬件,指令的執(zhí)行速度快。但其指令系統(tǒng)的固有格式受硬件結(jié)構(gòu)的限制很大,且難于編寫與調(diào)試,可移植性也差。隨著單片機(jī)硬件性能的提高,其工作速度越來越快,因此在編寫單片機(jī)應(yīng)用系統(tǒng)程序時,更著重于程序本身的編寫效率。而Franklin C51交叉編譯器是專為80C51系列單片機(jī)設(shè)計的一種高效的C語言編譯器,使用它可以縮短開發(fā)周期,降低開發(fā)成本,因此目前它已成為開發(fā)80C51系列單片機(jī)的流行工具。
一、C51的編程規(guī)范
(一)注釋
1.開始的注釋:
文件(模塊)注釋內(nèi)容:
公司名稱、版權(quán)、作者名稱、修改時間、模塊功能、背景介紹等,復(fù)雜的算法需要加上流程說明;
函數(shù)開頭的注釋內(nèi)容:
函數(shù)名稱、功能、說明 輸入、返回、函數(shù)描述、流程處理、全局變量、調(diào)用樣例等,復(fù)雜的函數(shù)需要加上變量用途說明 ;
2.程序中的注釋內(nèi)容:
修改時間和作者、方便理解的注釋等。注釋內(nèi)容應(yīng)簡煉、清楚、明了,一目了然的語句不加注釋。
(二)命名:
命名必須具有一定的實際意義。
1.常量的命名:全部用大寫。
2.變量的命名:
3.結(jié)構(gòu)體命名:
4.函數(shù)的命名:
函數(shù)名首字大寫,若包含有兩個單詞的每個單詞首字母大寫。
函數(shù)原型說明包括:引用外來函數(shù)及內(nèi)部函數(shù),外部引用必須在右側(cè)注明函數(shù)來源: 模塊名及文件名, 內(nèi)部函數(shù),只要注釋其定義文件名 ;
1.縮進(jìn):縮進(jìn)以Tab為單位,一個Tab為四個空格大小。預(yù)處理語句、全局?jǐn)?shù)據(jù)、函數(shù)原型、標(biāo)題、附加說明、函數(shù)說明、標(biāo)號等均頂格書寫。語句塊的“{”“}”配對對齊,并與其前一行對齊;
2.空格:數(shù)據(jù)和函數(shù)在其類型,修飾名稱之間適當(dāng)空格并據(jù)情況對齊。關(guān)鍵字原則上空一格,如:
if ( ... ) 等,運算符的空格規(guī)定如下:“->”、“[”、“]”、“++”、“--”、“~”、“!”、“+”、“-”(指正負(fù)號),“&”(取址或引用)、“*”(指使用指針時)等幾個運算符兩邊不空格(其中單目運算符系指與操作數(shù)相連的一邊),其它運算符(包括大多數(shù)二目運算符和三目運算符“?:”兩邊均空一格,“(”、“)”運算符在其內(nèi)側(cè)空一格,在作函數(shù)定義時還可據(jù)情況多空或不空格來對齊,但在函數(shù)實現(xiàn)時可以不用。
3.空行:程序文件結(jié)構(gòu)各部分之間空兩行,若不必要也可只空一行,各函數(shù)實現(xiàn)之間一般空兩行
4.修改:版本封存以后的修改一定要將老語句用/* */ 封閉,不能自行刪除或修改,并要在文件及函數(shù)的修改記錄中加以記錄。
二、C51語言程序設(shè)計的基本技巧
C語言是一種高級程序設(shè)計語言,它提供了十分完備的規(guī)范化流程控制結(jié)構(gòu)。因此采用C51語言設(shè)計單片機(jī)應(yīng)用系統(tǒng)程序時,首先要盡可能地采用結(jié)構(gòu)化的程序設(shè)計方法,這樣可使整個應(yīng)用系統(tǒng)程序結(jié)構(gòu)清晰,易于調(diào)試和維護(hù)。對于不同的功能模塊,分別指定相應(yīng)的入口參數(shù)和出口參數(shù),而經(jīng)常使用的一些程序最好編成函數(shù),這樣既不會引起整個程序管理的混亂,還可增強(qiáng)可讀性,移植性也好。
在程序設(shè)計過程中,要充分利用C51語言的預(yù)處理命令。對于一些常用的常數(shù),如TRUE,F(xiàn)ALSE,PI以及各種特殊功能寄存器,或程序中一些重要的依據(jù)外界條件可變的常量,可采用宏定義"#define"或集中起來放在一個頭文件中進(jìn)行定義,再采用文件包含命令"#include"將其加入到程序中去。這樣當(dāng)需要修改某個參量時,只須修改相應(yīng)的包含文件或宏定義,而不必對使用它們的每個程序文件都作修改,從而有利于文件的維護(hù)和更新。
三、C51語言與匯編語言程序的混合編程
C51編譯器能對C語言源程序進(jìn)行高效率的編譯,生成高效簡潔的代碼,在絕大多數(shù)場合采用C語言編程即可完成預(yù)期的目的。但有時為了編程直觀或某些特殊地址的處理,還須采用一定的匯編語言編程。它們必須有完整的約定,否則數(shù)據(jù)的交換就可能出錯。下面就以力源公司的10位串行A/D轉(zhuǎn)換器TLC1549 為例說明C語言程序與匯編語言程序的調(diào)用。
四、C51中斷處理過程
C51編譯器支持在C源程序中直接開發(fā)中斷過程,因此減輕了使用匯編語言的繁瑣工作,提高了開發(fā)效率。中斷服務(wù)函數(shù)的完整語法如下:
void函數(shù)名(void)[模式]
[再入]interrupt n [using r]
其中n(0~31)代表中斷號。C51編譯器允許32個中斷,具體使用哪個中斷由80C51系列的芯片決定。r(0~3)代表第r組寄存器。在調(diào)用中斷函數(shù)時,要求中斷過程調(diào)用的函數(shù)所使用的寄存器組必須與其相同。"再入"用于說明中斷處理函數(shù)有無"再入"能力。C51編譯器及其對C語言的擴(kuò)充允許編程者對中斷所有方面的控制和寄存器組的使用。這種支持能使編程者創(chuàng)建高效的中斷服務(wù)程序,用戶只須在C語言下關(guān)心中斷和必要的寄存器組切換操作。
四、結(jié)語
C51編譯器不但可以縮短單片機(jī)控制系統(tǒng)的開發(fā)周期,而且易于調(diào)試和維護(hù)。此外,C51語言還有許多強(qiáng)大的功能,如提供豐富的庫函數(shù)供用戶直接調(diào)用,完整的編譯控制指令為程序調(diào)試提供必要的符號信息等等??傊?,C51語言是廣大單片機(jī)開發(fā)人員的強(qiáng)有力的工具。
參考文獻(xiàn):
[1]周立功.單片機(jī)實驗與實踐教程(三)[M].北京:北京航天航空大學(xué)出版社.2006
[2]柴鈺.單片機(jī)原理及應(yīng)用[M].北京:西安電子科技大學(xué)出版社.2009