首页 > 编程语言 >C++函数传递引用或指针

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

时间:2024-11-13 15:50:23浏览次数:3  
标签:std num int C++ vector 引用 vec 指针

常见变量用法

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

#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;
}

标签:std,num,int,C++,vector,引用,vec,指针
From: https://blog.csdn.net/gsgbgxp/article/details/143662954

相关文章

  • 指针加法中的隐形偏差:一次不该有的偏移踩坑
    在最近的开发中,有这样的一个需求,给一个结构体,我需要传出这个结构体的个别成员的地址,offsetof这个宏函数可以很好的解决这个业务需求,但是我还是踩坑了。下面看看我的踩坑记录。我们知道一个(TInfoRom*)infoRom类型的结构体指针,他指向当前结构体变量的首地址。我们可以通过off......
  • 用matlab算子提取相机亮度一致性曲线,转VC++实现
    用matlab的算子,提取相机亮度一致性曲线,用曲线调节相机亮度一致性。用C++开发,开发工具vs2019,使用迈德威视的相机。算法原理:间隔提取整副图像中的采集点,横向10点,竖向10点,均匀覆盖整图,采样不同曝光时间采集N帧图像,然后计算亮度的变化趋势,得到亮度曲线。读取原始图片,把......
  • 打卡信奥刷题(225)用C++工具信奥P1760[普及组/提高] 通天之汉诺塔
    通天之汉诺塔题目背景直达通天路·小A历险记第四篇题目描述在你的帮助下,小A成功收集到了宝贵的数据,他终于来到了传说中连接通天路的通天山。但是这距离通天路仍然有一段距离,但是小A突然发现他没有地图!!!但是幸运的是,他在山脚下发现了一个宝箱。根据经验判断(小A有经......
  • Foxit PDF Conversion SDK (C++, Linux ARM)-2.0.2
    FoxitPDFConversionSDKisaflexiblehigh-performancelibraryforconversionbetweenPDFfiles andMSOfficefileswhilemaintainingthelayoutandformatofyouroriginaldocuments.Itoffers advancedconversioncapabilitiesaswellasthesamequa......
  • C语言指针详解:用法与实例
    目录C语言指针详解:用法与实例引言1.指针基础1.1什么是指针?1.2如何声明指针?1.3获取变量的地址1.4解引用指针2.指针的高级用法2.1指针和数组2.2指针和函数参数2.3指针和动态内存分配3.指针的注意事项3.1空指针3.2悬空指针3.3指针运算C语言指针详......
  • C++动态库封装C#库,验证动态库环境
    windows平台、VS2019、x64当C++编译的动态库提供给C#的开发人员时,需要实现一个C#的库使用委托去调用C++动态库。当C#开发人员链接使用C#的动态库时,如果没有完全拷贝C++动态库所依赖的其他动态库时,就会出现运行报错。但是报错时,不会提示缺少了什么库,这里在C#的中增加一个函数......
  • 在Odoo开发中,ref是一个非常重要的函数,用于在XML文件中引用其他数据的ID,帮助我们快速定
    在Odoo开发中,ref是一个非常重要的函数,用于在XML文件中引用其他数据的ID,帮助我们快速定位和调用系统中已经存在的记录。ref的全称是reference,可以通过该函数引用特定的视图、字段、模型等元素,从而在模块开发中实现跨文件、跨模块的引用。下面我会详细解释ref的作用,并提供丰富的示例......
  • SAM4MLLM:结合多模态大型语言模型和SAM实现高精度引用表达分割 | ECCV'24
    来源:晓飞的算法工程笔记公众号,转载请注明出处论文:SAM4MLLM:EnhanceMulti-ModalLargeLanguageModelforReferringExpressionSegmentation论文地址:https://arxiv.org/abs/2409.10542论文代码:https://github.com/AI-Application-and-Integration-Lab/SAM4MLLM创......
  • C++基础学习6
    //练习://1.计算圆柱体体积和表面积//定义π=3.14159,输入半径r和高h。//公式://圆柱体积:体积=π*r^2*h//圆柱表面积:表面积=2*π*r*(r+h)////#define_CRT_SECURE_NO_WARNINGS1//#include<stdio.h>//#defineX3.14159//intmain()//{// floa......
  • 每日OJ题_牛客_kotori和迷宫_BFS_C++_Java
    目录牛客_kotori和迷宫_BFS题目解析C++代码Java代码牛客_kotori和迷宫_BFSkotori和迷宫描述:        kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口。kotori只能上下左右四个方向移动。她想知道有多少出口是她能到达的,最近的出口离她......