c语言函数范例6篇

前言:中文期刊网精心挑选了c语言函数范文供你参考和学习,希望我们的参考范文能激发你的文章创作灵感,欢迎阅读。

c语言函数

c语言函数范文1

一、格式说明符和输入项的三对应(类型、个数、顺序)scanf函数格式中的格式说明(“%格式字符”)应与输入项数据类型一致,个数相等、顺序对应(除格式说明中出现“*”附加格式说明字符外)。示例一:inta,b;scanf("%d%d%d",&a,&b);printf("%d,%d",a,b);输入“345”时,输出“3,4”,没有错误提示信息,但是第三个数没有接收的变量,也就没有输出。再如inta,b;scanf("%d",&a,&b);printf("%d,%d",a,b);输入“34”时,输出“3,-858993460”,a得到3,但b是一个随机数,都是因为格式说明(“%格式字符”)与输入项个数不一致造成的。再如structst{intnum;charname[10];intage;floatscore;}student;scanf("%d,%s,%d,%f",&student);输入“10001,"zhang",23,68”,运行程序时,无出错信息,但student不能正确接收输入数据。

应该写成:scanf("%d,%s,%d,%f",&student.num,student.name,&student.age,&stu-dent.score);保证格式说明与输入项个数相等、一一对应,才能使student正确接收输入数据。示例二:chara,b;scanf("%d%d",&a,&b);printf("%d,%d",a,b);输入“34”时,输出“3,4”,输入整型数据,是字符型数据接收,但是结果正确,因为字符型数据在内存中的存放形式是整型数据。再如floata,b;scanf("%d%d",&a,&b);printf("%d,%d",a,b);输入“34”时,输出“0,918028288”,即a和b的结果都是随机数,这就是输入格式和接收的数据类型不一样造成的。又如:inta,b;scanf("%f%f",&a,&b);printf("%d,%d",a,b);输入“1.23.4”时,输出“1067030938,1079613850”,即a和b的结果都是随机数,这也是输入格式和接收的数据类型不一样造成的。

二、非格式说明符的输入非格式说明符要求用户原样照写输入,既不能更改,又不能漏写。示例一:inta,b;scanf("a=%d,b=%d",&a,&b);printf("%d,%d",a,b);输入“12”(即1、2间用空格隔开),输出“-858993460,-858993460”,无错误提示,但结果与输入数据不一致,输出a、b的值是随机数。这就是因为scanf函数中设定的格式(“a=%d,b=%d”)(其中a=,b=均为普通字符)与输入数据的格式(1、2间用空格间隔)不一致造成的,正确的输入形式应为“a=1,b=2”(“,”也绝不能漏掉)。所以,为了保证正确输入数据,输入数据前首先看好程序中scanf函数设定的格式,再按照设定的格式正确输入数据。示例二:scanf("%d,%d",&a,&b);输入时应用以下形式:3,4注意3后面应是逗号,它与scanf函数中的“格式控制”中的逗号对应。如果输入时不用逗号而用空格或其他字符是不对的。34(不对)3:4(不对)如果是scanf("%d%d",&a,&b);则输入时两个数据间应空两个或更多个空格字符。如:34或34

三、附加格式说明符的说明示例一:inta,b;scanf("%2d%2d",&a,&b);printf("%d,%d",a,b);输入“1234”,输出“12,34”输入“123”,输出“12,3”输入“123456”,输出“12,34”因为格式中“d”格式字符表示输入整型数据,“2”附加格式说明字符表示输入数据所占宽度为2,因此,无论用户输入什么,系统都将自动截取两位赋给a,再截取两位赋给b。也就是说可以用附加格式说明符指定输入数据所占列数,系统将自动按它截取所需数据。

再如scanf("%3c",&ch);如果从键盘上连续输入3个字符abc,由于ch只能容纳一个字符,系统就把第一个字符‘a’赋给ch。示例二:floata;scanf("%5.1f",&a);输入“1234”,无错误提示,但a并不能接收输入数据,输出a的值为随机数,再尝试输入别的数据,结果都为随机数。用户本意想用这样的scanf格式输入宽度为5位,小数部分为1位的小数,但得不到预想结果。因为,scanf函数中只有“域宽”(此处为5)附加格式说明字符(指定输入数据所占列数),而没有在“小数位数”附加格式说明字符(只有printf函数有),应该去掉“.1”,即scanf("%5f",&a);或scanf("%f",&a);均可,此时输入“123.4”即可接收。所以,应根据scanf函数中规定的格式字符及其附加格式说明字符使用,不能滥用,输入数据时不能规定精度。示例三:doublex;scanf("%f",&x);输入“123.4”,输出x的值为随机数,没有接收输入的数据,再输入别的数据,结果都为随机数。这是因为用户定义x为双精度型数据,而用“%f”格式输入数据时,不能接收,应该使用“%lf”或“%le”,即scanf("%lf",&x);此时输入“123.4”即可接收。

因此长整型数据和双精度型数据必须使用附加格式说明字符l,短整型数据必须使用附加格式说明字符h。示例四:inta,b;scanf("%2d,%*3d,%2d",&a,&b);输入“12,345,67”,此时,12赋给a,67赋给b。注意:原则上“,%格式字符”应与“输入项”(&a,&b)个数相等,一一对应,此处则出现了个数不等的情况(“%格式字符”项数为3,而输入项数为2)。因为scanf函数中有附加格式说明字符“*”,加“*”项表示输入的数据不赋给相应变量,因此输入的“345”被跳过,接收下一个数据(“67”),致使“%格式字符”与“输入项”个数可以不等的情况出现。在利用现成的一批数据时,有时不需要其中某些数据,可用此法跳过它们。例如scanf("%c%c",&a,&b);printf("%c%c",a,b);输入AB,输出A‘,A’给了字符变量a‘,’作为合法字符给了字符变量b。这时我们改用scanf("%c%*c%c",&a,&b);输入AB,输出AB,‘A’给了字符变量a‘,’被%*c跳过‘,B’就给了字符变量b。可见,使用scanf函数时,要在scanf规定的格式字符及其附加格式说明字符下使用。既不能不用,又不能滥用。

四、注意输入结束标志①遇到空格,或者回车键,或者Tab键。如果相邻两个格式指示符之间,不指定数据分隔符(如逗号、冒号等),则相应的两个输入数据之间,至少用一个空格分开,或者用Tab键分开,或者输入一个数据后,按回车,然后再输入下一个数据。在用“%c”格式输入字符时,空格字符和“转义字符”都作为有效字符输入。示例一:scanf("%d%d",&num1,&num2);假设给num1输入12,给num2输入36,则正确的输入操作为:1236或者:1236示例二:scanf("%c%c%c",&c1,&c2,&c3);如果从键盘输入abc则字符‘a’赋给c1,字符‘’赋给c2,字符‘b’赋给c3。因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔空格,因此空格作为下一个字符赋给c2。

c语言函数范文2

关键词:函数;形参;实参;数据传递

中图分类号:TP312文献标识码:A 文章编号:1009-3044(2007)17-31457-01

Analysis of Data Transferring from Actual Argument to Formal Argument in C Language Function Calling

LU Xiang-ning, LI Xiao-mei

(Hainan Software Professional Institute, Qionghai 571400,China)

Abstract: C's design philosophy is to use functions as building blocks. When a function is called, value of the actual argument is assigned to the variable known as the formal argument. This paper presents that the essence of data transferring from actual argument to formal parameter is value delivery and one-way.

Key words: functions; formal parameters; actual arguments; data transferring

1 引言

在C语言教学过程中,我发现有很多初学者对函数调用过程中实参和形参之间的数据传递问题理解不够透彻,尤其是指针做函数参数时,常常有许多误解。有这样一个程序:

#include

main()

{

void swap(int *p1,int *p2);

int a,b;

int *point1,*point2;

clrscr();

scanf("%d,%d",&a,&b);

point1=&a;point2=&b;

if(a

printf("a=%d,b=%d\n ",a,b);

printf("max=%d,min=%d\n ",*point1,*point2);

}

void swap(int *p1,int *p2)

{

int *temp;

temp=p1;

p1=p2;

p2=temp;

}

编程者的目的很明显,即编写用户自定义函数void swap(int *p1,int *p2),并以整型指针作为参数,在main()函数中调用这一函数来实现两个整型数据a和b的值的互换。但这个函数能否实现两个数值的交换呢?下面我们对其进行分析。

2 函数调用过程分析

在前面这一程序的main()函数中,整型指针变量point1、point2分别指向整型变量a、b,即point1 和point2的值分别为变量a和b的地址。在调用函数swap()时实参(point1,point2)将各自的“值”传递给形参(p1,p2) 。如图1所示(图中虚线箭头表示数据的传递方向,实线箭头表示指向),由于point1 和point2的值分别为变量a和b的地址,所以p1和p2也分别得到变量a和b的地址,即p1和p2也分别指向变量a和b。

图1 实参向形参进行“值”的传递

实参向形参进行“值”的传递之后,执行swap()函数的函数体部分,当执行语句“temp=p1;” 后,将p1的值(主函数中整形变量a的地址)赋给指针变量temp,这时temp也指向了变量a,如图2所示。

图2 执行赋值语句temp=p1;后

执行赋值语句“p1=p2;”,将p2的值(主函数中整形变量b的地址)赋给p1,这时p1不再指向变量a,而指向了变量b,如图3所示,temp和p2的指向不变。

图3 执行赋值语句p1=p2,后

最后执行赋值语句“p2=temp;”,将temp的值(主函数中整形变量a的地址)赋给p2,这时p2的值发生改变,不再指向变量b,而指向变量a。如图4所示。

由上述讨论可以看出,编程者调用swap()函数,仅仅改变了形参变量p1和p2的值,即改变了p1和p2的指向,而这一过程中实参变量point1 和point2并没有指向。swap()函数调用结束后,形参所占内存单元被释放,形参变量p1和p2以及局部指针变量temp消亡。因此,该程序调用swap()函数的执行结果就是改变了通过中间指针变量temp交换了两个形参变量p1和p2的指向,对main()函数没有起到任何作用。

3 函数的改正及问题分析

前例中,调用swap()函数虽然不能改变实参指针变量point1 和point2的值(即它们的指向),但是我们可以改变point1 和point2所指向的内存单元当中的值,即改变整型变量a、b的值。对swap()函数做如下修改:

void swap1(int *p1,int *p2)

{ int temp;

temp=*p1;

*p1=*p2;

*p2=tem}

分析修改后的函数swap1()可知,在函数swap1()调用执行过程中,不仅没能改变实参指针变量point1 和point2的指向,形参指针变量p1和p2的指向也一直没有改变,只是交换了是p1和p2指向的内存单元中的值,即使a、b值互换。

这样以来,就实现了函数调用的功能,达到了编程者的目的。

然而,也有很多人将swap()函数修改为如下形式:

void swap2(int *p1,int *p2)

{ int * temp;

*temp=*p1;

*p1=*p2;

*p2=*tem}

函数swap2()中,编程者以整型指针变量temp为中间变量,交换p1和p2所指向的内存单元中的值,是否能达到这个目的呢?

启动TUBOR C编译环境中,如前例在主函数中对swap2()函数进行调用,编译时 “*temp=*p1;” 语句出现警告,忽略这个警告,运行程序,并输入5,9按回车键,运行结果如图5。

显然,编程者的目的没有达到,执行swap2()函数的过程中,指针变量temp和p1指向了同一个内存单元,并将p2所指向的内存单元中的值赋给p1所指向的内存单元,即将main()函数中变量b的值赋给变量a,因而出现了图示结果。

函数swap2()中问题出现在语句“*temp=*p1;”,对指针变量temp的这种使用方式存在很大的冒险性。由于指针变量temp并没有确定的地址值,所以temp的指向是不可预测的,对*temp赋值可能会造成重要数据的丢失,应避免指针变量的这种使用方式。

4 结论

通过这个例子,本文浅析了函数调用过程中实参与形参之间数据传递的实质,即“值传递”,就好像是实参把自身的数值拷贝了一份给形参,这种“值传递”是单向的,即由实参传递给形参,形参无法改变实参的值。笔者认为这种提法不仅有失准确性,还给初学者造成了概念上的混淆,误认为传递的是实参变量的地址。初学者在学习C语言过程中,往往“谈指针色变”,理解指针做函数参数的情况更是难于上青天,本文结合实例,阐述了函数调用过程中实参对形参的“单向值传递”性,希望对广大初学者有所帮助。

参考文献:

[1]谭浩强.C程序设计[M] .北京:清华大学出版社,2000.186-189.

[2]陈家骏.程序设计教程用C++语言编程[M]. 北京:机械工业出版社,2004.155-160.

[3]Herbert Schildt,著.戴健鹏,译.C语言大全(第2版)[M]. 北京:电子工业出版社,1994.120-125.

c语言函数范文3

关键词: Sleep;循环;硬件思维;指针

中图分类号:TP312.1 文献标识码:A 文章编号:1671-7597(2012)0210144-01

0 引言

循环嵌套对于初学者来说是个难以理清的知识点,尤其是内层循环和外层循环之间的关系也只能是靠多加练习来体会;虽然断点测试可以清晰的看到运行情况,但是复杂的地址和中间值对于初学者来说更难理解。我们这里借用一些辅助函数,比如说Sleep函数,来使嵌套的层次更加清晰,使break和contimue的对循环的影响更加清楚。指针更是让许多学生望而怯步,归根到底是学生对于硬件知识的缺乏,我们这里采用先对学生讲解内存存储原理的方式,是学生对指针的认识更加直接和深入。

1 Sleep函数在循环嵌套中的妙用

在学习循环嵌套的时候,我们往往都是写完代码后一次性将最终结果显示在窗口,或者一次性将所有的结果显示在窗口,这样就很难看清每次循环所做的具体事情。虽然我们可以用断点测试来看程序运行的具体情况,但是断点测试对于初学者来说太过复杂。在这里我们用一个比较直观的例子,再加上一些辅助函数来了解循环和循环嵌套的详细过程。

例1:用C语言实现一个格式为“分:秒:毫秒”,范围为00:00:00~19:59:99。

我们这里首先根据题意分析可得,1秒=1000毫秒,这里我们毫秒采用两位,即99代表990毫秒。我们采用6个int类型变量m1(分的十位),m2(分的个位),s1(秒的十位),s2(秒的个位),ms1(毫秒的百位),ms2(毫秒的十位),他们之间的进位关系为:1m1=10m2,1m2=6s2,1s1=10s2,s2=10ms1,1ms1=10ms2,利用这些变量之间的进制关系,我们采用6层for循环嵌套来实现,循环部分的核心代码如下:

这样实现的结果根本做不到秒表读秒的效果,也看不出循环执行的具体层次。所以我们引入Sleep函数,并利用“\r”来打到比较好的读秒效果。在VC里面加上头文件#include,便可利用Sleep函数将程序挂起(暂停)一段时间,时间长短取决于Sleep(unsigned long)函数中的参数,其参数代表毫秒,Sleep(1)表示将程序在此挂起1毫秒,在本例题里,我们采用Sleep(10)表示将程序每执行一次printf函数就挂起10毫秒,刚好和秒表的右边第一位跳一次的时间相等。利用“\r”返回行首,这样我们改造后的代码为:

return 0;}如此一来,我们就实现了秒表的效果。通过秒表的贴近日程生活的进位显示现象,我们可以非常清晰的看出循环嵌套之间的层次,从而对循环嵌套有一个一步到位的清楚认识;并通过添加Sleep函数的使用,还对学生自主拓展知识有一定的引导作用。

2 硬件思维在理解指针中的妙用

语言课是学生的入门课,由于没有地址的概念,所以对于指针的认知一直都是难点。我们这里先向学生介绍内存及内存地址的组织情况,从内存地址的角度来讲解指针,这将是学生对指针的认识和掌握有个一步到位的认识。

所谓指针,其实就是所需的操作数的地址,我们这里以简单的直接一次间接寻址为例,我们先看一下内存和内存地址的简单组织情况:

我们举一个简单的例子来说明,例如有如下定义:

int a=1000,*p;

p=&a;

这里的内存和内存地址结构我们就以上面简单的形式组织,以典型的32位字长为例,变量值和指针(地址)均可放到内存单元中。刚开始定义变量a并赋予其初始值1000的时候,我们是将变量a的值1000存到000号单元中,然后定义指针变量p时是将008号单元分配给指针变量p,也就是说008单元中放的是指针变量p;p=&a操作是让指针变量p指向变量a,也就是将008单元中的指针变量值具体化为000,在以后的通过指针p引用变量a的时候,*p中的*的意思是指:取指针变量p的值(000)作为地址去找操作数,而000号单元中放的就是变量a。这也就是在引用时,*p和a是等价的。

利用内存结构还很容易在函数中用指针传参能改变变量的值,而通过普通变量传参因为作用域的问题而无法改变变量值。例如有如下代码:

输出结果中,a=1b=4,在调用函数fun的时候,第一个参数传的是变量a的值,但是main函数中的a和fun函数中的a并不是一个变量,000单元中的变量a是main函数中的a,003中的a是fun函数中的a,a=3是对fun中的a赋值,并未对main函数中的a做出任何改变;但fun函数中的*q=4是对q中的地址001中的变量b进行赋值,而001中的变量b刚好是main函数中的b,所以main函数中的printf语句输出的a还是1,而b则变成了3。

以上就是硬件思维在指针学习中的作用。

参考文献:

c语言函数范文4

关键词:C语言;函数;调试技术

中图分类号:G642.4 文献标志码:A 文章编号:1674-9324(2014)11-0085-02

C语言是一门函数式语言。学习C语言编程必须学好函数的使用。笔者在多年的教学过程中,发现学生在学习函数的过程存在一些问题。虽然这些内容教师在课堂上都十分认真地讲解,但有些学生还是觉得内容很抽象,不容易理解。程序调试技术一般用在程序查错上。在程序调试的过程中,可以看到程序的执行过程,包括函数的调用过程、形参实参的传递,变量的内存地址等内容,这样可以很直观地给学生讲解函数的相关内容,因此笔者在函数的教学中使用了程序调试技术,使教学内容不再抽象,而是具体化,使学生能够更好地掌握相关知识,达到了较好的结果。

程序调试技术在函数教学中的具体使用:

1.通过调试技术直观地查看函数的调用过程。首先设计一个简单的使用函数的实例,jc函数实现计算n的阶乘。在main函数中通过函数调用来求任意一个整数的阶乘。double jc(int n),{ double mul=1;//……2,int i;for(i=1;i

2.通过程序调试技术了解函数参数传递过程和局部变量的概念。在函数教学中,形参和实参的关系往往是学生容易出错的地方。形参和实参是两个不同的变量,实参的作用就是给形参传值。而函数的形参以及函数内定义的变量都是函数的局部变量,只能在该函数中使用。而在调试中通过查看变量的值可以很清晰地看到这些知识的作用,则比较生动具体。在上例中,程序在断点停下后,选择debug工具栏中的watch项,打开watch对话框,在对话框中输入num和n,如图3所示,此时num的值是5,而由于jc函数还没有被调用,形参n还不存在。然后选择Step into(F11)项,跟踪进到jc函数内部查看,注意观察watch对话框的变化,发现n的值变为5,而num失效了,如图4所示。这说明程序的执行进入到jc函数,形参变量n被创建并从实参获得了值5。而num是main函数的局部变量,在其他函数中如jc函数中是无法访问的,从而失效。

3.通过调试技术加强对指针做函数参数的内容的理解。在讲解函数的过程中,指针做参数是重点和难点之一。教师在教学过程中强调指针做形参,可以突破局部变量的限制而访问到其他函数的局部变量,这在以后的函数使用中经常用到。但学生觉得很难理解。笔者通过调试技术运行一个实例,查看实际的运行过程,来加深学生对内容的理解。首先设计一个简单的指针做参数的实例。void fun(int * q){*q=10;//…….2}int main(){int n=89;int * p=&n;fun(p);//…….1printf("n=%d\n",n);return 0;},在标号1处设置断点。调试运行该程序,在断点处停下,p是fun函数的实参。此时选择debug工具栏中的watch项,打开watch对话框,分别输入p和&n,如图5所示,它们值相同,都是0x0012ff44,表示n的内存地址。然后选择Step into项跟踪进入fun函数内部执行,由于p和n是main函数的局部变量,在fun函数内部无法访问,它们的值失效。然后,在watch对话框中再输入q和*q,则可以看到如图6的内容。说明形参q从实参p获得了值0x0012ff44,即q也保存了main函数中n的地址,而*q的意思是通过q保存的地址访问该地址所表示的变量。继续单步执行,返回到main函数执行,此时查看n的值,果真变为了10。即在fun函数内部通过指针变量改变了main函数中局部变量的值。

笔者在实际的函数教学中采用了程序调试技术,让学生直观地看到了程序的运行过程,从而加深了学生对函数调用过程、参数传递、指针做参数等内容的理解。学生反应良好。计算机技术总是在不断的发展,教师还要不断地探索更好的教学方法,使C语言课程的教学质量进一步提高。

参考文献:

[1]谭浩强.C程序设计(第四版)[M].清华大学出版社,2010.7.

c语言函数范文5

关键词:Copula函数;交叉货币;汇率风险

中图分类号:F832 文献标识码:A 文章编号:1672-3198(2010)02-0050-02

1 Copula相关理论

资产组合尤其是含有不同种类资产的资产组合(股票和外汇),各种金融资产边缘分布函数通常不符合同一类型的分布函数,这种情况使得多元分布函数很难在资产定价理论中得到应用。而通过Copula函数技术可以构造灵活的多元分布函数。

Copula函数是指把多个变量的联合分布与它们的边缘分布连接在一起的函数。如果F1,…,Fd是一元分布函数,ui=Fi(xi),i=1,…,d,则C(F1(x1),…,Fd(xd))是具有边缘分布函数F1,…,Fd的多元分布函数。d维Copula函数C是把多个随机变量ζ1,…,ζd的联合分布与它们各自的边缘分布连接在一起的函数。Copula函数对于构造和模拟多元分布函数具有重要的意义。根据关于Copula函数最重要的Sklar定理:

令F是具有边缘分布函数F1,…,Fd的d维分布函数,若边缘分布函数F1,…,Fd连续,则存在一个唯一满足F(X,…,xd)=C(F1(x1),…,Fd(xd))关系的连接函数C。

对于多元连续分布函数,一元边缘分布函数和多元分布函数相关结构能够被分离,多元变量之间的相关结构可以用适当的Copula函数表示。Copula函数与多元分布函数一样,包含随机变量之间的所有相关信息。

2 选择合适的Copula函数

Copulas函数的类型很多,总体可以分为椭圆类分布函数连接函数和阿基米德连接函数(Archimedean copulas),而每一类又分为许多具体的连接函数。具体在定价理论中,选择哪一种连接函数要考虑到两方面。首先:看这种Copula函数的特征是否与现实金融市场中金融资产收益率之间的相关性相符合。其次;看这种Copula函数在实际应用中的可行性,是否存在计算技术上的难题。

在现实的金融市场中,各种金融资产的收益率并不符合正态分布的假设条件,通常表现为“尖峰”和“厚尾”的特征。与此同时,各种金融资产的收益率之间也不符合多元正态分布的假设,呈现出尾部极值相关性。符合此特征的分布函数主要有t-Copula连接函数和阿基米德连接函数中的Clayton类连接函数。在Clayton类连接函数中,一般的Clayton连接函数只能度量单侧极值相关,只有Joe-Clayton连接函数在分布的上下尾部均具有相关性,而且这种相关性是非对称的。从理论上讲它比t-Copula连接函数更完美。Patton]用Joe-Clayton连接函数对外汇资产风险进行的研究,证明了其良好的特性。但是目前Joe-Clayton连接函数只能是限于二维的情况,在维数增加时,其计算任务是复杂和繁琐的,实际中很难运用。 研究金融资产收益相关性时,t连接函数能够反映尾部相关性,而高斯连接函数不等反映尾部相关性。当自由度v∞,除非在ρ=1,否则尾部相关系数将变为零,此时,t连接函数与Gauss 连接函数相同。因此,t连接函数比Gauss 连接函数应用更广泛。

3 国外文献综述

国外关于Copula函数在交叉货币衍生产品定价研究中的应用:Wei(1997)对交叉外汇衍生产品进行了综合研究。Matthew Hurd, Mark Salmon, Christoph Schleicher(1998)通过用Copula函数将欧元-英镑和美元-英镑汇率的隐含期权边际分布连接起来,建立两者的风险中性联合分布模型。研究结果表明标准参数的Copula函数,例如常用的正态Copula和Frank Copula,不能通过观察数据得到不对称的程度。他们通过使用一种Bernstein形式的非参数基础函数克服了这个问题,得到一个非常接近的拟合,最后他们将这种方法运用到货币指数期权定价实证研究中。Embrechts(2001)探讨了在金融市场中采用线性相关指标度量相依性有其局限性,使用Copula 函数导出的相依性指标更加符合金融市场的实际。Patton(2001)构造了马克-美元和日元-美元汇率的对数收益的二元Copula 模型,并与相应的BEKK 模型做了比较,结果表明Copula 模型可以更好地描述金融市场间的相关关系。

Lindsog和NcNeil(2003)给出了金融相关的Copulas及相关性概念的测量,着重集中在椭圆的Copulas,Archimedean Copulas和Marshall-Olkin Copulas及保险风险和市场风险(VaR)的运用上面;Ernst Eberlein and Nataliya Koval(2006) 将伦敦银行同业拆息市场模型引入交叉货币衍生产品的定价理论中,详细研究了外汇汇率的上限和下限以及交叉货币互换理论,引用了建立在双边拉普拉斯变换基础上的有效定价算法,并给出了关于欧元-美元交叉货币货币实例进行校正检验。Mark Salmon, Christoph Schleicher(2006)用Copula函数对多变量货币期权进行定价,使用Bernstein Copula函数作为Copula的一种一般的近似过程。Sami Attaoui(2006)以现货而不是远期外汇汇率的动态变化为依据研究概率测度的变化,得到外汇远期伦敦银行同业拆息利率更为丰富的动态变化过程,解决了对伦敦银行同业拆息市场模型中交叉货币衍生产品的定价。

4 国内文献综述

国内关于Copula函数在交叉货币衍生产品定价中的应用:陈松男(2002)对交叉外汇远期合约和期权的定价进行了详细的介绍。张尧庭(2002a),(2002b)从理论上探讨了Copula 在金融上应用的可行性,指出在不确定线性关系能否正确度量相关关系时,采用一种更为灵活稳健的相关性分析工具- Copula 技术来分析变量间的相关结构更为可靠。孙志宾、顾岚(2004)讨论Copula理论中存在的一些问题和未来要解决的问题的一些思想和方法,指出Copula理论在金融中的应用价值。张世英等(2004)研究了Copula -GARCH 模型对波动性的描述。吴振翔等(2004)运用Archimedean Copula 给出了确定两种外汇最小风险(VaR)投资组合的方法。朱光、陈厚生、李平(2006) 具体地研究了Copula 函数与极大和极小欧式期权价格的关系,并给出了该种期权价格的表达式。邵美琴(2007)运用风险中性定价原理,利用偏微分方程的方法,求出了四类汇率联动期权的定价公式。分析资产价格的“波动率微笑”现象,在资产价格服从跳-扩散模型的基础上,进一步考虑汇率联动期权的定价问题,并得到了期权应满足的积分-微分方程。龚朴,黄荣兵(2008)采用时变条件t-copula模型对我国人民币汇率制度改革前后美元、欧元和日元兑人民币汇率之间的相关性进行了研究,研究表明人民币汇率制度的改革使得美元与欧元兑人民币汇率、美元与日元对人民币汇率之间扭曲的相关性得到了较大程度的矫正,为外汇组合风险的管理提供了参考。

从目前国内外的研究来看,利用Copula函数对交叉货币衍生产品进行定价的研究已经引起国内外研究学者的高度重视与广泛兴趣,并吸引了不少优秀的研究人员加入该领域。国内外学者对Copula连接函数在金融领域的应用研究主要集中于风险管理、投资组合方面,缺乏把Copula函数引进现有资产定价理论的分析,尤其是基于Copula函数基础上的交叉货币衍生产品定价研究。

c语言函数范文6

【关键词】CDMA系统;功率控制;效用函数

1.引言

频分多址(FDMA)、时分多址(TDMA)、码分多址(CDMA)是无线移动通信系统中三种基本的多址接入技术。由于CDMA扩展频谱通信比其他技术至少能提高三倍以上的系统用户容量。CDMA抗干扰能力强,采用最新的数字编码技术,保证了即使在很低的信噪比环境下也能恢复信息,所以,这种数字编码技术,还提供了更高的安全性和保密性。CDMA采用“软切换”,即用户在小区边缘时,并不是先断掉与原来小区基站的联系,而是先与新的小区基站建立连接后,方断开与原小区基站的联系,即“先连后断”,从技术上保证了越区切换时,掉线率基本为零。正由于以上显著的优势,CDMA作为第三代移动通信的标准。

任何技术都不是完美的,CDMA系统也不例外,也会存在一些问题。例如在上行链路(移动台到基站)中,如果本小区中所有的移动台都是相同的发射功率,由于移动台与基站(BS)间距离不同及无线信道固有的衰落,基站接收到的离基站近的移动台的信号功率要比接收到的离基站远的移动台的信号功率强,对于离基站远的移动台来说也是一种干扰,,称之为“远近效应”。CDMA要克服“远近效应”,就要进行功率控制,即离基站较近的移动台以较小的发射功率发射信号,离基站较远的移动台使用较大的发射功率,以抵偿无线信道衰落。

同时CDMA系统中又存在“边缘效应”,即在下行链路(基站到移动台)中,处于小区边缘的移动台,不仅接受本小区基站发射的功率较小,而且还会受到邻近小区信号的干扰。这种干扰会导致通信质量严重下降。为了克服CDMA系统中的“边缘效应”和“远近效应”,通常采用CDMA功率控制技术,即控制发射端的发射功率,补偿信道衰落,减少小区间的干扰。在达到服务质量要求时,通过功率控制技术减小移动台的发射功率,可以延长移动台电池的使用寿命。

功率控制可以分为前向功率控制、反向功率控制、集中式功率控制及分布式功率控制等。前向功率控制是通过对基站发射的功率进行控制,集中式功率控制指在基站侧进行功率控制,根据接收端收到信号的功率及通信链路的增益来实时的调整其发射功率。分布式功率控制是每个小区根据当前测量到的信干比及当前的发送功率来确定最佳的发射功率。

2.引入效用函数

效用函数(Utility Function)是最常用的经济学理论的概念,用来描述用户在消费商品时所获得的效用与所消费的商品之间数量关系的函数。即用户体验到的商品服务满意度。

定义:效用函数u,是一个从实数集合A到另一个实数集合B的一个映射,记为u:AB,如果对于任意x,yA,并且满足u(x)≥u(y)时,表明行为x比行为y的效用高。

在通信系统中,当其信干比SIR(记为),低于门限值0时,用户得不到满意的通话效果,即效用函数值为零。当实际信干比≥0时,用户获得满意的通话效果,此时效用函数值为1。这里可以看出,话音用户对于的微小变化是不敏感的。对于数据通信系统,一般是以包的形式发送信息。这里假定,测所有的错误,并且所有错误数据都可以重传。因此系统的吞吐量接收机有能力检T可以表示为:

这里,R表示用户的信息传输速率,f()是传输协议效率的一种度量。注意,协议的效率取决于信宿所接收到的信干比SIR,f()[0,1]。信宿端较高的信干比SIR意味着有较低的误码率BER,说明f()效率较好。假设移动用户j的电池能量为E(J),移动用户j的发射功率为pj,那么该移动用户的的效用函数可记为uj(pj,j),即为在电池能量范围内,在通信过程中信宿端正确接收到的比特数。该模型的效用函数u可表示为:

仍然来考虑一个典型的CDMA无线通信系统,假设该CDMA系统为一个BS和n个MS,当CDMA系统的上行链路的功率控制的效果较好时,小区间的干扰非常小,故在该模型中可忽略不计。

3.分布式传统算法及其仿真结果分析

下文描述了一个传统的分布式功率控制算法,其发射功率p计算如下[6]。

使用matlab工具对分别对分布式传统算法和改进后的分布式算法进行仿真。

设置此次仿真参数如下:小区用户数为Num=10个,其中扩频增益L=128,目标信干比=10,初始试探发射功率p0=0.001。

仿真结果截图如下:

由仿真结果可以分析出,经过一定迭代次数后,发射功率和信干比SIR都可以趋于稳定,但是从仿真结果可以明显看出传统算法的收敛速度较慢,发射功率大概要经过25次迭代时趋于稳定,信干比SIR大概要经过15次迭代才趋于稳定状态。

4.改进后的算法及其仿真结果分析

跟据高等数学知识可知,形如(4)、(5)的常级数迭代方式的收敛速度较慢。若要加快发射功率和信干比的收敛速度,我们可以采用相应幂级数迭代的形式,已达到快速收敛的目的。如下是一种改进后的采用幂级数形式的分布式功率控制算法:

(6)

= (7)

使用matlab工具对分别对分布式传统算法和改进后的分布式算法进行仿真。

设置此次仿真参数如下:小区用户数为Num=10个,其中扩频增益L=128,目标信干比=10,初始试探发射功率p0=0.001。

观察改进后算法的仿真结果图,可明显看出幂指数迭代算法较传统算法在收敛速度上有很大提高。

发射功率收敛速率比较:传统算法大概在第25次迭代时,发射功率才趋于稳定。而改进后的算法,其发射功率大概在第5次迭代时就趋于稳定状态。

信干比SIR比较:传统算法大概在第15次迭代时,信干比才趋于稳定。而改进后的算法,其信干比大概在第4次迭代时就趋于稳定状态。

由此可见,无论是从发射功率的收敛速度还是信干比的收敛速度,通过改进后的算法较传统算法均有很大的改进。

5.结束语

综上所述,改进后的基于效用函数分布式功率控制算法,在保证信干比SIR的情况下,有较小的发射功率。况且收敛速度较传统算法有明显提高。

参考文献

[1]纪越峰.现代通信技术[M].北京:北京邮电大学出版社,2000.

[2]吴伟陵.移动通信中的关键技术[M].北京:北京邮电大学出版社2000.

[3]朱钧.无线移动信道的仿真[M].上海:同济大学出版社,2005.

[4]Tehodore S.Rappaport著.蔡涛等译.无线通信原理与应用[M].北京:电子工业出版社,1999,11.

[5]王枫.DS-CDMA移动通信系统中功率控制策略的研究[D].长沙:湖南大学,2005.

[6]吕玲,朱世华,汪永刚.一种基于模糊逻辑的外环功率控制算法[J].通信学报.2002,23:2.

[7]姚国庆.博弈论[M].天津:南开大学出版社,2002.

[8]W.C.Jakes(Ed),Microwave Mobile Communications,New York,NY,Wiley,1974.

[9]Savo Glisic,Branka Vucetic,Spread Spectrum CDMA Systems for Wireless Communications,Dedham,MA,Artech House,Inc,1997,Ch.5,211-262.