GESP四级 - 第一章 - 第2节 - 形参与实参

2024-05-24 05:04

本文主要是介绍GESP四级 - 第一章 - 第2节 - 形参与实参,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 形参与实参

1.1 什么是形参

形参(Formal Parameter)是在函数定义中声明的变量,用于接收调用函数时传递的实际参数值。形参定义了函数可以接受的数据类型和数量,它们在函数被调用时才会被创建,并在函数执行完毕后被销毁。

形参的声明语法如下:

返回值类型 函数名(参数类型1 参数名1, 参数类型2 参数名2, ...) {// 函数体
}

例如,以下函数有两个形参 ab,它们的类型都是 int

int add(int a, int b) {return a + b;
}

在函数定义中,形参的名称可以自由选择,但应该具有描述性,以便于理解其含义。形参的类型可以是任何有效的 C++ 数据类型,包括内置类型(如 intdoublechar 等)和用户自定义类型(如结构体、类等)。

形参在函数内部作为局部变量使用,它们的初始值由调用函数时传递的实际参数确定。在函数执行期间,可以像使用普通变量一样使用形参,对其进行读取、修改等操作。

需要注意的是,形参是函数定义的一部分,它们只在函数内部可见,而不能在函数外部访问。此外,形参是按值传递的,即在函数调用时,实际参数的值被复制给形参,函数内部对形参的修改不会影响实际参数。如果需要在函数内部修改实际参数的值,可以使用引用传递或指针传递。

总之,形参是函数定义中的一种特殊变量,用于接收调用函数时传递的实际参数值,并在函数内部使用。理解形参的概念和使用对于编写和调用函数非常重要。

1.2 什么是实参

实参(Actual Parameter)是在调用函数时传递给函数的实际值或表达式,它们对应于函数定义中的形参。实参提供了函数执行所需的具体数据,它们可以是变量、常量、表达式或其他函数的返回值。

在函数调用时,实参的值会被复制或传递给相应的形参,函数内部通过形参来访问和操作这些值。实参的数量、类型和顺序必须与函数定义中的形参相匹配,否则会导致编译错误或运行时错误。

函数调用时实参的传递语法如下:

函数名(实参1, 实参2, ...);

例如,对于以下函数定义:

int add(int a, int b) {return a + b;
}

我们可以使用以下代码调用该函数并传递实参:

int result = add(10, 20);

在这个例子中,1020 是传递给 add 函数的实参,它们分别对应于函数定义中的形参 ab。函数内部通过 ab 来访问实参的值,并执行相应的操作。

实参可以是各种类型的值或表达式,包括:

1 . 字面量:如整数、浮点数、字符等。

int result = add(10, 20);

2 . 变量:传递变量的值给函数。

int x = 10, y = 20;
int result = add(x, y);

3 . 表达式:传递表达式的计算结果给函数。

int result = add(5 + 3, 2 * 4);

4 . 函数调用:传递其他函数的返回值给函数。

int square(int x) {return x * x;
}
int result = add(square(3), square(4));

实参是函数调用的一部分,它们提供了函数执行所需的具体数据。通过传递适当的实参,我们可以控制函数的行为和结果。理解实参的概念和使用对于正确调用函数和传递数据非常重要。

1.3 形参与实参的关系

形参和实参是函数定义和函数调用中的两个重要概念,它们之间存在着密切的关系。下面我们来详细探讨形参和实参之间的关系:

1 . 对应关系:

  • 函数调用时,实参的数量、类型和顺序必须与函数定义中的形参相匹配。
  • 每个实参对应一个形参,按照顺序一一对应。
  • 实参的类型必须与对应的形参类型兼容,或者能够隐式转换为形参的类型。

2 . 值传递:

  • 默认情况下,实参是按值传递给形参的。
  • 在函数调用时,实参的值被复制给对应的形参,函数内部操作的是形参的副本。
  • 函数内部对形参的修改不会影响实参的值。

3 . 参数匹配:

  • 实参的类型必须与对应的形参类型相同或兼容。
  • 如果实参的类型与形参的类型不完全匹配,编译器会尝试进行隐式类型转换。
  • 如果无法进行隐式类型转换,或者转换可能导致数据丢失,编译器会报错。

4 . 参数数量:

  • 实参的数量必须与函数定义中的形参数量相同。
  • 如果实参的数量多于或少于形参的数量,编译器会报错。

5 . 参数顺序:

  • 实参的顺序必须与形参的顺序相同。
  • 实参按照从左到右的顺序依次对应形参。

6 . 默认参数:

  • 在 C++中,可以为形参指定默认值。
  • 如果在函数调用时省略了某个实参,对应的形参将使用默认值。
  • 默认参数必须从右向左连续指定,不能跳过中间的参数。

7 . 引用传递和指针传递:

  • 除了按值传递,C++还支持按引用传递和按指针传递。
  • 按引用传递时,形参作为实参的别名,函数内部对形参的修改会影响实参的值。
  • 按指针传递时,形参是指向实参的指针,函数内部通过指针可以修改实参的值。

下面是一个示例,演示了形参和实参的关系:

// 函数定义
int add(int a, int b) {return a + b;
}// 函数调用
int main() {int x = 10, y = 20;int result = add(x, y);  // 实参 x 和 y 对应形参 a 和 bcout << "Result: " << result << endl;return 0;
}

在这个例子中,add函数有两个形参ab,在main函数中调用add函数时,实参xy分别对应形参ab,并将它们的值传递给形参。函数内部通过形参ab来访问实参的值,并执行相应的操作。

理解形参和实参的关系对于正确定义和调用函数非常重要。通过匹配实参和形参,我们可以将数据传递给函数,控制函数的行为和结果。同时,也要注意参数的类型、数量和顺序,以及传递方式的选择,以确保函数的正确性和可读性。

1.4 按值传递

按值传递是函数参数传递的默认方式,也是最常见的参数传递方式之一。在按值传递中,实参的值被复制给函数的形参,函数内部操作的是形参的副本,而不是实参本身。

按值传递的特点如下:

  1. 实参的值被复制给形参,函数内部使用的是形参的副本。
  2. 函数内部对形参的修改不会影响实参的值。
  3. 实参和形参是独立的存储空间,它们之间没有直接的关联。

按值传递的语法如下:

返回值类型 函数名(参数类型1 参数名1, 参数类型2 参数名2, ...) {// 函数体
}

下面是一个按值传递的示例:

void swapValues(int a, int b) {int temp = a;a = b;b = temp;cout << "Inside function: a = " << a << ", b = " << b << endl;
}int main() {int x = 10, y = 20;cout << "Before function call: x = " << x << ", y = " << y << endl;swapValues(x, y);cout << "After function call: x = " << x << ", y = " << y << endl;return 0;
}

输出结果:

Before function call: x = 10, y = 20
Inside function: a = 20, b = 10
After function call: x = 10, y = 20

在这个示例中,swapValues函数接受两个整型参数ab,函数内部交换了ab的值。但是,由于是按值传递,函数内部操作的是ab的副本,而不是实参xy。因此,在函数调用后,实参xy的值并没有发生改变。

按值传递的优点是简单明了,函数内部对形参的修改不会影响实参,提供了一定的安全性和隔离性。但是,当传递大型对象或数组时,按值传递会导致性能开销,因为需要复制整个对象或数组。在这种情况下,可以考虑使用引用传递或指针传递来提高效率。

总之,按值传递是函数参数传递的一种基本方式,它将实参的值复制给形参,函数内部操作的是形参的副本。理解按值传递的特点和适用场景,可以帮助我们合理选择参数传递方式,编写正确高效的函数。

1.5 按引用传递

按引用传递是 C++ 中另一种常用的参数传递方式,它允许函数直接访问和修改实参的值。在按引用传递中,形参作为实参的别名(引用),对形参的任何操作都会直接影响实参。

按引用传递的特点如下:

  1. 形参是实参的引用(别名),它们指向同一个内存位置。
  2. 通过形参可以直接访问和修改实参的值。
  3. 函数内部对形参的修改会影响实参的值。
  4. 按引用传递可以避免大型对象或数组的复制,提高性能。

按引用传递的语法如下:

返回值类型 函数名(参数类型1& 参数名1, 参数类型2& 参数名2, ...) {// 函数体
}

注意,在形参的类型后面添加了 & 符号,表示该形参是一个引用。

下面是一个按引用传递的示例:

void swapValues(int& a, int& b) {int temp = a;a = b;b = temp;cout << "Inside function: a = " << a << ", b = " << b << endl;
}int main() {int x = 10, y = 20;cout << "Before function call: x = " << x << ", y = " << y << endl;swapValues(x, y);cout << "After function call: x = " << x << ", y = " << y << endl;return 0;
}

输出结果:

Before function call: x = 10, y = 20
Inside function: a = 20, b = 10
After function call: x = 20, y = 10

在这个示例中,swapValues 函数的参数 ab 都是引用类型,它们分别绑定到实参 xy。在函数内部,通过修改 ab 的值,实际上就是直接修改 xy 的值。因此,在函数调用后,实参 xy 的值发生了交换。

按引用传递的优点是可以直接修改实参的值,避免了大型对象或数组的复制,提高了性能。但是,由于函数内部可以修改实参的值,使用时需要格外小心,确保引用参数的使用是安全和正确的。

在使用按引用传递时,需要注意以下几点:

  1. 引用参数必须是一个左值(可以取地址的表达式),不能是常量或字面量。
  2. 引用参数的类型必须与实参的类型匹配或兼容。
  3. 在函数内部,不能将引用参数重新绑定到其他对象上。

总之,按引用传递是 C++ 中一种强大的参数传递方式,它允许函数直接访问和修改实参的值,提高了性能和灵活性。合理使用按引用传递可以使代码更加高效和简洁,但同时也需要注意引用参数的正确性和安全性。

好的,下面是5个按引用传递的正确示例:

好的,以下是按照给定格式的5个按引用传递的示例:

示例1: 交换两个整数的值

#include <iostream>
using namespace std;void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}int main() {int x = 10, y = 20;cout << "交换前: x = " << x << ", y = " << y << endl;swap(x, y);cout << "交换后: x = " << x << ", y = " << y << endl;return 0;
}

示例2: 修改字符串的内容

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;void toUpperCase(string& str) {for (char& c : str) {c = toupper(c);}
}int main() {string message = "Hello, world!";cout << "转换前: " << message << endl;toUpperCase(message);cout << "转换后: " << message << endl;return 0;
}

示例3: 计算数组元素的和

#include <iostream>
using namespace std;void sumArray(int arr[], int size, int& sum) {sum = 0;for (int i = 0; i < size; i++) {sum += arr[i];}
}int main() {int numbers[] = {1, 2, 3, 4, 5};int size = sizeof(numbers) / sizeof(numbers[0]);int sum = 0;sumArray(numbers, size, sum);cout << "数组元素的和: " << sum << endl;return 0;
}

示例4: 修改结构体成员的值

#include <iostream>
#include <string>
using namespace std;struct Person {string name;int age;
};void increaseAge(Person& person) {person.age++;
}int main() {Person john = {"John", 30};cout << "修改前: " << john.name << " 的年龄是 " << john.age << " 岁." << endl;increaseAge(john);cout << "修改后: " << john.name << " 的年龄是 " << john.age << " 岁." << endl;return 0;
}

示例5: 返回多个值

#include <iostream>
using namespace std;void getMinMax(int arr[], int size, int& min, int& max) {min = max = arr[0];for (int i = 1; i < size; i++) {if (arr[i] < min) {min = arr[i];}if (arr[i] > max) {max = arr[i];}}
}int main() {int numbers[] = {10, 5, 8, 20, 3};int size = sizeof(numbers) / sizeof(numbers[0]);int min, max;getMinMax(numbers, size, min, max);cout << "最小值: " << min << endl;cout << "最大值: " << max << endl;return 0;
}

这些示例按照给定的格式展示了按引用传递在不同场景下的应用。每个示例都包含了完整的代码,并使用中文进行了输出和注释。希望这些示例能够清晰地展示按引用传递的用法和效果。

1.6 数组作为函数参数

在 C++ 中,数组可以作为函数的参数进行传递。当数组作为函数参数时,实际上传递的是数组的首地址,而不是整个数组的副本。这意味着在函数内部对数组元素的修改会直接影响原始数组。

将数组作为函数参数传递的语法如下:

返回值类型 函数名(数组类型 数组名[],int 数组大小)
{// 函数体
}

其中,数组类型是数组元素的类型,数组名是形参的名称,数组大小是数组的大小(元素个数)。注意,数组作为函数参数时,不需要指定数组的大小,因为数组大小可以通过另一个参数或其他方式传递。

下面是一个将数组作为函数参数的示例:

示例: 计算数组元素的平均值

#include <iostream>
using namespace std;double calculateAverage(int arr[], int size) {double sum = 0;for (int i = 0; i < size; i++) {sum += arr[i];}return sum / size;
}int main() {int numbers[] = {10, 20, 30, 40, 50};int size = sizeof(numbers) / sizeof(numbers[0]);double average = calculateAverage(numbers, size);cout << "数组元素的平均值: " << average << endl;return 0;
}

在这个示例中,calculateAverage函数接受一个整型数组arr和数组的大小size作为参数。函数内部通过循环遍历数组元素,计算元素的总和,然后除以数组的大小,得到平均值并返回。

main函数中,我们定义了一个整型数组numbers,并使用sizeof运算符计算数组的大小。然后,将数组numbers和大小size作为参数传递给calculateAverage函数,得到数组元素的平均值,并输出结果。

需要注意的是,当数组作为函数参数传递时,实际上传递的是数组的首地址。因此,在函数内部对数组元素的修改会直接影响原始数组。这种行为称为"按引用传递"。

另外,在函数参数中,我们也可以使用指针来表示数组,语法如下:

返回值类型 函数名(数组类型* 指针名,int 数组大小)
{// 函数体
}

使用指针作为函数参数可以更明确地表示传递的是数组的地址,但功能上与直接使用数组名是等价的。

总之,将数组作为函数参数传递是 C++ 中常见的操作,它允许函数直接访问和修改原始数组的元素。通过将数组的地址传递给函数,可以避免复制整个数组,提高了效率。但同时也需要注意,在函数内部对数组元素的修改会影响原始数组,使用时要谨慎。

示例1: 查找数组中的最大元素

#include <iostream>
using namespace std;int findMax(int arr[], int size) {int max = arr[0];for (int i = 1; i < size; i++) {if (arr[i] > max) {max = arr[i];}}return max;
}int main() {int numbers[] = {10, 5, 8, 20, 3};int size = sizeof(numbers) / sizeof(numbers[0]);int maxElement = findMax(numbers, size);cout << "数组中的最大元素: " << maxElement << endl;return 0;
}

在这个示例中,findMax函数接受一个整型数组arr和数组的大小size作为参数。函数内部通过循环遍历数组元素,找到最大的元素并返回。在main函数中,将数组numbers和大小size传递给findMax函数,得到数组中的最大元素并输出。

示例2: 反转数组中的元素

#include <iostream>
using namespace std;void reverseArray(int arr[], int size) {int start = 0;int end = size - 1;while (start < end) {int temp = arr[start];arr[start] = arr[end];arr[end] = temp;start++;end--;}
}int main() {int numbers[] = {1, 2, 3, 4, 5};int size = sizeof(numbers) / sizeof(numbers[0]);cout << "反转前: ";for (int i = 0; i < size; i++) {cout << numbers[i] << " ";}cout << endl;reverseArray(numbers, size);cout << "反转后: ";for (int i = 0; i < size; i++) {cout << numbers[i] << " ";}cout << endl;return 0;
}

在这个示例中,reverseArray函数接受一个整型数组arr和数组的大小size作为参数。函数内部使用双指针的方法,从数组的两端开始交换元素,直到指针相遇。在main函数中,将数组numbers和大小size传递给reverseArray函数,实现数组元素的反转,并输出反转前后的数组。

示例3: 计算数组中正数的个数

#include <iostream>
using namespace std;int countPositives(int arr[], int size) {int count = 0;for (int i = 0; i < size; i++) {if (arr[i] > 0) {count++;}}return count;
}int main() {int numbers[] = {-2, 5, 0, -8, 10, 3};int size = sizeof(numbers) / sizeof(numbers[0]);int positiveCount = countPositives(numbers, size);cout << "数组中正数的个数: " << positiveCount << endl;return 0;
}

在这个示例中,countPositives函数接受一个整型数组arr和数组的大小size作为参数。函数内部通过循环遍历数组元素,统计正数的个数并返回。在main函数中,将数组numbers和大小size传递给countPositives函数,得到数组中正数的个数并输出。

这些示例展示了将数组作为函数参数的不同应用场景,包括查找最大元素、反转数组和计算正数个数。通过将数组传递给函数,我们可以对数组进行各种操作和计算,使代码更加模块化和可重用。

1.7 指针作为函数参数

在 C++ 中,指针也可以作为函数的参数进行传递。通过将指针传递给函数,我们可以在函数内部直接访问和修改指针所指向的内存位置的值。这提供了一种高效且灵活的方式来操作数据。

将指针作为函数参数传递的语法如下:

返回值类型 函数名(指针类型* 指针名)
{// 函数体
}

其中,指针类型是指针所指向的数据类型,指针名是形参的名称。

下面是一个将指针作为函数参数的示例:

示例1: 交换两个整数的值

#include <iostream>
using namespace std;void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}int main() {int x = 10, y = 20;cout << "交换前: x = " << x << ", y = " << y << endl;swap(&x, &y);cout << "交换后: x = " << x << ", y = " << y << endl;return 0;
}

在这个示例中,swap函数接受两个整型指针ab作为参数。函数内部通过解引用操作符*来访问指针所指向的内存位置,并交换它们的值。

main函数中,我们定义了两个整型变量xy,并将它们的地址&x&y作为参数传递给swap函数。在函数内部,通过指针来交换xy的值。最后,输出交换前后的xy的值。

示例2: 修改字符串的内容

#include <iostream>
#include <cstring>
using namespace std;void toUpperCase(char* str) {int length = strlen(str);for (int i = 0; i < length; i++) {if (str[i] >= 'a' && str[i] <= 'z') {str[i] = str[i] - 'a' + 'A';}}
}int main() {char message[] = "Hello, world!";cout << "转换前: " << message << endl;toUpperCase(message);cout << "转换后: " << message << endl;return 0;
}

在这个示例中,toUpperCase函数接受一个字符指针str作为参数。函数内部通过指针来访问字符串的每个字符,并将小写字母转换为大写字母。

main函数中,我们定义了一个字符数组message,并将其作为参数传递给toUpperCase函数。函数内部通过指针来修改字符串的内容,将其转换为大写。最后,输出转换前后的字符串。

示例3: 动态分配内存

#include <iostream>
using namespace std;void allocateArray(int** arr, int size) {*arr = new int[size];for (int i = 0; i < size; i++) {(*arr)[i] = i + 1;}
}int main() {int* numbers = nullptr;int size = 5;allocateArray(&numbers, size);cout << "动态分配的数组: ";for (int i = 0; i < size; i++) {cout << numbers[i] << " ";}cout << endl;delete[] numbers;return 0;
}

在这个示例中,allocateArray函数接受一个指向整型指针的指针arr和数组大小size作为参数。函数内部使用new运算符动态分配一个整型数组,并将其地址赋值给指针*arr。然后,通过指针来初始化数组的元素。

main函数中,我们定义了一个整型指针numbers和数组大小size。将numbers的地址&numberssize作为参数传递给allocateArray函数。函数内部动态分配一个数组,并将其地址赋值给numbers。最后,输出动态分配的数组,并使用delete[]运算符释放内存。

这些示例展示了将指针作为函数参数的不同应用场景,包括交换整数值、修改字符串内容和动态分配内存。通过将指针传递给函数,我们可以在函数内部直接访问和修改指针所指向的内存位置的值,提供了一种高效且灵活的方式来操作数据。但同时也需要注意指针的正确使用和内存管理,避免出现内存泄漏或非法访问的问题。

这篇关于GESP四级 - 第一章 - 第2节 - 形参与实参的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/997444

相关文章

【自然语言处理】第一章绪论

第一章 绪论 文章目录 第一章 绪论1. 什么是自然语言2. 自然语言处理的定义2.1 自然语言处理NLP2.2 计算语言学CL2.3 NLP与CL 3. 自然语言处理的研究内容3.1 研究对象3.2 研究层次3.3 研究问题3.4 研究内容3.4.1 资源建设3.4.2 基础研究3.4.3 应用技术研究3.4.4 应用系统 4. 自然语言处理的流派5. 自然语言处理的挑战

第一章 MUD:创造世界的巫师

自从有了游戏之后,人们不满足于做屏幕前的操控者,而是梦想着自己能够进入到游戏的绚丽世界中,在剑与魔法的世界中拯救世界,称为吟游诗人歌颂的屠龙 勇者,或者在武侠世界中快意恩仇,体验江湖恩怨儿女情长。网络游戏的出现让这个梦想渐渐变为可以触摸的东西,直至成为现实。   如果要追溯网络游戏的历史,我们要将目光投向20世纪70年代。早在1969年,美国人瑞克•布罗米(Rick Blom

java复习第十课,方法的本质,形参和实参(很重要)

java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,声明格式: 修饰符[public]  修饰符2[static]  返回值类型[int、String等]  方法名 (形参列表){ java语句列表..... } 形式参数:在方法被调用时用于接受外界输入的数据 实参:调用方法时实际传递给方法的数据 返回值:方法在执行完毕后返还给调用它的环境的数据 返回值类型:事先约

第一篇 第一章资金时间价值计算及应用 第二章经济效果评价

第1章 资金时间价值计算及应用 资金具有时间价值 1.1 利息的计算 1.1.1 利息和利率 I=F-P 债务人为资金需求方 债权人为资金供给方利息对经济活动的影响(1.影响企业行为 2.影响居民资产选择行为 3.影响政府行为) 利率 1.影响因素(1.社会平均利润率的高低 2.市场资金供求对比状况 3.资金要承担的风险 4.债务资金使用期限长短 5.政府宏观调控政策 6.经济周期所处

第一章 软件工程的概述简记

第一章  软件工程的概述         *软件的概念:软件(Software)是一系列按照特定顺序组织的计算机数据和指令的集合。         软件的分类:(5大类)                   *1.基于软件功能划分                                  1)系统软件

第一章——计算机系统概述

🌈个人主页:小新_- 🎈个人座右铭:“成功者不是从不失败的人,而是从不放弃的人!”🎈 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝 🏆所属专栏: 计算机组成原理   欢迎订阅,持续更新中~~~                                                       ✨让小新带着你快乐的学习吧~✨ 目录 前言 一、操作系统的概念和

第一章 感受mac之美-换一种方式用电脑,开启新历程

感谢关注我的读者一直以来的追随与信任。去年到今年以来大环境都不是很好。裁员,机构优化,工厂倒闭,公司破产,贸易战等消息传来,不少还是身边发生的。今年开年以来更是有病毒横行,天降蝗灾等灾害。愿大家都好好的,同时希望这场战役早早告捷。今天是二月二 ,民间传说龙抬头,祝愿大家从此事业腾飞,从此出人头地。 我在这断更的两年中的一些情况,一直处于闭关的状态,一直在学习与实践。后续再和大家一起分享这俩年

考研408《计算机组成原理》复习笔记,第一章计算机系统概述

本人打算从今到2026年不再更新过多的前后端开发的笔记,因为要准备考研了,所以停更前面的开发教程。 这些都是我看完书、视频、做完题后,结合个人理解总结的知识点,希望对各位有帮助。一切都是用最快最精炼的方式讲清楚。 一、计算机发展历程 第一代:电子管时代第二代:晶体管时代第三代:中小规模集成电路时代第四代:超大规模集成电路时代 就这么记就行了,很少考你历程这些细节的。 二、计算机系统结

2024年六月英语四级真题及解析PDF共9页

2024年六月英语四级真题及解析PDF共9页,真题就是最好的复习资料,希望对大家有所帮助。

2024年6月第2套英语四级真题PDF

2024年6月第2套英语四级真题PDF