首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我不能在函数中改变指针(重新赋值)?

在函数中改变指针(重新赋值)的原因是因为函数参数传递的方式是按值传递。当我们将指针作为参数传递给函数时,实际上是将指针的副本传递给了函数,而不是指针本身。因此,当我们在函数中重新赋值指针时,只是修改了指针副本的值,并不会影响到原始指针。

这种按值传递的方式可以理解为将指针的值复制给了函数内部的一个新的指针变量,这个新的指针变量与原始指针指向的是同一个内存地址。当我们在函数中重新赋值这个新的指针变量时,只是修改了这个新的指针变量的值,并不会改变原始指针的值。

如果我们想在函数中改变指针的值,可以通过传递指针的指针或者指针的引用来实现。这样,在函数中修改指针的值时,实际上是修改了原始指针的值。

以下是一个示例代码:

代码语言:txt
复制
#include <iostream>

void changePointer(int** ptr) {
    int* newPtr = new int(10);
    *ptr = newPtr;
}

int main() {
    int* ptr = nullptr;
    changePointer(&ptr);
    std::cout << *ptr << std::endl;  // 输出 10
    delete ptr;
    return 0;
}

在上述代码中,我们定义了一个函数changePointer,它接受一个指向指针的指针作为参数。在函数内部,我们创建了一个新的指针newPtr并将其赋值为10,然后通过修改指针的指针ptr的值,将其指向newPtr。在main函数中,我们调用changePointer函数,并输出ptr指向的值,可以看到输出结果为10。

需要注意的是,在使用完动态分配的内存后,我们需要手动释放内存,以避免内存泄漏。在上述示例代码中,我们使用delete关键字释放了ptr指向的内存。

腾讯云相关产品和产品介绍链接地址:

  • 云服务器(CVM):提供弹性计算能力,满足各种业务需求。产品介绍链接
  • 云函数(SCF):无需管理服务器,实现按需运行代码的事件驱动型计算服务。产品介绍链接
  • 云数据库 MySQL 版(CDB):提供高性能、可扩展的关系型数据库服务。产品介绍链接
  • 云存储(COS):提供安全、稳定、低成本的云端存储服务。产品介绍链接
  • 人工智能平台(AI Lab):提供丰富的人工智能算法和模型,帮助开发者快速构建人工智能应用。产品介绍链接
  • 物联网开发平台(IoT Explorer):提供全面的物联网解决方案,帮助开发者连接和管理物联网设备。产品介绍链接
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

彻底搞定C语言指针(精华版)

下面我们就开始真正进入指针 的学习了。 二、指针是什么东西 想说弄懂你不容易啊!我们许多初学指针的人都要这样的感慨。常常在思索它,为什么呢?其实生活处处都有指针。我们也处处在使用它。...1 int i 说起 你知道我们申明一个变量时象这样int i ;这个i是可能在它处重新赋值的。...之后的程序在其它任何处都 不会再去重新对它赋值。那我又应该怎么办呢?...//************** 有了const修饰的ic 我们称它为变量,而称符号常量,代表着20这 个数。这就是const 的作用。ic是不能在它处重新赋新值了。...奇怪,明明把a,b分别代入了x,y,并在函数里完成了两个变量值的交换,为什么a,b变量 值还是没有交换(仍然是a==4,b==6,而不是a==6,b==4)?

96130

C++笔试面试题整理

如果使用了这个修饰词,就是通知编译器别犯懒,老老实实去重新读一遍!可能说的太“通俗”了,那么引用一下“大师”的标准解释: volatile的本意是“易变的”。...格式:类型标识符 &函数名(形参列表及类型说明){ //函数体 } 好处:在内存产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。...而虚函数实现的是在基类通过使用关键字virtual来申明一个函数为虚函数,含义就是该函数的功能可能在将来的派生类定义或者在基类的基础之上进行扩展,系统只能在运行阶段才能动态决定该调用哪一个函数,所以实现的是动态的多态性...当一个类A没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,请解释一下编译器为什么没有让它为零。 为1。...成员函数通过什么来区分不同对象的成员数据?为什么它能够区分? 答:通过this指针指向对象的首地址来区分的。 对象都具有的两方面特征是什么?分别是什么含义?

2.6K40
  • 【数据结构】深入浅出理解链表中二级指针的应用

    相信大家在初学链表时一定被下面这些函数的二级指针搞得晕头转向的,疑惑包括但不限于: 什么是二级指针? 为什么链表要用到二级指针? 为什么同样是链表的函数,有的要用二级指针而有的只要用一级指针?...为什么同样是链表,有的链表中使用了二级指针?而有的链表却只需要使用一级指针? 要搞清上面这些问题,我们就要先搞清楚二级指针在链表的作用到底是什么,接下来将带大家一起探究二级指针的"前世今生"....传值调用和传址调用不同的核心原理:函数会对形参和中间变量重新分配空间 2.调用函数更改指针的指向时传值调用和传址调用的区别 那么是否我们要改变形参时都传指针就一劳永逸了呢?...同理,函数更改了头指针的指向后,我们将新的头指针的地址记录下来并返回给主函数,然后在主函数重新使用plist指针接收这个头即可更新头指针的指向: 该思路代码示例如下(仅展示头插部分主函数与头插函数逻辑...plist,这样plist就重新指向新头了 return 0; } 经过测试,这种方法同样可以不使用二级指针就能够完成链表的一系列相关操作,但缺点是只要调用了有可能改变plist的函数,都必须在外面使用

    20010

    指针与引用相关面试题

    相反,指针则应该总是被测试,防止其为空。 可修改区别。指针和引用的一个重要区别是指针可以被重新赋值以指向另一个不同的对象。...但是引用则总是指向在初始化时被指定的对象,以后不能改变,但是指定的其内容可以修改。 应用区别。在以下情况应该使用指针:一是考虑到存在指向任何对象的可能,二是需要能够在不同的·时刻指向不同的对象。...这时它就是一个迷途指针。 使用迷途指针或空指针是非法的,而且有可能会造成程序奔溃。 C++中有了malloc/free,为什么还需要new/delete?...this指针能在成员函数中使用,全局函数,静态函数都不能使用this指针。 this在成员函数的开始前构造,在成员的结束后清除。...this指针只有在成员函数才有定义。

    31850

    Java的引用传递

    觉得引用传递  真的很好理解,不知道为什么大家觉得这么难,你只要掌握这几点就可以了 在Java机制他自己提供的那些数据类型(String ,Object等)要这样理解: 1)在Java  引用  ...说的就是  地址指针,或者叫地址变量, 2)引用传递  一般发生在函数调用的时候,最明显的特征就是  函数参数 3)如果引用传递  实用过程  ,函数没有返回值,这个叫真正的引用传递,没有改变对象的真实值...但是,请你记住一点,如果你改变的副本的值,对不起,你可能在函数内部使用的过程再也无法正确的调用指向的内容值了,请认真对待这个问题。...4)如果引用传递 实用过程函数有返回值,且返回值的类型和参数是一致的,那么在外部 通过调用函数进行重新赋值,就会改变 对象的真实值,一般把它叫做假的引用传递, 看懂了上面的4点,关于引用传递就没有问题了...,也就是通常意义上的  类    要这样理解: 他传递进去的也是引用传递,在函数里面如果调用了set方法或者.方法进行重新赋值,那么自定义的实例化对象的内容值一定发生了变化。

    2.7K30

    Java的传值调用

    从那篇文章后,了解到Java的参数传递其实牵涉到了Java语言的设计的参数传递方式,可能在语言设计之时就考虑了这个问题,所以在工作之余自己简单的研究了一下,最终也能根据自己的理解解释一下关于Java...所以,其实String类型传的是引用,只不过被重新赋值指向了别的对象了,没有修改原对象。即,String本质上还是引用传递,表像上是值传递。...但是要知道String也是传递的引用,只不过它的引用被重新赋值,指向了别的对象了,所以不会影响原值。所以String不能简单的说是值传递。...传引用调用(Call by reference) 在“传引用调用”求值,传递给函数的是它的实际参数的隐式引用而不是实参的拷贝。通常函数能够修改这些参数(比如赋值),而且改变对于调用者是可见的。...因为列表是可变的,append方法改变了m。而赋值局部变量l的行为对外面作用域没有影响(在这类语言中赋值是给变量绑定一个新对象,而不是改变对象)。

    3.5K20

    var let 以及 const区别和用法(详解)

    因为函数的形参在栈中会被解析成函数的私有变量出现在其执行上下文中,let不允许重复定义。...let声明不使用会报错 let声明后不能重新赋值 3.不存在变量提升 只有用var 声明的变量才会有变量提升,let 和const 都不用考虑 4.脱离顶层作用域 我们知道用 var 声明的变量,可以通过...只声明,赋值,会报错(注意:var let 只声明赋值 : undefined) 不能重新赋值const定义的值,但是可以修改const’声明的对象类型。...因为 const 保存的是指向数组或对象的指针。对于基本类型值,使用const声明的变量是不可以被修改的。但是对于对象,指针依然不能被修改,但是指针指向内容可以修改。...const声明的常量和let一样不可重复声明 const和let的最大区别 const声明的对象不能重新赋值,只能赋值里面的属性值 let声明的变量(对象)可以重新赋值

    69200

    C++基础闯关100题,你能闯多少?【2021超硬核大厂高频面试题】

    引用一旦初始化之后就不可以再改变(变量可以被引用为多次,但引用只能作为一个变量引用);指针变量可以重新指向别的变量。 不存在指向空值的引用,必须有具体实体;但是存在指向空值的指针。...浅拷贝: 在拥有指针成员的类,一个对象利用拷贝构造函数或者赋值函数拷贝或者赋值给另一个对象的时候,直接将这个对象的指针成员赋值给另一个对象的指针成员,将一个指针赋值给另一个指针,就会使两个指针指向同一个空间...深拷贝: 在拷贝构造函数赋值函数不是直接的将指针赋给另外一个对象的指针,而是新开辟一块内存空间,将被拷贝或赋值的对象的指针成员指向新开辟的内存空间,然后再将数据拷贝过去。...每次使用它的时候必须从内存取出它的值,因而编译器生成的汇编代码会重新从它的地址处读取数据放在左值。...37、为什么析构函数一般写成虚函数

    2.1K20

    万字长文【C++】高质量编程指南

    2,引用被创建的同时必须被初始化,指针则可以在任何时候被初始化 3,不能有NULL引用,引用必须与合法的存储单元关联,指针则可以是NULL 4, 一旦引用被初始化,就不能改变引用的关系,指针则可以随时改变所指的对象...0) // 错误,缺省值出现在函数的定义体 { ⋯ } 为什么?.../ 赋值函数 private: char *m_data; // 用于保存字符串 }; 为什么会有拷贝和析构函数?...A 的构造函数 { … } 2,类的const常量只能在初始化列表里被初始化,因为它不能在函数体内赋值的方式来初始化 3,非内部数据类型的成员对象应当采用初始化列表方式来初始化,以获取更高的效率。...,那么输出结果为 ~Base 3,在编写派生类的赋值函数时,注意不要忘记对基类的数据成员进行重新赋值 class Base { public: … Base & operate =(const

    1.5K20

    抽丝剥茧C语言(初阶 下)

    那么为什么结果不正确呢?是因为在C语言规定,两个数据相除,如果想得到浮点数(也就是小数,之所以叫浮点数,是因为小数点可以移动,所以叫做浮点数)那么 / 两边必须有一个浮点数才行!...void :声明函数无返回值或无参数,声明无类型指针 volatile:说明变量在程序执行可被隐含地改变 while :循环语句的循环条件 关键字 typedef typedef 顾名思义是类型定义...比如说再写一个代码: void add()//我们不需要add函数返回,所以返回类型就是void { int a = 5;//每一次调用都要重新创建临时变量a,初始化的值是5 a++; printf...至于为什么指针变量,就拿p来说,它可以指向num的地址,也可以指向其他地址。...一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。 一个函数被static修饰,使得这个函数能在本源文件内使用,不能在其他源文件内使用。

    25500

    C++之类和对象

    ,当用户主动传递时编译器会报错;不过在成员函数内部我们是可以显示的去使用 this 指针的: this指针的特性 this指针有如下一些特性: 1.this 指针能在 “成员函数” 的内部使用...可以看到,我们写编译器确实会有一个构造函数来初始化,不过这个初始化出来的数太随机值了,看起来就像乱码一样。这是为什么?...:比如operator@ 2.重载操作符必须有一个类类型参数 3.用于内置类型的运算符,其含义不能改变,例如:内置的整型+,改变其含义 4.作为类成员函数重载时,其形参看起来比操作数数目少1..._capacity; } 深拷贝栈st1需要有一块和st2相同大小的空间,或许有人会疑惑为什么一定要先释放然后重新开辟,而不能使用realloc来改变大小。...所以还不如直接重新建立一块新的空间来使用。 前面在实现日期类函数重载的时候有考虑到一个自我赋值的问题,那么栈是否也需要考虑这个问题呢?下面来看一个示例: 这是为什么

    1.2K00

    由 Go 结构体指针引发的值传递的思考

    这篇笔记的思考开始于一篇帖子中提的问题:下面这段代码,都是从 map 取一个元素并调用其方法,为什么最后一行无法编译通过 import "testing" type S struct { Name...map 的值传递 在 Go ,所有的函数参数和返回值都是通过值传递的,这意味着它们都是原始数据的副本,而不是引用或指针。...由于 map 可能在运行时进行重新哈希以调整大小,重哈希后元素的地址可能发生变化,所以如果支持返回地址,那么可能会在程序运行中出现错误。...(*s).Name,而 *s 是从指责取出对象操作,自然可以赋值。...,也会复制出来一个新的指针对象,但注意复制的是指针对象,即新旧两个指针对象已经完全独立,有各自的内存地址,但是两个指针对象内部指向的目标对象地址没有改变,如下面代码和图示: s := &S{Name:

    22710

    C++:特殊类设计和四种类型转换

    一、特殊类设计 1.1 不能被拷贝的类 拷贝只会放生在两个场景:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。...C++98: 1、将拷贝构造函数赋值运算符重载只声明不定义。...因为常量被存到寄存器中了,所以其实改变的是内存的a,但是不是寄存器的a。...3、为什么 dynamic_cast只能用于父类含有虚函数的类 dynamic_cast转换是在运行时进行转换,因为只有对于这种类层次结构,才应该将派生类的地址赋给基类指针。...C++对象模型,对象实例最前面的就是虚函数指针,通过这个指针可以获取到该类对象的所有虚函数,包括父类的。

    12610

    C++中指针和引用的区别

    指针和引用主要有以下区别: 引用必须被初始化,但是不分配存储空间。指针声明时初始化,在初始化的时候需要分配存储空间。 引用初始化后不能被改变指针可以改变所指的对象。...被调函数对形参的任何操作都被处理成间 接寻址,即通过栈存放的地址访问主调函数的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数的实参变量。...而对于指针 传递的参数,如果改变被调函数指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数的相关变量,那就得使用指向指针指针,或者指针引用。...防止其为空:   void printDouble(const double *pd)   {   if (pd)    {// 检查是否为NULL   cout<< *pd;    }   }     指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象...总的来说,在以下情况下你应该使用 指针: 一是你考虑到存在指向任何对象的可能(在这种情况下,你能够设置指针为空); 二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变 指针的指向)

    5K82

    关于C++ const 的全面总结

    大家好,又见面了,是全栈君 C++的const关键字的使用方法很灵活,而使用const将大大改善程序的健壮性,本人依据各方面查到的资料进行总结例如以下,期望对朋友们有所帮助。...3、函数中使用CONST (1)const修饰函数參数 a.传递过来的參数在函数内不能够改变(无意义,由于Var本身就是形參) void function(const int Var); b.參数指针所指内容为常量不可变...4、类相关CONST (1)const修饰成员变量 const修饰类的成员函数,表示成员常量,不能被改动,同一时候它仅仅能在初始化列表赋值。...class A { … const int nValue; //成员常量不能被改动 … A(int x): nValue(x) { } ; //仅仅能在初始化列表赋值...,this指针仅仅是一个类类型的;假设在const成员函数, this指针是一个const类类型的;假设在volatile成员函数,this指针就是一个 volatile类类型的。

    78030

    一个C#开发者重温C++的心路历程

    前言 这是一篇C#开发重新学习C++的体验文章。 作为一个C#开发为什么重新学习C++呢?...此时,如果想为结构体kiba的字段id赋值,就需要这样写【(*kpointer).id = 518】。 必须把*kpointer扩起来,才能点出它对应的字段id,如果扩起来编译器会报错。...kiunew,kiu,和一个指针*kiupointer,然后把kiu的地址赋值指针。...接着指针和kiunew一起发送给函数usagePointer,在函数里,指针的地址改成了kiunew的地址。 运行结果如下图。 ? 可以看到,指针地址已经改变了。...如果删除掉函数usagePointer的【引用符&】(某些情况下也叫取地址符)。我们将得到如下结果。 ? 我们从图中发现,不仅地址没改变赋值也失败了。

    83630

    详解指针(超详细)(第一卷)

    2.解引用(用于访问指针所指向的内存单元的值) 当我们用指针访问到a的地址后,就可以不用直接操作a进而改变a的值,可以直接在a的地址改变a的值(当然a的地址不变,只是地址存储的值发生了改变),通过这个方法我们可以进行一些...“非法”操作啦 比如我们将a定义成一个具有常属性的变量,就无法直接对a的值进行改变,这时我们就可以用解引用,例如这样 (c++不支持该操作,编译器会报错) 二.指针变量 1.注意上文对指针p的定义是...提到变量我们首先就要考虑这个变量占多少字节 当然这里就用了int char两个类型,我们不难发现在debug状态下x64任意指针变量的字节都是8,x86任意指针类型的字节都为4。...第二种例如 此时用const对p进行修饰,所以*p不受影响,依旧可以被重新赋值。 三.指针运算 上面讲啦许多与指针有关的知识,但好像没有太大的实际价值,接下来讲一下指针的实际应用——指针运算。...我们都知道C语言中有个函数叫做strlen,统计一个字符串中出\0外的字符个数 就像这样,那么接下来我们可以用指针-指针自己设计一个类似于strlen函数函数,来更直观的体验一下指针-指针: 具体代码如下

    8310

    ES6语法学习(let与var区别、块级作用域、const命令)

    变量i是var声明的,所以i是一个全局变量在全局范围内都有效,所以全局只有一个变量i,每一次循环i的值都会发生改变,被赋给数组a的函数内部的console.log(i)的i指向全局的i,因此所有数组a...3.能重复声明 4.可以重新赋值  let声明变量: 1.没有变量提升 2.有块级作用域 3.不能重复声明 4.可以重新赋值 02-块级作用域 2.1-为什么需要块级作用域?...函数能不能在块级作用域中声明?...ES5规定,函数能在顶层作用域和函数作用域之中声明,不能在块级作用域中声明。... variable 3.2-一旦声明,就必须立即初始化,不能保留到以后赋值 例: const a;//只声明赋值就会报错SyntaxError: Missing initializer in const

    1K00

    【Hooks】:不是魔法,仅仅是数组

    1.1. hooks 的 2 个规则 react 核心小组在提案文档指出,有 2 个使用规则是开发者必须去遵守的 不要在循环、条件语句、或嵌套函数调用 hooks hooks 只能在函数组件中使用 第...每个 setState 第一次执行,推送一个 setter 函数(绑定一个指针位置)到 setters 数组,推送一个 state 到 state 数组。 2.3....随后的渲染 随后的每次渲染,就是光标的重置,从各个数组读值 2.4. 事件处理 每个 setter 都有一个指针位置的引用,所以每次调用 setter,都会改变对应的 state 的值。...为什么顺序很重要? 如果我们改变 hooks 的顺序,当外部因素或组件 state 变化导致重新渲染时,会发生什么?...现在应该明白了为什么 hooks 不能在条件分支和循环中。因为我们处理的是数据集合的指针,要是你改变了调用顺序,指针会对应上,从而指向错误的数据或处理器。 4.

    66510
    领券