首页 > 编程语言 >C++ 以指针(*)作为参数和以指针引用(*&)作为参数的区别

C++ 以指针(*)作为参数和以指针引用(*&)作为参数的区别

时间:2024-02-20 15:35:18浏览次数:33  
标签:10 int C++ 地址 参数 数组 targetArray 指针

首先说结论,传入指针只能更改指针所指向的那一块内存的数据,传入指针引用既能修改指针本身的地址也能修改指针所指向的内存。

假设现在有这样一个功能:传入一个数组指针,并将另一个数组的地址赋值给被传入的指针,以完成数据更新功能。

定义两个函数,分别以指针和指针引用为参数:

//数组大小
const int arraySize = 10;
//备用数组,用于替换传入到函数中的数组指针
int sourceArray[arraySize] = {10,9,8,7,6,5,4,3,2,1};
//辅助函数,用于打印数组中的全部数据
void printArray(int* array,int size)
{
    QString str;
    for(int i = 0; i < size; i++)
    {
        str.append(QString::number(array[i])).append(" ");
    }
    qDebug()<<str;
}
//传入数组指针
void changePtr(int* array)
{
    qDebug()<<"pointer to:"<<array<<"address of pointer is:"<<&array;
    array = sourceArray;
}
//传入数组指针引用
void changePtrRef(int*& array)
{
    qDebug()<<"pointer to:"<<array<<"address of pointer is:"<<&array;
    array = sourceArray;
}

然后在main函数中定义如下代码:

 1 int main()
 2 {
 3     int* targetArray = new int[arraySize];
 4     for(int i = 0; i < arraySize; i++)
 5     {
 6         targetArray[i] = (i+1)*10;
 7     }
 8     qDebug()<<"pointer to:"<<targetArray<<"address of pointer is:"<<&targetArray;
 9     printArray(targetArray,arraySize);
10 
11     changePtr(targetArray);
12     printArray(targetArray,arraySize);
13 
14     changePtrRef(targetArray);
15     printArray(targetArray,arraySize);
16 }

 

在main函数中,定义了一个targetArray数组,并将这个数组初始化为{10,20,30,40,50,60,70,80,90,100},分别将这个数组传入到changePtr函数和changePtrRef中,在这两个函数中会分别打印传入数组指针的地址和指针指向的地址,在更替了数组指针之后,打印数组中的内容。

运行程序,输出如下:

 #8:数组targetArray定义完成之后,自身的地址为0xa9fc40,指针指向的地址为0x34f1bd0,此时数组内的数据为:"10 20 30 40 50 60 70 80 90 100 "

#11:将数组targetArray传入到changePtr(int*)函数中,此时传入的指针自身的地址为0xa9fc00,指针指向的地址为0x34f1bd0,由此可以发现,此时在changePtr函数内的指针虽然也指向地址0xa9fc40,但是它本身却是targetArray指针的一个拷贝。也就是说,存在两个不一样的指针,但是它们都指向同一个地址。

#12:changePtr(int*)执行完成之后,打印targetArray数组中的内容:"10 20 30 40 50 60 70 80 90 100 "可以发现数组中的值其实还是以前的值。changePtr(int*)替换指针并没有真正能做到更新数组的内容,因此被替换的指针实际上是targetArray的一个拷贝,真正的targetArray并没有受到任何影响。

#14:将数组指针传入到changeRefPtr(int*&)函数中,此时传入的指针自身的地址为0xa9fc40,指针指向的地址为0x34f1bd0,这个地址和targetArray完全一致,说明此时changeRefPtr(int*&)函数中所使用的指针就是targetArray本身,而不是targetArray的一个拷贝。

#15:changeRefPtr(int*&)执行完成之后,打印targetArray数组中的内容:"10 9 8 7 6 5 4 3 2 1 ",此时数组中的内容被更新。

结论:当传入指针的时候,函数内部使用的指针是外部指针的一个拷贝,此时只能对指针所指向的内容进行修改,而无法更改指针本身的地址(这种情况还会出现在最后的例子中)。当传入指针的引用时,函数内部使用的就是外部指针本身,此时既可以修改指针所指向的内容,也可以对指针本身进行修改。

补充:传入一个数组空指针,在函数内部对数组分配内存并初始化数组。

 1     void initArray(int* array)
 2     {
 3         array = new int[10];
 4         for(int i = 0; i < 10; i++)
 5         {
 6             array[i] = i;
 7         }
 8     }
 9     
10     int main()
11     {
12          int * target= nullptr;
13          initArray(target);
14     }

#13:这一行代码执行完成之后,target依然是一个空指针,以为内存被分配到另一个地址的指针上了,array本身没有得到任何改变。但是如果initArray(int* array)更改为initArray(int*& array)之后,target就能被正确地初始化。

 

标签:10,int,C++,地址,参数,数组,targetArray,指针
From: https://www.cnblogs.com/leocc325/p/18023216

相关文章

  • 新版VSC++安装QuantLib量化工具包安装及其使用
    1.下载安装boosthttps://boostorg.jfrog.io/artifactory/main/release/建议安装与当前电脑VS版本年份差不多的boost自行设置安装路径2.去Github下载开源代码QuantLibhttps://github.com/lballabio/QuantLib/releases下载解压3.安装VS安装C++window桌面开发环境!4.打......
  • fastDFS:优化参数配置,让dfs集群更灵敏
    【storage.conf】配置文件#connecttimeoutinseconds#defaultvalueis30#Note:intheintranetnetwork(LAN),2secondsisenough.connect_timeout=2#networktimeoutinsecondsforsendandrecv#defaultvalueis30network_timeout=60#theheartbeati......
  • C++函数用法
    1.getline函数的用法函数声明boolgetline(istream&in,string&s)功能说明从输入流读入一行到变量strings,即使是空格也可以读入。直到出现以下情况为止:读入了文件结束标志读到一个新行(有重载函数可以指定行分隔符,默认是"\n".)达到字符串的最大长度如果getline没有读......
  • 用C++实现string类
    今天用C++实现了一个string类,包括构造函数、拷贝构造、赋值构造、流输出、移动构造、重载+号,发现很多细节都没有考虑到,细节都在注释中,贴在这里作为备忘吧。 1#include<iostream>2#include<cstring>34usingnamespacestd;567classMyString{......
  • C++(2)Big-Endian VS Littler-Endian
    1、概念大端:高字节存放在低地址,低字节存放在高地址。小端:低字节存放在低地址,高字节存放在高地址。简称“低低小”2、如何判别大端小端intIsSmallEnd2(){ inti=0x11223344; if(*(char*)(&i)==0x44) { return1; } else return0;}......
  • c++小游戏合集
    1.恶魔轮盘赌恶魔轮盘赌代码#include<windows.h>#include<bits/stdc++.h>usingnamespacestd;intYour=6,Other=6;stringdaojuname[]={"放大镜","手铐","小刀","烟","饮料"};doubleYourmoney;intshi,kong;intq[10],......
  • C++ lambda表达式
    C++lambda表达式,又称为闭包,匿名函数入门语法举个例子autof=[](inta,intb){returna<b;};std::vector<int>vec={0,11,2,23,4};std::sort(vec.begin(),vec.end(),f);上面的就是通过一个简单的匿名函数来简化了排序,lambda表达式具体语法如下......
  • 【三分钟开服仅32/月】幻兽帕鲁服务器最新一键部署以及修改游戏参数保姆教程
    前言《幻兽帕鲁》是Pocketpair开发的一款开放世界生存制作游戏,游戏于2023年11月2日至11月5日进行了封闭网络测试,于2024年1月18日发行抢先体验版本。游戏中,玩家可以在广阔的世界中收集神奇的生物“帕鲁”,派他们进行战斗、建造、做农活,工业生产等游戏支持单人游玩&创建本地房间(最......
  • Linux 管道与参数传递(xargs&exec)
    深入学习链接:Linux的进程间通信:管道-知乎(zhihu.com)             Linux管道符|命令使用详解_linux中|的用法-CSDN博客 一、什么是管道?    管道(pipe),在任何一个shell中,都可以使用“|”连接两个命令,shell会将前后两个进程的输入输出用一个......
  • Spring Boot 实现各种参数校验
    之前也写过一篇关于SpringValidation使用的文章,不过自我感觉还是浮于表面,本次打算彻底搞懂SpringValidation。本文会详细介绍SpringValidation各种场景下的最佳实践及其实现原理,死磕到底!项目源码:spring-validation:https://github.com/chentianming11/spring-validation简单使......