C语言——函数

函数

 

 

  1. 什么是函数

在设计一个较大程序是,往往将他们分成若干个程序模块,每一个模块包括一个或多个函数,每一个函数实现一个特定的功能。此时函数分为:主函数和其他函数。

将每一个函数设计好之后,在主函数中运行,实现其功能。

举个例子

输出

***************************

How do you do!

***************************

实现这个程序,如果直接实现很容易,直接输出就行,我们今天用函数的方式输出!

源码:

#include<stdio.h>

int main(){

   void print_1();  //声明print_1函数

   void print_2();  //声明print_2函数

   print_1();       //调用print_1函数

   print_2();       //调用print_2函数

   print_1();       //调用print_1函数

   return 0;

}

void print_1(){

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

}

void print_2(){

printf("      How do you do!\n");

}

 

  1. 怎样定义函数

定义无参函数:

上面的例子属于无参函数。一般形式为:

函数类型  函数名(){

    函数体

}

函数名    函数名(void){

函数体

}

      注:void表示  函数没有参数

定义有参函数:

int max(int x,int y){

  int z;

  z=x>y?x:y;

  return(z);

}

“z=x>y?x:y”指的是求出z的值,z为x,y中最大的哪一个。

一般形式:

类型名  函数名(形式参数类别){

函数体

}

定义空函数:

类型名  函数名(){}

  1. 调用函数

函数调用的方式有3中:

函数调用语句   例:上面的pirnt_1()

函数表达式     例:c=2*max(a,b);

函数参数       例:m=max(a,max(b,c));

      形式参数和实际参数

          形式参数:在定义函数时函数名括号中的变量名称

          实际参数:在主函数中调用一个函数时,函数名后面括号中的参数,可以是常量、变量或表达式。

      例:输入二个整数,要求输出其中值较大者。要求永安还能输来找到大数。

          编写程序:

            先写MAX函数

            int max(int x,int y){

                 int z;

   z=x>y?x:y;

                return(z);

}

            再写主函数

            #include<stdio.h>

int main(){

              int max(int x,int y);

                int a,b,c;

                printf("输入二个数:\n");

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

   c=max(a,b);

   printf("最大的值为:%d\n",c);

   return 0;   

}

  1. 函数的嵌套使用

嵌套函数,就是指在某些情况下,您可能需要将某函数作为另一函数的参数使用,这一函数就是嵌套函数。一个为大家所熟知的例子就是qsort函数会将一个比较器cmp作为参数.又如图1中所示的公式使用了嵌套的 AVERAGE 函数,并将结果与 50 相比较。这个公式的含义是:如果单元格F2到F5的平均值大于50,则求F2到F5的和,否则显示数值0。又如,在一个程序中,主函数调用了sum函数,而在sum函数中又调用了mul函数。在一个函数被调用的过程中又调用另一个函数,这就是函数的嵌套调用。如果是函数本身嵌套调用函数本身,那就是函数递归调用了

  1. 函数的递归调用

   定义:递归调用就是在当前的函数中调用当前的函数并传给相应的参数,这是一个动作,这一动作是层层进行的,直到满足一般情况的的时候,才停止递归调用,开始从最后一个递归调用返回。

   调用前:

         而从被调用函数返回调用函数之前,系统也应完成3件工作:

(1)保存被调函数的计算结果;

(2)释放被调函数的数据区;

(3)依照被调函数保存的返回地址将控制转移到调用函数。当有多个函数构成嵌套调用时,按照后调用先返回的原则

调用后:

一个函数的运行期间调用另一个函数时,在运行被调用函数之前,系统需要完成3件事情:

(1)将所有的实参、返回地址等信息传递给被调用函数保存;

(2)为被调用函数的局部变量分配存储区;

(3)将控制转移到被调函数的入口。

举个例子:求n!

#include<stdio.h>

int main(){

int fact(int n);

int n;

int y;

printf("输入一个数:\n");

scanf("%d",&n);

y=fact(n);

printf("%d!=%d\n",n,y);

return 0;

}

int fact(int n){

int f;

if(n<0){

       printf("n<0,失败");

}

else if(n==0||n==1){

       f=1;

}

else f=fact(n-1)*n;

return(f);

}

  1. 数组作为函数参数

  一维数组作为函数的参数

声明数组参数可以采用2种方式:

int strfunc(char *str);    //推荐使用

int strfunc(char str[]);

由于数组名作为参数传递给函数时,函数实际接收到的是一个指针,因此第一种声明是更为准确的。在函数内部sizeof(str)的值将会是字符指针的长度,而不是数组的长度。

编译器同样接受第二种声明形式。数组形参无需写明它的元素数目,是因为函数并不为数组参数分配内存空间,形参只是一个指针。因此数组形参可以与任何长度的数组匹配。如果函数需要知道数组的长度,它必须作为一个显式的参数传递给函数。

多维数组作为函数的参数

一维数组作为函数形参,在声明时可以把它写成数组的形式,也可以把它写成指针形式。但对于多维数组,只有第一维可以进行如此选择,这里的关键在于编译器必须知道第2个及后面各维的长度才能对各下标进行求值,因此在原型中必须声明这些维的长度。你可以使用下面2种形式中的任意一种:

 

    void func(int (*mat)[10]);

    void func(int mat[][10]);

 

但写成下面的原型是不正确的:

 

void func(int **mat);

  1. 变量

变程序量中使用的范围不同:作用域(Scope),就是变量的有效范围。变量的作用域取决于变量的访问性。

局部变量:函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。

1.主函数中定义的变量也只能在主函数中使用,不能在其他函数中使用。

2.允许在不同的函数中使用相同的变量名,他们代表不同变量,分配不同的存放单元,互不相干,不会发生混淆。

3.复合语句中定义的变量,只限于使用当前函数中,也是复合语句的局部变量,复合语句:就是用{}包含起来的语句块。

4.形参变量、在函数体内定义的变量都是局部变量。实参给形参传值的过程也就是给局部变量赋值的过程。

全局变量:在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。它的作用域是从声明时刻开始,到程序结束。

1.全局变量定义必须在所有函数之外。

2.全局变量可加强函数模块之间的数据联系,但是函数又依赖这些变量,降低函数的独立性。

3.在同一源文件中,允许全局变量和局部变量同名,在局部变量作用域内,同名的全局变量不起作用。

  1. 内部函数和外部函数

内部函数:

static 类型名 函数名 (参数表)

例如:

static int fun(int a,int b)

表示fun是一个内部函数,不能憋其他文件调用

内部函数又称静态函数

外部函数:

如果在定义函数时,在函数首部的最左端加关键字extern
则此函数时外部函数,可供其他文件调用
extern int fun(int a,int b)
如果在定义函数时省略extern,则默认为外部函数。
#include<stdio.h>
int main()
{
    extern void enter_string(char str[]);
    extern void delete_string(char str[],char ch);
    extern void print_string(char str[]);
    char c,str[80];
    enter_string(str);
    scanf("%c",&c);
    delete_string(str,c);
    print_string(str);
    return 0;
}
void enter_string(char str[80])  //定义外部函数 enter_string
{
    gets(str);  // 向字符数组输入字符串
}
//file3.c 文件3
void delete_string(char str[],char ch)
{
    int i,j;
    for(i=j=0;str[i]!='\0';i++)
        if(str[i]!=ch)
        str[j++]=str[i];
    str[j]='\0';
}
void print_string(char str[])
{
    printf("%s\n",str);
}

希望有不同见解的,可以提出来呦~

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值