当前位置: 首页 > article >正文

C++函数传递引用或指针

常见变量用法

下面通过例子分别展示传递值、字符串、数组的用法
示例代码

#include <iostream>
#include <string>

// 函数接受一个整数的引用和一个整数的指针
void modifyValue(int& refValue, int* ptrValue) {
    refValue = 100;   // 通过引用修改值
    std::cout << "Value pointed by ptrValue: " << *ptrValue << std::endl;  // 通过指针打印值
}
//==========================================================================
// 函数接受一个字符串的引用
void modifyString(std::string& strRef) {
    strRef += " modified";
}
//==========================================================================
// 函数接受一个指向整型数组的指针
void modifyArray(int* arrPtr, int size) {
    for (int i = 0; i < size; ++i) {
        arrPtr[i] += 10; // 将数组中的每个元素增加10
    }
}

int main() {

    int value = 10;        // 声明一个整数值
    int anotherValue = 20; // 声明另一个整数值

    // 调用 modifyValue 函数,传递 value 的引用和 anotherValue 的地址
    modifyValue(value, &anotherValue);
    std::cout << "Modified value: " << value << std::endl;  // 打印修改后的 value

    // 打印 anotherValue,注意它不会被 modifyValue 函数修改
    std::cout << "anotherValue: " << anotherValue << std::endl;
    std::cout << "================================================" << std::endl;
    
    //==========================================================================
    // 调用 modifyString 函数,传递字符串的引用
    std::string myString = "Original String";
    modifyString(myString);
    std::cout << "Modified String: " << myString << std::endl;
    std::cout << "================================================" << std::endl;

    //==========================================================================
    // 调用 modifyArray 函数,传递数组的指针和大小
    // 当传递一个数组到函数时,它会被退化为一个指向其第一个元素的指针。
    // 因此,函数本身无法直接知道传入的数组的大小,因为数组的大小信息在传递时丢失了,所以必须在函数外计算数组长度。
    int myArray[] = { 1, 2, 3, 4, 5 }; // 任意长度的数组
    int arraySize = sizeof(myArray) / sizeof(myArray[0]); // 计算数组的大小
    modifyArray(myArray, arraySize);

    // 打印修改后的数组
    std::cout << "Modified Array: ";
    for (int item : myArray) {
        std::cout << item << " ";
    }
    std::cout << std::endl;

    return 0;
}

运行结果为

Value pointed by ptrValue: 20
Modified value: 100
anotherValue: 20
================================================
Modified String: Original String modified
================================================
Modified Array: 11 12 13 14 15

vector变量用法

给出示例

#include <iostream>
#include <vector>

// 函数接受一个 std::vector 的引用
// 如果无需修改 vector,可以传递一个常量引用。这样可以提高效率,因为编译器不需要为 vector 创建副本。(待确认?)
void printVector(const std::vector<int>& vec) {
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

void modifyVector1(std::vector<int> vec) {
    for (int& num : vec) {  // 注意:这里的修改不会影响原始的 myVector
        num *= 2; // 修改 vector 中的每个元素
    }
}

void modifyVector2(std::vector<int>& vec_ref) {
    for (int num : vec_ref) {  // 实际上为每个元素创建了副本,不会影响原始的 myVector
        num *= 2; // 修改 vector 中的每个元素
    }

    for (int& num : vec_ref) {  // 只有传进来的是引用且通过引用来访问其中的元素才会影响原始的 myVector
        num *= 2; // 修改 vector 中的每个元素
    }
}

void modifyVector3(std::vector<int>& vec_ref) {
    int length = vec_ref.size(); // 计算 vector 的长度
    for (int i = 0; i < length; ++i) {
        vec_ref[i] *= 2; // 修改 vector 中的每个元素
    }
}

int main() {
    std::vector<int> myVector = { 1, 2, 3, 4, 5 };

    modifyVector1(myVector);  // 调用函数,传递 vector 的拷贝
    printVector(myVector);   // 打印原始 vector,其内容不会改变

    modifyVector2(myVector);  // 调用函数,传递 vector 的引用
    printVector(myVector);   // 打印 vector,其内容会改变

    modifyVector3(myVector);  // 调用函数,传递 vector 的引用
    printVector(myVector);   // 打印 vector,其内容会改变

    return 0;
}

运行结果为

1 2 3 4 5
2 4 6 8 10
4 8 12 16 20

大多数情况下,传递 std::vector 的引用或常量引用是最佳选择,因为它们既能够访问 vector 的内容,又不会产生不必要的性能开销。传递指针在语法上也能实现,但据说用的不多。

补充说明

1. for (int& num : vec)for (int num : vec) 的用法

这两种循环都是基于范围的 for 循环,是 C++11 引入的新特性。

  • for (int num : vec):这种用法是创建 vec 中每个元素的副本。在这个循环中,numvec 中元素的拷贝,对 num 的任何修改都不会影响原始的 vec
  • for (int& num : vec):这种用法是通过引用来访问 vec 中的每个元素。在这个循环中,numvec 中元素的引用,对 num 的任何修改都会直接反映到原始的 vec 上。

应该在以下情况下使用 &

  • 当需要修改 vector 中的元素时。
  • 当处理的是大型对象,并且希望通过引用来避免不必要的拷贝,从而提高效率。

2. 推荐 std::vector 还是数组?功能上的差别(GPT生成)

一般来说,推荐使用 std::vector 而不是原生数组,因为 std::vector 提供了更多的便利和安全性。以下是两者的一些功能上的差别:

  • 动态大小std::vector 可以在运行时动态地改变其大小,而数组的大小在编译时是固定的。
  • 方便的接口std::vector 提供了如 push_back, pop_back, size, capacity 等有用的成员函数。
  • 自动管理内存std::vector 自动管理其元素的内存分配和释放,减少了内存泄漏的风险。
    以下是一个例子,展示了 std::vector 和数组的功能差异:
#include <iostream>
#include <vector>
int main() {
    // 使用数组
    int arr[5] = {1, 2, 3, 4, 5}; // 数组大小在编译时确定
    // arr.push_back(6); // 错误:数组没有 push_back 方法
    // 使用 std::vector
    std::vector<int> vec = {1, 2, 3, 4, 5}; // vector 可以动态改变大小
    vec.push_back(6); // 添加一个新元素到 vector
    // 打印 vector
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

在这个例子中,我们不能对数组 arr 使用 push_back 方法,因为数组不支持动态大小。而 std::vector 可以很容易地添加新元素。
总的来说,除非有特定的性能需求或限制,否则在大多数情况下,推荐使用 std::vector,因为它更灵活、更安全,并且更容易使用。

字符串的用法

在第一个示例的基础上进一步扩展说明字符串相关的用法。概括来讲:

  • 指针:适合处理 C 风格字符串(即以空字符 \0 结尾的字符数组),允许直接操作内存,但需要小心管理内存。
  • 引用:适合处理 C++ 的 std::string,语法简洁且安全,能够避免常见的字符串处理错误。

使用引用修改字符串:

#include <iostream>
#include <string>

// 修改字符串的函数,接受字符串的引用
void modifyString(std::string& str) {
    str += " modified";       // 修改传入的字符串
    str = "Modified string";  // 当然也可以直接修改引用对象的值
}

int main() {
    std::string myString = "Original string";
    std::cout << "Before modification: " << myString << std::endl;

    modifyString(myString);   // 调用函数,传递字符串的引用
    std::cout << "After modification: " << myString << std::endl;

    return 0;
}

使用指针修改字符串:
很容易出现各种bug,不推荐。

#include <iostream>
#include <cstring>

void modifyString(char* str) {
    if (str != nullptr) {
        // 使用strcpy_s函数修改字符串
        if (strcpy_s(str, strlen("Modified string") + 1, "Modified string") != 0) {
            std::cerr << "Error: Failed to modify string." << std::endl;
            return;
        }
    }
}

int main() {
    char myString[] = "Original string";
    std::cout << "Before: " << myString << std::endl; // 输出: Original string

    modifyString(myString);
    std::cout << "After: " << myString << std::endl; // 输出: Modified string

    return 0;
}

http://www.kler.cn/a/391827.html

相关文章:

  • Springboot集成syslog+logstash收集日志到ES
  • C# 委托与匿名方法
  • ML 系列: 第 24 节 — 离散概率分布(泊松分布)
  • 【秋招笔试-支持在线评测】11.13花子秋招(已改编)-三语言题解
  • 高频 SQL 50 题(基础版)连接部分
  • fastapi 查询参数支持 Pydantic Model:参数校验与配置技巧
  • linux基础入门实战
  • 特朗普上任在即,加密监管走向何方?
  • Jenkins安装自定义插件
  • 350. 两个数组的交集 II
  • python3的基本数据类型:Dictionary(字典)的创建
  • Python如何从HTML提取img标签下的src属性
  • 太速科技-440-基于XCVU440的多核处理器多输入芯片验证板卡
  • uniapp使用uni-tooltip自定义多行
  • hive中数据的粒度级别有哪些?
  • 视频智能分析平台LiteAIServer算法定制未戴安全帽检测技术:智能安防领域的新篇章
  • 2024最新版JavaScript逆向爬虫教程-------基础篇之面向对象
  • AI养宠:如何重塑宠物照护的未来
  • vue+vite前端项目ci过程中遇到的问题
  • 为什么你总是被割韭菜?揭秘币圈五大操控手段,教你如何避开“割韭菜”陷阱
  • 算力100问☞第1问:算力为什么重要?
  • JavaScript面向对象笔记(4)
  • 【LeetCode】每日一题 2024_11_12 统计满足 K 约束的子字符串数量 I(滑动窗口)
  • 【JAVA毕业设计】基于Vue和SpringBoot的微服务在线教育系统
  • 什么是 DAPP?它能解决什么问题?
  • pinia-plugin-persistedstate包安装失败解决办法