c语言之函数 -----学习笔记

Posted 旭日初扬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言之函数 -----学习笔记相关的知识,希望对你有一定的参考价值。

目录

 

一、函数概念

二、函数的分类

2.1、按函数的定义分类

2.1.1、标准函数

2.1.2、自定义函数

2.2、按有无返回值的分类

2.2.1、有返回值函数

2.2.2、无返回值的函数

2.3、按函数的形式分类

2.3.1、无参函数

2.3.2、有参函数

三、函数返回值及类型

3.1、函数的返回值

3.2、函数的类型

3.2.1、常见函数类型

3.2.2、编写一个函数,输出一个图形

3.2.3、一个函数中无论有几个return都只返回一个

四、函数的参数及传递方式

4.1、函数的参数

4.2、函数参数的传递方式

五、函数调用

5.1、函数的调用方式

5.1.1、(函数语句)第一种调用方式

5.1.2、(函数表达式)第二种调用方式

5.2、函数的声明

5.3、函数的嵌套调用

5.4、函数的递归

5.5、用递归求Fibonacci数列

六、内部函数和外部函数

6.1、内部函数

6.2、外部函数


一、函数概念

结构化程序设计的思想:把大问题分解成若干个小问题,每个小问题就是一个独立的子模块,以实现特定的功能、在C程序中,子模块的作用是由函数完成的.

 

  • 一个c源程序可以由多个文件构成(c文件的后缀名.c)
  • 一个源文件是一个编译单位
  • 一个源文件可以由若干个函数组成(函数是c程序的基本组成单位)
  • 每个c程序只能有一个main函数,其他都是子函数。
  • 主函数可以调用子函数,子函数可以相互多次调用。

实例

#include <stdio.h>
void printstar()        //   自定义函数 printstar()   输出*

printf("************");


int sum(int a,int b)     // 自定义函数sum   计算a+b的值

return a+b;              // 通过return返回函数


void main()              // 主函数  唯一    程序入口

int x=2,y=3,z;
printstar();            //  调用函数
z=sum(x,y);
printf("\\n%d+%d=%d\\n",x,y,z);
printstar();    


二、函数的分类

2.1、按函数的定义分类

2.1.1、标准函数

标准函数又称为库函数,由c系统提供,无需程序员定义,可直接使用,但需要在程序开头包含原型声明的头文件。如scanf()

2.1.2、自定义函数

由程序员根据自己的需求编写,自定义函数不仅要在程序中定义函数本身,必须还要在主函数中调用该函数

2.2、按有无返回值的分类

2.2.1、有返回值函数

该类函数被调用执行完毕,将向调用者返回一个执行结果,称为函数的返回值


int send( int a,int b)

return a+b;


void main()

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

2.2.2、无返回值的函数

无返回值函数不需要向主调函数提供返回值

void printstar()        

printf("************");

void main()


printsar();

2.3、按函数的形式分类

2.3.1、无参函数

在函数的声明、定义和调用中均不带参数,特点:在调用无参函数主调函数并不将数据传输给被调用函数,此类函数通常被用来完成指定的功能,可以返回或不返回函数值。

/*
格式:
     类型说明  函数名()                                        
                                                             
// 函数体                                                   
                                                              

*/
int max()

// 函数体



空函数   无函数体
类型说明   函数名()
 
//无函数体   因程序设计需要,确定模块需求   先占位置  后在补上
   

int max()


2.3.2、有参函数

在函数定义、声明都都有参数。特点:主调函数调用被调函数时,主调函数必须把值传输给形参,以供被调函数使用


int max(int a,int b)  // 有参函数

函数体




三、函数返回值及类型

3.1、函数的返回值

/*
函数的定义

  函数类型  函数名([类型说明 变量名[,类型说明 变量名]])
  
           函数体
	

注意:函数与函数的关系是同等级别,不能嵌套

*/

#include "stdio.h"
int max(int a, int b)  // 有返回值  用参数的函数   a,b为形参

int c;
c=a>b?a:b;
return c;


void main()   // 无返回值必须加void声明,否则默认为int


int x,y;
printf("请输入两个整数:");
scanf("%d%d",&x,&y);
printf("%d和%d的最大值为:%d\\n",x,y,max(x,y));


/*

return expression;    return a;

return(expression);   return (a);
*/

/*

函数的返回值是通过函数中的return语句实现
return语句将被调函数中的一个确定值带回主调函数中

编写cobe()函数用于计算x立方
*/

#include "stdio.h"
long cube(long x)        // 定义函数cube(),返回类型为long

long z;
z=x*x*x;
return z;                // 通过return返回所求结果,结果也应该为long
// x*x*x


void main()

long a,b;
printf("请输入一个整数:\\n");
scanf("%ld",&a);
b=cube(a);
printf("%ld的立方为:%ld",a,b);

3.2、函数的类型

3.2.1、常见函数类型

int max()
double max()
void max()
float max()
/*
定义函数时,必须指明函数的返回值类型,而且
return语句表达式中的类型应该与函数定义时首部的函数类型时一致的,如果二者不一致,则以函数定义时首部的函数类型为准
*/

#include "stdio.h"
int cube(float x)  /*定义函数cube(),返回值类型为int*/

float z;
z=x*x*x;           // 定义返回值为z,类型为float
return z;          // 通过return返回所求结果


void main()

float a;
int b;
printf("请输入一个数:");
scanf("%f",&a);
b=cube(a);
printf("%f的立方为:%d\\n",a,b);

报错

E:\\vc\\hanshu\\hanshu.c(11) : warning C4244: 'return' : conversion from 'float ' to 'int ', possible loss of data

但能通过编译

3.2.2、编写一个函数,输出一个图形

/*
编写一个函数,输出下列图型
      ***********
	   ***********
	    ***********
*/

#include "stdio.h"
void printdod()   // 省略void 编译会认为printdod的类型是int

printf("**********\\n");
printf(" **********\\n");
printf("   **********\\n");

void main()

printdod();          // 调用函数

3.2.3、一个函数中无论有几个return都只返回一个

一个函数中可以有一个以上的return语句,但不论执行那个return,都将结束函数的调用返回主调函数,即带返回值的函数只能有一个。

/*
一个函数中可以有一个以上的return语句,但不论执行那个return,都将结束函数的调用返回主调函数,即带返回值的函数只能有一个
*/

#include "stdio.h"
int max(int a,int b)    // 定义函数max()   a,b实参传递给形参x,y

  if(a>b)              // 如果a>b,返回a
	  return a; 
  return b;            //否则返回b


void main()

int x,y;
printf("请输入两个整数:");
scanf("%d%d",&x,&y);
printf("%d和%d的最大值为:%d\\n",x,y,max(x,y));

四、函数的参数及传递方式

4.1、函数的参数

函数的参数有两类:形参和实参
函数定义时的参数称为形参,参数在函数未被调用时是没有确定值的,只是形式上的参数
函数调用时使用的参数称为实参

/*
函数的参数有两类:形参和实参
函数定义时的参数称为形参,参数在函数未被调用时是没有确定值的,只是形式上的参数
函数调用时使用的参数称为实参
*/

#include "stdio.h"
void order(int a,int b) // a,b为形式参数(形参)

int t;
if(a>b)                 // 如果a>b,就执行一下3条语句

t=a;
a=b;
b=t;

printf("从小到大的顺序:%d %d\\n",a,b);   // 输出交换后的a,b的值



void main()

int x,y;
printf("请输入两个整数");   // 键入两个整数
scanf("%d%d",&x,&y);
order(x,y);                 // x,y为实际参数(实参)

/*
1、参数可以是常量,变量,其他构造数据类型或表达式,调用时可写成
order(2,3);      // 实参时常量
order(x+y,x-Y);  // 实参时表达式
实参是表达式时,先计算表达式的值,再将实参的值传递个形参,但要求它有确切的值,因为调用是要将值传递给形参的。

2、定义函数时必须说明形参的类型,形参只能是简单的变量或数组,不能是常量或表达式

3、函数被调用前,形参不占内存的存储单元;调用以后,形参才被分配内存单元;函数调用结束后,形参所占用的内存也被收回或者释放。

4、实参的个数、出现的顺序和实参的类型,应该与函数定义中形参的设计一一对应。


*/

4.2、函数参数的传递方式

c语言规定,实参对形参的数据传递是“值传递”,即单向传递,只是把实参的值传递给形参,而不能把实参的值再传递给实参。再内存当中,实参与形参是不同的单元,不管名字是否相同,因此函数中对形参值的任何改变都不会影响到实参的值。



#include "stdio.h"
void swap(int a,int b)   // 自定义函数 无返回值类型的有参函数


int temp;
temp=a;a=b;b=temp;                   /*交换a,b的值*/
printf("a=%d,b=%d\\n",a,b);


void main()

int x,y;
printf("请输入两个整数:\\n");
scanf("%d%d",&x,&y);                 // 输入两个整数
printf("调用函数之前\\n");
printf("x=%d,y=%d\\n",x,y);  
        //  输出调用swap函数之前x,y的值
printf("调用函数中:\\n");
swap(x,y);                         //  x,y 实参
printf("调用函数之后:\\n");
printf("x=%d,y=%d\\n",x,y);         // 输出调用swap函数之后x,y的值

五、函数调用

  • C程序是从主函数main()开始执行的,以main()函数体结束为止在函数体的执行过程中,通过不断地对函数的调用来执行的。
  • 调用者  被称为主调函数一般为main()函数
  • 被调用者   称为被调函数一般为自定义函数或者库函数
  • 被调函数执行结束,从被调函数结束的位置再返回主调函数当中,继续执行主调函数后面的语句。

5.1、函数的调用方式

5.1.1、(函数语句)第一种调用方式

函数名(实参列表);

函数名();

5.1.2、(函数表达式)第二种调用方式

m=max(x,y);                      // 将max()函数的返回值赋值给变量m
m=3*max(x,y);                    // 将max()函数的返回值乘3赋值给变量m
printf("Max is %d,max(x,y)");    // 输出max()函数的返回值
/*求两个数的最小公倍数*/

#include "stdio.h"

int sec(int m,int n)            // 自定义函数  int返回值类型  无参数

int temp,a,b;        // 定义变量temp,a,b
   if(m<n)
   

     temp =m;
	 m=n;
	 n=temp;
   
   a=m;b=n;
   while(b!=0)
   
   temp=a%b;
   a=b;
   b=temp;
   
   return(m*n/a);


void main()  // 主函数c程序的入口

int x,y,g;
printf("请输入两个整数:");
scanf("%d%d",&x,&y);
g=sec(x,y);
printf("最小公倍数为:%d\\n",g);

5.2、函数的声明

使用原则:先定义后使用

有参函数的声明形式
函数类型   函数名(形参列表);
int    tian(int a,int b);

无参函数的声明形式:
函数类型   函数名();
int tain();

5.3、函数的嵌套调用

在c语言中,函数的关系是平行的,是独立的即函数的不能嵌套定义。

c语言中函数的嵌套调用即在调用一个函数的过程中可以调用另外一个函数。



#include "stdio.h"
fun2(int x,int y)

int z;
z=2*x-y;
return z;


fun1(int x,int y)

int z;
z=fun2(x,x+y);
return z;


void main()

int a,b,c;
printf("请输入两个整数: \\n");
scanf("%d%d",&a,&b);
c=fun1(a,b);                // 调用fun1()函数
printf("%d\\n",c);

5.4、函数的递归

如果在调用一个函数的过程中,有直接或间接的调用了该函数本身,这种形式称为函数的递归调用,这个函数就称递归调用。

int func(int a)

int b,c;
c=func(b);

 

 

/*用递归方法求n!*/
long fac(int n)

long m;
if(n==1)
    m=1;
	else
	m=fac(n-1)*n;
return m;

main()

int n;
float y;
printf("input the value of n.\\n");
scanf("%d",&n);
printf("%d!=%d\\n",n,fac(n));
/*用递归方法求n!*/
#include "stdio.h"
long fac(int n)

  int i; long m=1;
  for(i=1;i<=n;i++)
  
       m=m*i;
  
       return m;

   main()
   
   int n;
   float y;
   printf("input the value of n.\\n");
   scanf("%d",&n);
printf("%d!=%ld",n,fac(n));

   
   

5.5、用递归求Fibonacci数列

#include "stdio.h"
long fibonacci(int n)

if(n==1||n==2)
return 1;
  else
	  return(fibonacci(n-1)+fibonacci(n-2));

  main()
  
  int n,i;
  long y;
  printf("input n:");
  scanf("%d",&n);
  for(i=1;i<=n;i++)
  
  y=fibonacci(i);
printf("%d",y);
  
  printf("\\n");
  

六、内部函数和外部函数

6.1、内部函数

如果在一个源文件中定义的函数只能被文件中的函数调用,而不能被同一源程序其他文件中的函数调用。

内部函数的一般形式

static 类型说明符  函数名([形参表])    

[ ]中的部分为可选项

内部函数关键字:static

static int f(int a,int b)  // 内部函数




f()函数只能被本文件中的函数调用,其他文件中不能使用该函数。

6.2、外部函数

外部函数在整个源程序中都有效,只要定义函数时,在前面加上extern关键字

定义形式

extern 类型说明符 函数名 (<形参表>)

extern int f(int a,int b)




不带extern与static关键字的函数都是外部函数如:

int voo()     // 外部函数
int vi()     // 外部函数

以上是关于c语言之函数 -----学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

C语言试题188之实现strcspn函数功能

C语言试题187之实现strspn函数功能

C语言奇淫技巧之函数的可变参数

C语言之字符串处理函数

C语言之函数指针用法总结

C语言试题180之实现实现字符串strcpy函数