简单学C——第七天

函数编程

   函数是C语言重要的组成部分,你如今,或者之后(若是C没什么变化的话)所写的任何一个C语言程序都是由一个一个的函数组合在一块儿的,固然,如今或许你只会在主函数 main中写一个小程序,那么在看了本篇文章后,我以为本身编写多个函数在一个程序中运行确定不是问题啦,对于理解C语言的模块化编程也有很大的帮助。小程序

   前面已经学过不少数据类型,如指针,数组,结构体,等数据类型,想一想,在使用以前,咱们首先须要进行什么操做? 没错,首先是定义。固然,使用函数以前也要先定义一个函数。下面给出如何定义:数组

类型说明符 函数名 (传递的参数类型 行参名...)模块化

{函数

    //此处的内容与主函数 main()大括号的同样spa

}.net

想想,上面的定义方式是否感受很眼熟?指针

还记得你接触的第一个程序吧?它的核心部分就是code

int main()blog

{

//内容

return 0;  

}


其实这就是一个主函数,每个c语言程序的运行都须要它的存在。它的名称是被固定的,不可整改的,即 main,会发现,main后面的小括号里面什么也没有,这说明这个main函数是不带参数的,这也是咱们常用的。固然main函数也能够带参数,形如 int main(int argc,char *argv[]) ,具体可参见:http://blog.csdn.net/cnctloveyu/article/details/3905720   

上面的定义格式中的类型说明符指明了函数的返回值类型(通常所写的main函数最后都有 return 0;这表明运行正常, 也能够省略,若是省略编译时会自动加上,因此main函数的返回值为 int ),若是没有返回值 须要加上 void 表明返回值为空。形如 void print(){} 如今这就表示定义了一个返回值类型为空的名称为print且没有形式参数的函数。下面我将使用到本身定义的print函数。

#include<stdio.h>
void print() //print函数的定义
{
    printf("you are someone\n"); //语句
return ;
} int main() { print();//在主函数中调用print函数 }

运行结果:

假如没有在主函数中调用所写的print函数,程序也没错,可是print也就没用到了。了解一个程序的执行过程是很关键的一步,做为一个C语言程序的运行顺序,简单来讲就是以main函数为出发点,从上到下是根本,而后跟着所写的语句执行这个顺序。

下面再写一个稍微复杂的程序:比较两个数a,b的大小,若是a大,输出a,若是b大,输出b。

#include<stdio.h> //1
int Max(int c,int d) //Max函数的定义 //5
{
    //此时c的值等于a的值,d==b
   //若是c比d大,Max的返回值为c,不然,返回值为d
   if(c>d)   //6
   return c;  //7
   else      //6
   return d;  //7 
}
int main()
{
   int a,b,c;//2
   scanf("%d%d",&a,&b);//3
   //将a的值穿给形式参数 c,将b的参数穿给d
   //将Max的返回值,即a,b的最大值赋值给c
   c=Max(a,b);//4   //8
   printf("%d\n",c);//输出c   //9
   return 0;   //10
}

 

(附加:外部函数应该写在什么位置?

通常来讲,为了方便起见,把外部函数放在调用它的函数的上方,这样能够不用再在主函数中对其进行申明。若是要放在你想放的位置,则必需要在主函数中对这个函数申明,以上面的程序为例,申明Max函数,须要在主函数里面加上申明语句:int Max(int c,int d);c和d这两个标识符能够去掉

#include<stdio.h> //1

int main()
{
   int a,b,c;  
   int Max(int c,int d); //2
   //Max函数的申明,这样能够把Max函数放在main函数的后面
   //通常都把申明与数据的定义放在同一位置
   //或者 int Max(int,int);
   scanf("%d%d",&a,&b);//3
   //将a的值穿给形式参数 c,将b的参数穿给d
   //将Max的返回值,即a,b的最大值赋值给c
   c=Max(a,b);//4   //8
   printf("%d\n",c);//输出c   //9
   return 0;   //10
}
int Max(int c,int d) //Max函数的定义 //5
{
    //此时c的值等于a的值,d==b
   //若是c比d大,Max的返回值为c,不然,返回值为d
   if(c>d)   //6
   return c;  //7
   else      //6
   return d;  //7 
}

 比较一下上面两个程序的区别)

上面的程序就实现了求两个数当中的最大值。程序的运行顺序为 程序中所标注的 1~10  ,重复表明有多是重复当中的某一个。如今看看这两个程序,与最上面的程序相比是否是多了不少东西? 第二和第三个程序定义了一个Max函数,它有返回值,因此return后面接的是一个与这个返回值一致的某个数或者表达式,第一个程序,定义了返回值的类型为void类型,为空,因此没有返回值,没有返回值能够写做 return;或者空着不写这一语句. 另外能够看到我在main函数中定义了变量c,同时,在Max函数中我也定义了一个变量c,做为形参。不是说,程序中的变量名不能相同吗?其实,这和变量的做用域有关。变量分为 两种,全局变量和局部变量,全局变量即在函数外部定义的变量,局部变量是在函数内部定义的变量,前面可能没提到过,全局变量只须要在函数的外部定义一次,即能在其下方全部的函数中使用这个变量,而局部变量定义在函数的内部,只能在这一个函数中使用,若是其余的函数要用到它,须要进行参数的传递,1.经过值传递,2.经过地址传递 ,传递给须要用到的那个函数。

下面讲讲这两种传递吧

1.值传递

只能传递某些变量的数值到自定义的函数里面,而不能访问变量的地址,不能访问变量的地址就意味着不能在自定义的函数体里面对这个变量进行操做,前面所写的比较两个数的大小就用到了值传递,由于在这个地方咱们只须要了解到a,b两个的值,就能够判断究竟是a大仍是b大,并不须要对a与b的值进行更改等操做。

然而,不少时候,咱们并非只是想知道某个变量的值,例如:给你两个数,让你交换两个数的位置,而后输出。看到这,你确定会想这不是很简单的事吗!!因而你就写出了下面的这些程序:

way1

#include<stdio.h>
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%d %d\n",b,a);
}

way2

#include<stdio.h>
int main()
{
    int a,b,c;
    scanf("%d%d",&a,&b);
    c=a;
    a=b;
    b=c;
    printf("%d %d\n",a,b);
}

相信上面的两个程序你可以写出来。固然它们也都是十分正确的。但是我如今讲的是关于函数参数的地址传递啊,因此在实现这个程序的同时,我还要求你用到函数,而且其参数是地址,想一想吧,如今应该怎么作呢?

回想上一讲的内容,指针,指针不正能够存放地址吗,能够经过指针接收主函数中的变量的地址,而后传送到自定义的函数中去,以后,在自定义的函数中就能够访问到主函数中的地址了,能访问地址,就能对与地址对应的变量进行操做。

 

code:

#include<stdio.h>
void swap(int *p,int *q) //指针p,q做为swap函数的形参,分别接收来自主函数的a,b的地址
{
    //此时 *p和在主函数中的a同样,只是名字不同,*q同理
    int c;
    c=*p;
    *p=*q;
    *q=c;
    return; //由于是无返回void型的函数,也能够直接去掉这一行
}
int main()
{
    int a,b;
    scanf("%d%d",&a,&b); //输入两个数
    swap(&a,&b);//&为取地址符,这样就能够把a和b的地址做为函数的实参传递给swap函数
    printf("%d %d\n",a,b);//输出a和b
}

上面的代码与前面写的两个代码的功能是彻底同样的,只是上面的代码有助于理解内容,因此复杂化了。

若是你看懂了这个代码,你可能会想,用其余的方法能不能实现呢?难道必定要用到指针吗?

不少人容易犯的错误就是不经过地址传递,经过值传递就想实现这,那么,能够编写一下试试,

code:

#include<stdio.h>
void swap(int p,int q)
{
    //交换p与q的值
    int c;
    c=p;
    p=q;
    q=c;
   //此时p与q的值被交换了,可是a与b的值并无被交换
    return; //swap函数结束
}
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    swap(a,b);//把a与b的数值传递给swap函数,在swap函数中不能再次访问到a与b
    printf("%d %d\n",a,b);//输出a和b,结果与输入的同样,并无交换
    return 0;
}

固然把主函数中的printf("%d %d\n",a,b);删掉。而后再再swap函数中的return;上面加上一句printf("%d %d\n",p,q);。这样也能实现功能,可是这样和上面的第五个程序并无本质的区别。

还有一个方法,记得前面提到的全局变量不。它的做用域是它的定义下面的全部的函数。

code

#include<stdio.h>
int a,b;//定义a,b为全局变量,做用于下面的全部函数
void swap()
{
    //交换a和b
    int c;
    c=a;
    a=b;
    b=c;
    return; //swap函数结束
}
int main()
{
    scanf("%d%d",&a,&b);
    swap();//无需传递参数,由于a与b一直都存在于main主函数和swap函数
    printf("%d %d\n",a,b);
    return 0;
}

因为重复的代码比较多,因此就不放上运行结果了。能够本身粘贴运行一下。

这样也实现了相同的功能。由于a,b是全局变量,因此不用经过地址传递也能在swap中访问到a与b的地址

关于函数的就说这么多吧。虽然还有很多没提到,不过这也足够初学者去理解了。

相关文章
相关标签/搜索