1. 首页>动态 > 动态

函数调用语句(函数调用)

作者:陈悦林
2023年07月05日 11:05
动态

你们好,最近小元发现有诸多的小伙伴们对于函数调用语句,函数调用这个问题都颇为感兴趣的,今天小活为大家梳理了下,一起往下看看吧。

1、 在实际工程项目中,一个程序通常由许多子程序模块组成,每个模块实现一个特定的功能。在C语言中,这个模块由一个函数来表示。一个C程序一般由一个主函数和几个其他函数组成。

2、 主函数可以调用其他函数,其他函数也可以相互调用,但是其他函数不能调用主函数。在我们的51单片机程序中,还有一个中断服务函数,在相应的中断到来时自动调用,不需要也可以由其他函数调用。

3、 函数调用的一般形式是:函数名(参数列表);函数名是被调用函数的名称,实参表是根据实际需求调用函数时要传递给被调用函数的参数列表,不传递参数时只需要括号。

4、 当传递多个参数时,参数之间应该用逗号分隔。

5、 那我先举个例子函数调用在让程序结构更连贯方面的作用。回顾图6-1所示的程序流程图和为实现它而编写的程序代码,这个主要功能的结构是比较复杂的。

6、 很难一目了然的看到它的实现过程。那么如果我们用单独的函数来实现两个最重要的东西,数码管的——秒计数和动态扫描功能呢?看节目。

7、 #include reg52.h

8、 sbit ADDR0=P1^0;

9、 sbit ADDR1=P1^1;

10、 sbit ADDR2=P1^2;

11、 sbit ADDR3=P1^3;

12、 sbit ENLED=P1^4;

13、 无符号char码LedChar[]={//数码管显示字符换算表。

14、 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,

15、 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E

16、 };

17、 无符号烧焦buff[6]={//数码管的显示缓冲区,初始值为0xFF,保证启动时不亮。

18、 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF

19、 };

20、 void SecondCount();

21、 void LedRefresh();

22、 void main(){

23、 ENLED=0;//使能U3,选择控制数码管。

24、 addr 3=1;//因为ADDR0-2的值需要动态改变,所以不需要初始化。

25、 TMOD=0x 01;//将T0设置为模式1。

26、 TH0=0xFC//将初始值0xFC67赋给T0,时序为1 ms。

27、 TL0=0x67;

28、 TR0=1;//开始T0

29、 while (1){

30、 If (TF0==1){ //判断T0是否溢出。

31、 TF0=0;//在//T0溢出后,清除中断标志。

32、 TH0=0xFC//并再次赋予初始值

33、 TL0=0x67;

34、 SecondCount();//调用第二个计数函数

35、 led refresh();//调用显示刷新函数

36、 }

37、 }

38、 }

39、

40、 void SecondCount(){

41、 Static unsigned integer count=0; //Record the number of T0 interrupts.

42、 Static unsigned long integer seconds=0; //Record the elapsed seconds.

43、 cnt//计数值增加1。

44、 If (cnt=1000){ //判断T0是否溢出1000次。

45、 CNT=0;//达到1000次后,计数值清零。

46、 sec//第二次计数增加1。

47、 LedBuff[0]=LedChar[sec%10];

48、 LedBuff[1]=LedChar[sec/10%10];

49、 LedBuff[2]=LedChar[sec/100%10];

50、 LedBuff[3]=LedChar[sec/1000%10];

51、 LedBuff[4]=LedChar[sec/10000%10];

52、 LedBuff[5]=LedChar[sec/100000%10];

53、 }

54、 }

55、

56、 void LedRefresh(){

57、 静态无符号字符I=0;//动态扫描的索引

58、 switch (i){

59、 case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;

60、 case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;

61、 case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;

62、 case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;

63、 case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;

64、 case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;

65、 default: break;

66、 }

67、 }

68、 我们来看看主函数的结构是不是清晰很多。——每1 ms做两件事,至于这两件事是什么,就让它们各自的功能来实现吧。还请注意一点:原程序

69、 I,cnt,sec都添加了静态关键字,放入单独的函数后成为静态变量。因为原版

70、 main()永远不会结束所以它们的值也总是得到保持的,但现在它们在各自的功能函数内,如不加static

71、 修饰那么每次函数被调用时它们的值就都成了初值了,借此也把静态变量再加深一下理解吧。当然,这是我们刻意把程序功能做了这样的划分,主要目的还是来讲解函数的调用,

72、 对于这个程序即使你不划分函数也复杂不到哪里去,但继续学下去你就能领会到划分功能函数的必要了。现在我们还是把注意力放在学习函数调用上,

73、 有以下几点需要大家注意:1) 函数调用的时候,不需要加函数类型。我们在主函数内调用SecondCount()和LedRefresh()时都没有加void。

74、 2) 调用函数与被调用函数的位置关系,C

75、 语言规定:函数在被调用之前,必须先被定义或声明。意思就是说:在一个文件中,一个函数应该先定义,然后才能被调用,也就是调用函数应位于被调用函数的下

76、 方。但是作为一种通常的编程规范,我们推荐main

77、 函数写在最前面(因为它起到提纲挈领的作用),其后再定义各个功能函数,而中断函数则写在文件的最后。那么主函数要调用定义在它之后的函数怎么办呢?我们

78、 就在文件开头,所有函数定义之前,开辟一块区域,叫做函数声明区,用来把被调用的函数声明一下,如此,该函数就可以被随意调用了。如上述例程所示。3)

79、 函数声明的时候必须加函数类型,函数的形式参数,最后加上一个分号表示结束。函数声明行与函数定义行的唯一区别就是最后的分号,其它的都必须保持一致。这

80、 点请尤其注意,初学者很容易因粗心大意而搞错分号或是修改了定义行中的形参却忘了修改声明行中的形参,导致程序编译不过。

以上就是函数调用这篇文章的一些介绍,希望对大家有所帮助。

推荐阅读