获取函数执行结果的n种方式

2024-07-18 13:27:37 浏览数 (2)

C 编程中,函数作为封装了一系列操作或计算过程的独立代码块,用于执行相应的功能。可能是操作文件IO、socket等资源,亦或者是修改某个成员变量,亦或者是单纯的执行计算并将结果返回给调用方。无论是哪种情况函数执行结果的获取都是至关重要的。

本文列举常见的获取执行结果六种方法,如下

返回值

返回值是最常用的获取函数执行结果的方式之一。通过在函数体中使用return语句返回结果,调用函数后可以直接获得函数执行的结果。这种方式直观,且符合编程习惯。

代码语言:javascript复制
int add(int a, int b)
{
    return a b;
}

引用形参

引用作为变量的别名,可以直接修改调用者传入的实参。从而可以直接获得函数的执行结果。其可以直接修改调用者传入的实参,同时支持同时返回多个结果。

代码语言:javascript复制
void swap(int& a, int& b)
{
    int tmp = a;
    a=b;
    b=tmp;
}

指针形参

指针形参也称之为输出参数。函数的执行结果赋值给指针,这种形式在windows平台微软的接口很常见。其也可以同时返回多个结果,并且不改变传入的参数,不会“污染”传入的参数。

代码语言:javascript复制
void divide(int x, int y, int* result) 
{
    if(!result)
    {
        return;
    }

    *result = x / y;
}

void using_pointer() 
{
    int x = 10, y = 2, result;
    divide(x, y, &result);
    std::cout << "The result is: " << result << std::endl;
    return;
}

修改作用域内的变量

修改变量分为两种情况,修改全局变量或修改类内成员变量,总之是修改后的变量可以在作用域内共享结果。修改变量值的场景要注意如果是多线程需要考虑线程间的同步问题。

代码语言:javascript复制
// 全局变量
int globalResult;

void subtract(int x, int y) {
    globalResult = x - y;
}

void  using_change_value() {
    int x = 10, y = 3;
    subtract(x, y);
    std::cout << "The result is: " << globalResult << std::endl;
    return ;
}

类/结构体

如果函数的结果包含多个值或者是复杂的数据结构,可以考虑使用结构体或类来封装这些值,然后将结构体或类对象作为返回值返回给调用者。

代码语言:javascript复制
// 结构体定义
struct Result {
    int sum;
    int difference;
};

// 函数定义
Result calculate(int x, int y) {
    Result result;
    result.sum = x   y;
    result.difference = x - y;
    return result;
}

void using_complex_obj() {
    int x = 8, y = 4;
    // 调用calculate函数并获取结果
    Result result = calculate(x, y);
    std::cout << "The sum is: " << result.sum << std::endl;
    std::cout << "The difference is: " << result.difference << std::endl;
    return ;
}

std::tuple

如果函数的结果含有多个值,除了使用类或结构体,还可以使用std::tuple

代码语言:javascript复制
//channel, bit_depth,codec_name
std::tuple<int, int, std::string> getCodecInfo(int id_flag)
{
  switch(id_flag)
  {
  case 1:
  {
    return { 2,4,"AAC" };
  }
  case 2:
  {
    return std::make_tuple(2, 2, "MP3");
  }
  case 3:
  default:
  {
    return std::tuple<int, int, std::string>(1, 4, "WAV");
  }
  }
}

void using_tuple()
{
  auto aac = getCodecInfo(1);
  std::cout<<"channels="<< std::get<0>(aac)<<" bit_depth="<<std::get<1>(aac)<<" codec name="<< std::get<2>(aac)<<std::endl;

  int mp3_channels;
  int mp3_bit_depth;
  std::string mp3_codec_name;
  std::tie(mp3_channels, mp3_bit_depth, mp3_codec_name)= getCodecInfo(2);
  std::cout << "channels=" << mp3_channels << " bit_depth=" << mp3_bit_depth << " codec name=" << mp3_codec_name << std::endl;

  auto [wav_channels, wav_bit_depth, wav_codec_name]= getCodecInfo(3);
  std::cout << "channels=" << wav_channels << " bit_depth=" << wav_bit_depth << " codec name=" << wav_codec_name << std::endl;
}

std::tuple作为C 的新特性,可以封装若干个返回值。同时,如上的代码示例中,展示了三种封装tuple和三种解析tuple的方法。其中结构化绑定需要C 17.

总结

本文列举了6种获得C 函数执行结果的方式,每种方式都有其适用的场景和优缺点。在选择方法时,需要考虑函数的返回值数量、调用者与被调用者之间的数据交互方式、程序的性能需求等因素。合理地选择获取函数执行结果的方式可以使程序更加灵活、可维护和高效。

0 人点赞