【C/C++ 基础 函数】精通C/C++函数参数:全面指南

简介: 【C/C++ 基础 函数】精通C/C++函数参数:全面指南

I. 介绍

形参是编程语言中函数或方法的重要组成部分。在 C 和 C++ 语言中,形参是函数声明中定义的一个或多个变量,用于接收调用函数时传递的实际参数。形参的作用是让函数在执行过程中可以访问并使用调用者传递的数据。

形参是一种抽象的概念,在函数声明时定义,在函数调用时被赋值。因此,形参是一种在函数执行前预定义的占位符,它允许函数在不同的调用中处理不同的数据。

II. C语言中的形参

在 C 语言中,形参可以通过三种不同的方式传递:值传递、指针传递和引用传递。

A. 值传递

值传递是 C 语言中最常见的形参传递方式。在值传递中,函数接收的是实际参数的副本,因此对形参的任何操作都不会影响实际参数。

B. 指针传递

指针传递是 C 语言中另一种常见的形参传递方式。在指针传递中,函数接收的是实际参数的内存地址,因此对形参的任何操作都会影响实际参数。

    void add2(int *p)    
 
  {   *p+=1; p+=1;     }        
 

 

使用指针做为函数的形参,同样指针的值(指针的地址)不会因为p+=1而受到影响,但是指针指向的地址的值(*p)将会改变。

所以要想修改实参的值,可以使用这种方法。但是还有一种更安全更自然的方法-引用形参。

C. 引用传递

引用传递是 C++ 语言中引入的一种形参传递方式,它在 C 语言中不可用。在引用传递中,函数接收的是实际参数的别名,因此对形参的任何操作都会影响实际参数。

D. 传递数组

在 C 语言中,数组作为实际参数传递给函数时,实际上是传递了数组的首地址,因此在函数中对数组的操作会影响实际参数。

III. C++语言中的形参

在 C++ 语言中,形参有多种不同的传递方式,包括值传递、引用传递、默认形参和可变参数模板。

A. 值传递

值传递在 C++ 中与 C 语言中的值传递相同,函数接收的是实际参数的副本,因此对形参的任何操作都不会影响实际参数。

void change(int a) {
    a = 100;
}
 
int main() {
    int x = 5;
    change(x);
    cout << x << endl; // 输出5,x的值并未改变
    return 0;
}

B. 引用传递

引用传递在 C++ 中与 C 语言中的引用传递相同,函数接收的是实际参数的别名,因此对形参的任何操作都会影响实际参数。

引用形参直接关联到其所绑定的对象,而非这些对象的副本。 所以这种方法可以修改实参的值,而且更加直观

引用参数  在形参表中以符号“&”开始的参数即为引用参数。

如果一个形参是引用参数,调用部位将把实参的地址传递给子程序。 于是子程序操作的就是实参真正的变量,而不是它的副本。

void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}
 
int main() {
    int x = 5;
    int y = 10;
    swap(x, y);
    cout << "x: " << x << ", y: " << y << endl; // 输出 "x: 10, y: 5"
    return 0;
}

例如如果程序员想修改指针本身,而不是指针引用的对象

那么他可以声明一个参数,该参数是一个指针的引用,

例如:下面是交 换两个指针的函数

C. 默认形参

默认形参是 C++ 中的一个特殊功能,允许为形参设置默认值,在调用函数时如果C++ 中的默认形参功能允许为形参设置默认值,在调用函数时如果不传递该形参,则使用默认值。这种功能可以大大简化代码,并且提高代码的可读性。

void greet(string name = "World") {
    cout << "Hello, " << name << "!" << endl;
}
 
int main() {
    greet();       // 输出 "Hello, World!"
    greet("Jane"); // 输出 "Hello, Jane!"
    return 0;
}

D. 可变参数模板

可变参数模板是 C++ 中的另一个特殊功能,允许函数接收任意数量的参数。这种功能可以大大简化代码,并且使代码更加灵活。

template<typename... Args>
void print(Args... args) {
    (cout << ... << args) << '\n';
}
 
int main() {
    print(1, 2, 3, "Hello", "World"); // 输出 "123HelloWorld"
    return 0;
}

IV. 形参的选择

当我们在编写函数时,形参是非常重要的,因为它们决定了函数能够接收哪些参数,并且影响函数在执行时的行为。因此,我们需要根据实际需求选择合适的形参传递方式。

A. 可读性

选择清晰明了的形参传递方式可以提高代码的可读性。例如,使用引用传递可以使函数调用更简单明了,因为它更接近于直接操作实际参数。

B. 效率

使用更快的形参传递方式可以提高代码的效率。例如,如果需要传递大量数据,使用指针传递可以避免复制大量数据,提高代码执行速度。

C. 代码可维护性

使用更简单易维护的形参传递方式可以提高代码的可维护性。例如,使用默认形参可以避免因为函数接口的改变而导致调用方代码需要大量修改。

D.安全性:

需要考虑参数传递时的安全性问题,例如指针传递可能会导致空指针异常,需要在函数内部做好参数检查。

在选择形参传递方式时,需要综合考虑上述因素,并根据实际需求做出选择。同时需要注意,不同的形参传递方式对内存的使用有不同的影响,需要避免出现内存泄漏和内存溢出等问题。

总之,选择正确的形参传递方式可以提高代码的质量和效率,需要认真对待。

VI.形参传递方式的优缺点

除了上述提到的选择因素外,我们还需要了解一些形参传递方式的优缺点。

  1. 值传递

优点:实现简单,避免出现指针错误,安全性高。

缺点:可能会浪费大量的内存,因为需要复制整个参数的值,不适合传递大量的数据。

  1. 指针传递

优点:可以直接访问实际参数的内存地址,节省内存,适合传递大量的数据。

缺点:需要在函数内部进行参数检查,避免出现空指针等异常。

  1. 引用传递

优点:直接访问实际参数的别名,避免了复制大量数据,执行速度快,不容易出现指针错误。

缺点:需要注意避免修改实际参数的值,可能会对调用方造成意外的影响。

  1. 默认形参

优点:可以避免函数接口改变对调用方代码的影响,提高代码的可维护性。

缺点:需要在定义函数时指定默认值,可能会增加代码的复杂度。

  1. 可变参数模板

优点:可以接收任意数量和类型的参数,代码更加灵活。

缺点:需要在函数内部进行参数类型的检查和转换,可能会影响代码的执行效率。

除了上述提到的传递方式外,还有一些特殊的传递方式,例如在 C++ 中使用 const 修饰符传递常量参数,使用 inline 函数将函数代码插入到调用点等。

在实际编写代码时,我们需要根据实际需求选择合适的形参传递方式,并遵守相关的编码规范和最佳实践,以保证代码的质量和可维护性。

VII. 注意的细节和注意事项

  1. 命名规范

在定义函数参数时,需要按照一定的命名规范来命名参数,以提高代码的可读性和可维护性。一般来说,可以采用下划线命名法或驼峰命名法来命名函数参数。

  1. 参数个数

在定义函数参数时,需要考虑到参数个数的问题。一般来说,函数参数个数不应该过多,否则会影响代码的可读性和可维护性。如果参数过多,可以考虑通过结构体或类等方式来组织参数。

  1. 参数类型

在定义函数参数时,需要考虑到参数类型的问题。一般来说,函数参数应该使用最简单的类型来表示,以提高代码的效率和可维护性。如果需要传递复杂的数据结构,可以使用指针或引用来传递参数。

  1. 参数顺序

在定义函数参数时,需要考虑到参数顺序的问题。一般来说,函数参数的顺序应该按照从左到右的顺序依次排列。如果有多个参数具有相同的类型,可以通过命名参数的方式来区分它们。

  1. 默认值

在定义函数参数时,需要考虑到默认值的问题。一般来说,可以为函数参数设置默认值,以提高代码的可读性和可维护性。如果需要传递多个参数,并且其中一些参数具有默认值,可以使用命名参数的方式来传递参数。

总之,编写函数参数时需要考虑到多方面的问题,并选择合适的形参传递方式和命名规范,以提高代码的质量和可维护性。在实际编写代码时,需要遵守相关的编码规范和最佳实践,以确保代码的可读性、效率和安全性。

VIII. 总结

形参是 C/C++ 语言中函数或方法的重要组成部分,它允许函数在执行过程中接收并使用调用者传递的数据。C/C++ 中的形参有多种传递方式,包括值传递、指针传递、引用传递、默认形参和可变参数模板等。

当选择形参传递方式时,应考虑代码的可读性、效率和可维护性。选择正确的形参传递方式可以提高代码的质量和效率。

总的来说,形参是 C/C++ 语言中非常重要的一个组成部分,它允许函数在执行过程中接收和使用数据,是代码质量和效率的重要影响因素。

这就是本次关于 C/C++ 形参的博客内容,希望对您有所帮助。

目录
相关文章
|
27天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
45 6
|
1月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
23 0
C++ 多线程之线程管理函数
|
1月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
23 3
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
156 1
|
1月前
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
30 1
|
1月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
41 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
1月前
|
算法 编译器 C++
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
77 2
|
2月前
|
编译器 C++
【C++核心】函数的应用和提高详解
这篇文章详细讲解了C++函数的定义、调用、值传递、常见样式、声明、分文件编写以及函数提高的内容,包括函数默认参数、占位参数、重载等高级用法。
22 3
|
3月前
|
编译器 C++ 容器
【C++】String常见函数用法
【C++】String常见函数用法