天天看点

函数内容学习小结函数内容学习小结

函数内容学习小结

函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由自己来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。

函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

创建 C 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。

函数返回值最多只有一个,若需要通过被调函数同时得到多个结果,那是行不通的;

函数的参数(实参与形参)的关系,在 C 语言函数中,只有一种:值传递(传递的是值,只不过这个值可能是普通的值,也可能是地址值),且这种传递方式所产生的必然结果是:对被调函数的形参变量所进行的任何更改,绝对不会影响主调函数的实参的值!

函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

当调用函数时,有两种向函数传递参数的方式:传值和传指针

调用类型 描述
传值调用 该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
传指针调用 通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

传值调用

我们在初学C语言的时候就被老师教过,下面的方式是无法交换a和b的值的:

#include<stdio.h>
void swap(int a,int b)
{    int temp = a;  
     a = b;    
     b = temp;    
     printf("swap a = %d,b = %d\n",a,b);
}int main(void)
{    int a = 10;    
     int b = 20;    
     printf("before swap:a = %d,b = %d\n",a,b);    
     swap(a,b);    
     printf("after  swap:a = %d,b = %d\n",a,b);    
     return 0;
}
           

运行结果如下:

before swap:a = 10,b = 20                                                        swap a = 20,b = 10                                                     
after  swap:a = 10,b = 20 
           

可以看到,a和b的值最终并没有被交换。开始时a,b的值为10,20,而最终还是同样的值。

因为函数参数在传递的时候,都是传原数据的副本,也就是说,swap内部使用的a和b只是最初始a和b的一个副本而已,所以无论在swap函数内部对a和b做任何改变,都不会影响初始的a和b的值。

正因如此,我们常常被告知,不要把直接把结构体直接作为参数,这样效率会很低。由于结构体本身占用字节数较大,如果直接作为参数,那么将会产生一个较大的”副本“,如此一来,效率也就很低了。

传指针调用

那么为解决上面的问题,我们知道,需要传指针。其代码如下:

#include<stdio.h>
void swap(int *a,int *b)
{    int temp = *a;    
     *a = *b;    
     *b = temp;    
     printf("swap a = %d,b = %d\n",*a,*b);
}
int main(void)
{    int a = 10;    
     int b = 20;    
     printf("before swap:a = %d,b = %d\n",a,b);    
     swap(&a,&b);    
     printf("after  swap:a = %d,b = %d\n",a,b);    
     return 0;
}
           

运行结果:

before swap:a = 10,b = 20                                                        swap a = 20,b = 10
after  swap:a = 20,b = 10 
           

可以看到在这种情况下,a,b的值才是真正交换了。

为什么又有传值,又有传指针

实际上,**C语言里,参数传递都是值传递!**也就是说,传指针也是传值,只不过它的值是指针类型罢了。

虽然传递给函数的是指向a和b的指针的副本,但是它的副本同样也是指向a和b,因此虽然不能改变指针的指向,但是能改变参数a和b指向的内容,即改变原始a和b的值。默认情况下,C语言使用传值调用来传递参数,这就意味着函数内的代码不能改变用于调用函数的实际参数。