C语言函数语法详解_C 语言

1、概述

        在C语言中,函数是来完成子程序或者某个模块的功能。有主程序或者其他函数调用,其他函数之间可以相互调用。同一函数可以被一个或多个函数任意次调用。
注意:
    a、一个C程序有一个或多个程序模块组成,每一个程序模块作为一个源程序文件。一个源文件可以为多个C程序共用。
    b、程序在编译时是以源文件为单位进行编译,而不是以函数为单位进行编译。一个源文件就是一个编译单元
    c、C程序的执行是从main函数开始,也是在main函数中结束整个程序
    d、所有函数是平行的,即在定义函数时是分别进行的,是互相独立的。一个函数并不从属于另一个函数,即函数不能嵌套定义。函数之间可以相互调用,但不能调用main函数。main函数是系统调用的。
    e、从用户使用角度看,函数分为两种:
        (1)标准函数。标准函数即函数库,它由系统提供。不同的C语言编译系统提供的标准函数的数量和功能或有不同,但是基本函数是一样的。
        (2)用户自定义函数。
    f、从函数形式看,函数分为两种:
        (1)有参函数。
        (2)无参函数。在调用函数时,主调函数通过参数向被调函数传递数据

2、函数的定义

定义无参函数的一般形式:
类型表示符 函数名()
{
    声明部分
    语句部分
}
【实】定义无参函数,输出“Hello World”字符串

复制代码 代码如下:

void show()
{
    printf("Hello World");
}

定义有参函数的一般形式:
类型标识符 函数名(形式参数列表)
{
    声明部分
    语句部分
}
【例】传递两个int的参数a和b,然后计算a加b的和,然后返回a加b的和。

复制代码 代码如下:

int add(int a, int b)
{
    int t = 0; // 声明部分
    t = a + b;
    return t;
}

空函数就是没有函数体的函数,如:

void test(){ ... }

调用空函数时,什么工作也不做,没有任何实际作用。在程序设计中往往程序初期只实现基本功能,对于高级功能我们可以提供一空函数,以后实现该空函数。

定义函数时指定的参数称为“形参”,调用函数时传递的参数称为“实参”。
    a、在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。只有在发生函数调用时,函数中的形参才被分配内存单元。在调用结束后,形参所占用的内存单元也被释放。
    b、实参可以是常量、变量或表达式,如:max(3, a+b);
    c、在被定义的函数中,必须指定形参的类型
    d、实参和形参的类型应相同或赋值兼容。
    e、在C语言中,实参向形参数据传递是“值传递”,单向传递,只由实参传递给形参,而形参不能传递给实参。在内存中形参和实参是不同的内存单元。因此,改变形参的值不会影响实参的值。

3、函数的返回值

    通常,希望通过函数调用是主调函数能得到一个确定的值,这就是函数的返回值。
    a、函数的返回值是通过函数中的return语句获得的。return语句将被调用函数中的一个确定值带回主调函数中去。如果需要从被调用函数带回一个函数值,被调函数中必须包含return语句。如果不需要从被调函数带回函数值可以不需要return语句。一个函数可以有多个return语句,执行到哪个return语句,哪个语句就起作用。
    b、函数值的类型。既然函数有返回值,这个值当然应属于某一个确定的类型,应当在定义函数时指定函数值的类型。C语言中,凡是不加类型说明的函数,自动按整型处理。在Turbo C 2.0中不写返回类型可以通过,Turbo C++ 3.0编译时不能通过。所以建议读者在定义时对所有函数都指定函数类型。
    c、在定义函数是指定的类型应该与return返回类型一致。如果函数值的类型和return语句中表达式值类型不一致,则按照函数类型为准。
    d、对于不带回值的函数,应当用“void”定义函数为“无类型”或称“空类型”。此时函数体中不得出现return语句。

4、函数调用
    函数调用的一般形式为:函数名(实参列表);如:

复制代码 代码如下:

int a = max(2, 4);

按函数在程序中出现的位置来分,可以有以下3种函数调用方式:
    a、函数语句。把函数调用作为一个语句。此时不许要函数返回值。如: show();
    b、函数表达式。函数出现在一个表达式中,这种表达式称为函数表达式,需要函数返回一个确定的值。如:a = 2*max(a, b);
    c、函数参数。函数调用作为一个函数的参数。如:m = max(a, max(b, c));

5、对被调函数的声明和函数原型

    在一个函数中调用另一个函数需要具备以下条件:
    a、被调函数必须是已经存在的函数
    b、如果使用函数库,还应该在文本文件开头用#include命令将调用有关库函数时所需用到的信息“包含”到本文件中来。如:#include <stdio.h>
        其中“stdio.h”是一个“头文件”。在stdio.h文件中包含了输入输出库函数所用到的一些宏定义信息。如果不包含stdio.h文件的信息,就无法使用输入输出库中的函数。
    c、如果使用用户自己定义的函数,而该函数的位置在调用它的函数的后面(在同一个文件中),应该在主调函数中对被调用的函数进行声明。如:

复制代码 代码如下:

#include <stdio.h>
void main()
{
    float add(float x, float y); // 或者: float add(float, float);
    float a, b, c;
    scanf("%f%f", &a, &b);
    c = add(a, b);
    printf("sum is %f\n", c);
}
float add(float x, float y)
{
    return x + y;
}

6、局部变量和全局变量

a、局部变量
        在一个函数内部定义的变量是内部变量,它只能在函数范围内才有效,也就是说只在本函数内才能使用它们,在此函数外部不能使用这些变量。如:

复制代码 代码如下:

float f1(int a)
{
    int b, c;     // b、c变量只在f1函数内部有效
}
char f2(int x, int y)
{
    int i, j;     // i、j变量在f2函数内部有效
}
void main()
{
    int m, n;  // m、n变量在main函数中有效
}

注意:
    1)主函数中定义的变量(m、n)也只在主函数中有效,而不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。
    2)不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。
    3)形式参数也是局部变量。
    4)在一个函数内部可以在符合语句中定义变量,这些变量值在本符合语句中有效,这种符合语句称为“分程序”或“程序块”。如:

复制代码 代码如下:

void main()
{
    int a, b; // a和b在main函数内部有效
    ……
    {
        int c;
        c = a + b; // c在该符合语句中有效
    }
}

b、全局变量
        在函数外部定义的变量就是全局变量。全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。如:

复制代码 代码如下:

int a, b;        // a、b的范围从此处到源文件结尾
float f1()
{
    int b, c;
}
char c1, c2;    //  c1、c2的范围是从此处到原文结尾
char f2()
{
    int i, j;
}
void main()
{
    int m, n;
}

注意:
    (1)全局变量是函数之间交换数据的一个渠道。一般第一个字母大写
    (2)建议不再必要时不要使用全局变量。原因如下:全局变量在程序的全部过程中都占用存储单元、使函数的通用性降低,因为依赖外部变量、使用过多全局变量会降低程序的清晰性
    (3)如果全局变量和局部变量同名,则局部变量优先

7、变量的存储类别

        从变量存在的生命周期来看,变量可以分为:静态存储方式和动态存储方式。所谓静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式。而动态存储方式是在程序运行期间根据需要进行动态的分配存储空间的方式。

内存中的供用户使用的存储空间的情况。存储空间分为三部分:
(1)程序区
(2)静态存储区。(存放:全局变量)内存空间在程序开始时给全局变量赋值、分配空间,一直保存到程序运行结束才释放,
(3)动态存储区。(存放:函数形参、自动变量、函数调用时的现场保护和返回地址等)调用时才分配空间,调用结束就释放空间。
    在C语言中,每个变量和函数有两个属性:数据类型和数据的存储类别。

存储类别分为量大方式:
    1)、静态存储类别
    2)、动态存储类别

具体包含4种:自动的(auto)、静态的(static)、寄存器(register)、外部的(extern)
a、auto
b、static
c、register
d、extern

8、内部函数和外部函数
a、内部函数
        如果一个函数只能被本文件中其他函数调用,则称为“内部函数”。在定义内部函数时,在函数名和函数类型前面加上static。语法如下:

static 类型标识符 函数名(形参列表);

例如:

复制代码 代码如下:

static int add(int a, int b);

        内部函数又称静态函数,因为它是用static声明的。使用内部函数,可以使函数的作用域只局限于所在文件,在不同的文件中有同名的内部函数,互不干扰。

如:Test.c文件调用Test2.c文件中的void show()方法,输出“Hello World”。
源文件:Test.c

复制代码 代码如下:

#include <stdio.h>
void main()
{
    extern void show();
    show();
}

源文件:Test2.c

复制代码 代码如下:

#include <stdio.h>
void show ()
{
    printf("Hello World\n");
}

b、外部函数。
        在定义函数时,如果在函数首部的最左端加关键字extern,则表示此函数是外部函数,可以供其他文件调用。如:

复制代码 代码如下:

extern int max(int a, int b);  // 可以为其他文件调用

C语言规定,如果在定义函数时省略extern,则隐含为外部函数。
   
        在需要调用此函数的文件中,用extern对函数作声明,表示该函数是在其他文件中定义的外部函数。

如:Test.c文件调用Test3.c文件中int add(int a, int b)方法,然后返回值,再将返回值传递给Test2.c文件中的show(int result)方法显示出来。
源文件:Test.c

复制代码 代码如下:

#include <stdio.h>
void main()
{
    extern void show(int result);
    extern int add(int a, int b);
    int result = 0;
    result = add(2, 3);
    show(result);
}

源文件:Test2.c

复制代码 代码如下:

#include <stdio.h>
void show (result)
{
    printf("result=%d\n", result);
}

源文件:Test3.c

复制代码 代码如下:

#include <stdio.h>
int add(int a, int b)
{
    return a + b;
}

小伙伴们是否对C语言的函数语法理解的更深刻了呢,希望大家能够喜欢本文。

时间: 2024-11-08 18:15:39

C语言函数语法详解_C 语言的相关文章

C++的get()函数与getline()函数使用详解_C 语言

C++ get()函数读入一个字符 get()函数是cin输入流对象的成员函数,它有3种形式:无参数的,有一个参数的,有3个参数的. 1) 不带参数的get函数 其调用形式为 cin.get() 用来从指定的输入流中提取一个字符(包括空白字符),函数的返回值就是读入的字符. 若遇到输入流中的文件结束符,则函数值返回文件结束标志EOF(End Of File),一般以-1代表EOF,用-1而不用0或正值,是考虑到不与字符的ASCII代码混淆,但不同的C ++系统所用的EOF值有可能不同. [例]

C语言中的sscanf()函数使用详解_C 语言

sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: Int sscanf( string str, string fmt, mixed var1, mixed var2 ... ); int scanf( const char *format [,argument]... ); 说明: sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源. 其中的format可以是一个或多个 {%[*] [width] [{h |

C++中memset函数用法详解_C 语言

本文实例讲述了C++中memset函数用法.分享给大家供大家参考,具体如下: 功 能: 将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作 用 法: void memset(void *s, char ch, unsigned n); 程序示例: #include <string.h> #include <stdio.h> #include <memory.h> int main(v

C语言转义字符实例详解_C 语言

在字符集中,有一类字符具有这样的特性:当从键盘上输入这个字符时,显示器上就可以显示这个字符,即输入什么就显示什么.这类字符称为可显示字符,如a.b.c.$.+和空格符等都是可显示字符. 另一类字符却没有这种特性.它们或者在键盘上找不到对应的一个键(当然可以用特殊方式输入),或者当按键以后不能显示键面上的字符.其实,这类字符是为控制作用而设计的,故称为控制字符. 在C语言中,构成字符常量的控制字符必须用转义字符表示.转义字符是一种以"\"开头的字符.例如退格符用'\b'表示,换行符用'\

基于linux下获取时间函数的详解_C 语言

//-------------------------------------------------------------//asctime(将时间和日期以字符串格式表示)#include<time.h>定义函数char * asctime(const struct tm * timeptr);函数说明asctime()将参数timeptr所指的tm结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回.此函数已经由时区转换成当地时间,字符串格式为:"We

基于C语言string函数的详解_C 语言

PS:本文包含了大部分strings函数的说明,并附带举例说明.本来想自己整理一下的,发现已经有前辈整理过了,就转了过来.修改了原文一些源码的问题,主要是用char *字义字符串的问题,导致程序运行时崩溃.另外自己重写了部分测试程序,使其更能满足自己测试的需要.不当之处,还请海涵.@函数原型:  char *strdup(const char *s) 函数功能:  字符串拷贝,目的空间由该函数分配  函数返回:  指向拷贝后的字符串指针 参数说明:  src-待拷贝的源字符串 所属文件:  <s

基于一致性hash算法 C++语言的实现详解_C 语言

    一致性hash算法实现有两个关键问题需要解决,一个是用于结点存储和查找的数据结构的选择,另一个是结点hash算法的选择.     首先来谈一下一致性hash算法中用于存储结点的数据结构.通过了解一致性hash的原理,我们知道结点可以想象为是存储在一个环形的数据结构上(如下图),结点A.B.C.D按hash值在环形分布上是有序的,也就是说结点可以按hash值存储在一个有序的队列里.如下图所示,当一个hash值为-2^20的请求点P查找路由结点时,一致性hash算法会按hash值的顺时针方向

C语言 基本语法示例讲解_C 语言

C 基本语法 我们已经看过 C 程序的基本结构,这将有助于我们理解 C 语言的其他基本的构建块. C 的令牌(Tokens) C 程序由各种令牌组成,令牌可以是关键字.标识符.常量.字符串值,或者是一个符号.例如,下面的 C 语句包括五个令牌: printf("Hello, World! \n");  这五个令牌分别是: printf ( "Hello, World! \n" ) ;  分号 ; 在 C 程序中,分号是语句结束符.也就是说,每个语句必须以分号结束.它

C语言中改变目录的相关操作函数详解_C 语言

C语言fchdir()函数:改变当前工作目录头文件: #include <unistd.h> 定义函数: int fchdir(int fd); 函数说明:fchdir()用来将当前的工作目录改变成以参数fd 所指的文件描述词. 返回值:执行成功则返回 0, 失败返回-1, errno 为错误代码. 范例 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <