软件

C语言实现函数重载

C++中存在函数重载的概念,函数重载可理解为:在局部可以允许多个函数用同一个函数名称,但要求函数所带的形参是不能相同的,可以是数量不同,也可以是类型不同。在C++中管这种函数名称相同,但是参数不同的函数叫做重载函数,也可以叫做函数的重载。


例如下面几个函数:

void func(int a) {

    cout << "func 1" << endl;
}

void func(double a) {

    cout << "func 2" << endl;
}

void func(int a, double b) {

    cout << "func 3" << endl;
}

而这种特性在C语言中是不存在的,然而我们可以使用一种特殊的方法来实现这种特性,这是因为在C语言中函数的参数长度是允许变长的。所以我们使用C语言中可变参数的特性来实现C++语言中重载这一功能:
代码如下:

/**
 * @file    overload.c
 * @author  
 * @version V1.0.0
 * @date    2020-07-15
 * @brief   module
 * @history
 *  1. 编写基于在C语言下实现C++的函数重载功能
 *  2.
 */

/* Includes ------------------------------------------------------------------*/
#include "overload.h"


/*
 * 函 数 名:int open(const char *__file, int __oflag, ...) __attribute__((nonnull(1)
 * 
 * 重载函数:int open(const char *__file, int flags);
 *          int open(const char *__file, int flags, int mode);
 * 
 * 
 */
int open(const char *__file, int __oflag, ...) {

    int         result = 2;
    int         list[1];                        // 用来接收可变参数部分的值
    va_list     vl;                             // va_list指针,用于va_start取可变参数

    va_start(vl, __oflag);                      // 取得可变参数中的第一个值

    for(int i = 0; i < 1; i ++) {               // 带有一个可变形参,那么就仅需要循环一次

        result ++;
        list[i] = va_arg(vl, int);              // 这里把vl往后跳过4个字节(sizeof(int)大小),指向下一个参数
    }
    va_end(vl);                                 // 与va_start成对出现,结束时调用

    return result;
}


/********* Copyright © goduino *********/

头文件如下:

/**
 * @file    overload.h
 * @author  
 * @version V1.0.0
 * @date    2020-07-15
 * @brief   module
 * @history
 *  1. 编写基于在C语言下实现C++的函数重载功能
 *  2.
 */

#ifndef OVERLOAD_H
#define OVERLOAD_H

/* Includes ------------------------------------------------------------------*/
#include <stdarg.h>


#ifdef __cplusplus
extern "C" {
#endif


/*
 * int open(const char *__file, int flags);
 * int open(const char *__file, int flags, int mode);
 */
extern int open(const char *__file, int __oflag, ...) __attribute__((nonnull(1)));


#ifdef __cplusplus
}
#endif

#endif


/********* Copyright © goduino.cc. *********/

调用方法:

void main(void) {

    // 通过可变形参的方式,我们就在C语言里实现了C++中的重载这一特性。
    // 两个函数名称相同,但是可以省略一个参数。
    open("/file.bin", 2);
    open("/file.bin", 2, 3);
}

通过使用va_list指针来从参数中获取到可变参数的值,不过这里有个问题,就是在c语言中使用这种方法无法获取到具体可变参数的个数。(除非将参数个数通过参数传入)

参考文献:

1.c语言实现类似重载的功能
2.用c语言实现函数重载
3.关于C中可变长参数

回复

This is just a placeholder img.