精华内容
下载资源
问答
  • 循环改变指针的值怎么改变
    2021-02-18 14:33:07

    转载自:https://blog.csdn.net/qq_22525091/article/details/80116128

    code

    #include<stdio.h>
    #include<stdlib.h>
    void  GetMemory(char *p, int num)
    {
        p = (char *)malloc(sizeof(char)  * num);
    }
    
    void  Test(void)
    {
        char *str = NULL;
    
        GetMemory(str, 100);    // str 仍然为 NULL 
        printf("address str:%p \n", str);
        // strcpy(str,  "hello");   // 运行错误
    }
    
    void getsum(int sum, int n)
    {
        for (int i = 0; i < n; i++)
        {
            sum += i;
        }
    }
    
    void Test2()
    {
        int sum = 0;
        getsum(sum, 10);
        printf("sum value:%d \n", sum);
    }
    
    int main(int argc, char** argv){
        Test();
        Test2();
        return 0;
    }
    

    解释:

    • Test是声明了一个指针,然后到子函数中用malloc进行内存申请,但是后面打印的时候发现,返回的结果为null。这里又写了Test2,将一个int变量作为形参传入,Test只是将一个指针变量作为形参传入,
    • 这里TestTest2差不多的。传入的变量在子函数都会新建一个副本,副本改变了,原来的不会改变。如果要改变原来的值,需要使用指针。
    更多相关内容
  • C++多重继承下的指针类型转换 在C++中,指针的类型转换是经常发生的事情,...基于上面的理解,我们似乎可以得出一个结论,C++中对指针进行类型转换,不会改变指针,只会改变指针的类型(即改变编译器对该指针指

    C++多重继承下的指针类型转换

    在C++中,指针的类型转换是经常发生的事情,比如将派生类指针转换为基类指针,将基类指针转换为派生类指针指针的本质其实就是一个整数,用以记录进程虚拟内存空间中的地址编号,而指针的类型决定了编译器对其指向的内存空间的解释方式。

    基于上面的理解,我们似乎可以得出一个结论,C++中对指针进行类型转换,不会改变指针的值,只会改变指针的类型(即改变编译器对该指针指向内存的解释方式)但是这个结论在C++多重继承下是 不成立的

    看下面一段代码:

    #include<iostream>
    using namespace std; 

    class CBaseA 

    public: 
    char m_A[32]; 
    }; 

    class CBaseB 

    public: 
    char m_B[64]; 
    }; 

    class CDerive : public CBaseA, public CBaseB 

    public: 
    char m_D[128]; 
    }; 


    int main() 

    auto pD = new CDerive; 
    auto pA = (CBaseA *)pD; 
    auto pB = (CBaseB *)pD; 

    cout << pA << '\n' << pB << '\n' << pD << endl; 
    cout << (pD == pB) << endl; 
    }

    这段代码的输出是:

    0x9f1080
    0x9f10a0
    0x9f1080
    1

    可以看出,指向同一个堆上new出来的内存指针,在经过类型转换之后,其值会发生改变。究其原因,要从C++中多重继承的内存布局说起。

    new CDerive;执行之后,生成的内存布局如下:

     

    同时我们注意到,pB与pD的指针差值正好是CBaseA占用的内存大小32字节,而pA与pD都指向了同一段地址。这是因为,将一个派生类的指针转换成某一个基类指针,编译器会将指针的值偏移到该基类在对象内存中的起始位置。

    可是为什么C++要这样设计呢?

    试想,沿用上面的场景,如果pB和pA都指向对象的首地址,那么使用pB指针来定位CBaseB的成员变量m_B时,编译器应该将pB指针偏移32个字节,从而跳过CBaseA的内存部分。而pB指针如果是这样产生的auto pB = new CBaseB;,那么使用pB指针来定位CBaseB的成员变量m_B时,偏移量应该为0。

    关键在于对于一个指针而言,编译器不关心也无法知道该指针的来源(一种极端情况,指针是从其他模块传递过来的),而只是把它视为一个有指针类型的整数。所以对于CBaseB类型的指针,取CBaseB的成员变量m_B时,偏移量应该通通为0,这是通过CBaseB的类声明就可以统一决策的事情。

    说到这里,pD和pB的指针地址为什么不一样大家应该清楚了,可是为什么下面的代码输出是1呢?

    cout << (pD == pB) << endl;

    输出1表示pD和pB是相等的,而刚刚我们才说明了,pD和pB的地址是相差了32个字节的。

    其实这也是编译器为大家屏蔽了这种指针的差异,当编译器发现一个指向派生类的指针和指向其某个基类的指针进行==运算时,会自动将指针做隐式类型提升以屏蔽多重继承带来的指针差异。因为两个指针做比较,目的通常是判断两个指针是否指向了同一个内存对象实例,在上面的场景中,pD和pB虽然指针值不等,但是他们确确实实都指向了同一个内存对象(即new CDerive;产生的内存对象 ),所以编译器又在此处插了一脚,实际比较的是pD和(CDerive *)pB,让我们可以安享==运算的上层语义。

    展开全文
  • 先看空指针异常:ListmovieInfos= null;这样创建时,list指向为空,修改方法:ListmovieInfos= new ArrayList();再看list循环赋值的问题:问题描述:for (i=0;i<10;i++){movieInfoSum.movieId = (int)...

    先看空指针异常:

    ListmovieInfos= null;

    这样创建时,list指向为空,修改方法:

    ListmovieInfos= new ArrayList();

    再看list循环赋值的问题:

    问题描述:

    for (i=0;i<10;i++){

    movieInfoSum.movieId = (int)recommendation.get(i).getItemID();

    movieInfoSum.movieName = movieInfos.get(i).getMovieName();

    movieInfoSum.movieType = movieInfos.get(i).getMovieType();

    movieInfoSum.value = recommendation.get(i).getValue();

    movieInfoSums.add(movieInfoSum);

    }

    这段代码在每一次循环时,都会将新的数值赋值到已保存的list中,比如,

    第一个循环结束后:

    aa237209fbcc5d0b445851e601a876f2.png

    数据正常加入,进行第二个循环过程中:

    10ff9a405c81f3125e9389ff71f81ab9.png

    List movieInfoSums中已存入的下标0的值改变了,经过蒙逼半天后查找资料(https://blog.csdn.net/single_cong/article/details/80560616),发现是因为值类型和引用类型没区分好的问题

    修改方法:

    for (i=0;i<10;i++){

    MovieInfoSum movieInfoSum = new MovieInfoSum();//将对象创建语句放在循环内

    movieInfoSum.movieId = (int)recommendation.get(i).getItemID();

    movieInfoSum.movieName = movieInfos.get(i).getMovieName();

    movieInfoSum.movieType = movieInfos.get(i).getMovieType();

    movieInfoSum.value = recommendation.get(i).getValue();

    movieInfoSums.add(movieInfoSum);

    }

    总结:1,List创建时不置空,2,将对象传入List时要new新的对象。

    展开全文
  • a的为10,接着调用Fun函数,Fun函数的意图是将指针p指向空,如果调用成功,那么最后程序就会崩溃,无法打印指针p所指向内容的,但运行后却发现,指针p所指向内容的依旧为10,即Fun函数根本没有改变指针p的指向...

    为什么一个指针变量作为形参传递给一个函数后,在函数体内改变这个指针的指向,但函数结束后这个指针的指向没有发生变化?


    现在有如下一段代码,其中指针p指向a,a的值为10,接着调用Fun函数,Fun函数的意图是将指针p指向空,如果调用成功,那么最后程序就会崩溃,无法打印指针p所指向内容的值,但运行后却发现, 指针p所指向内容的值依旧为10,即Fun函数根本没有改变指针p的指向。

    #include<stdio.h>
    
    void Fun(int* p)
    {
    	p = nullptr;
    }
    
    int main()
    {
    	int a = 10;
    	int* p = &a;
    	Fun(p);
    	printf_s("%d\n", *p);
    	return 0;
    }

    执行结果:

    为此我进行了调试,调试结果如下:

    执行Fun函数前

    执行Fun函数ing

     执行Fun函数后

    我们发现在执行Fun函数的过程中,p的指向确实变为了nullptr,但在Fun函数执行后,p却又指向了a。

    这是因为,主函数调用其他函数传入参数的时候,被传入的每个参数都会被复制一遍,复制后的这个参数我们可以理解为临时变量, 而当我们在函数内部对参数进行相应的操作或者修改时,实际上都是对这个临时变量进行的。所以当我们将指针p传入Fun函数时,会得到一个指针p的复制版即临时变量p_,而我们将指针p指向nullptr的这一过程,实际上是将p_指向了nullptr,本质上的指针p的指向并没有被改变,而Fun函数也没有返回值,跳出Fun函数后临时变量p_也就被销毁了,所以p的指针根本没有被改变。


    那么我们该如何实现在函数从本质上改变指针的指向呢,答案是使用引用或者二级指针。

    #include<stdio.h>
    
    void Fun_1(int*& p)/*使用引用*/
    {
    	p = nullptr;
    }
    
    int main()
    {
    	int a = 10;
    	int* p = &a;
    	Fun_1(p);
    	printf_s("%d\n", *p);
    	return 0;
    }

    运行结果: 

    使用了引用后我们发现指针p的指向确实被修改了,指向了空,这是因为如果你使用的是&引用,那么函数调用时传入的参数的方法是传值,这就意味着我们可以直接对传入的参数进行操作和修改,而不是对那个临时变量进行操作了,实际上此时也不会有临时变量产生。


    #include<stdio.h>
    
    void Fun_2(int** p)/*使用二级指针*/
    {
    	*p = nullptr;
    }
    
    int main()
    {
    	int a = 10;
    	int* p = &a;
    	Fun_2(&p);
    	printf_s("%d\n", *p);
    	return 0;
    }

     运行结果:

    为了搞清楚在二级指针中这一过程是如何进行的,我们再次进行调试

    执行Fun_2函数前

     执行Fun_2函数ing

     

    执行Fun_2函数前后

     

    也许看到这里大家有点糊涂了,为什么通过一个二级指针可以改变一个一级指针的指向呢?具体原因如下:

    首先当我们将指针p的地址入参时, 会产生一个二级指针类型的临时变量p_,接着这个二级指针会指向被传入的一级指针p,而此时一级指针p依然还是指向a,三者之间的关系示意图如下。

    接着系统执行*p=nullptr,此时二级指针p_的指向依然还是指向一级指针p,但是一级指针p的指向已经变为了nullptr,最终Fun_2函数结束时,临时变量即二级指针p_被销毁,但我们已经通过它改变了一级指针p的指向。这样,我们就通过一个二级指针改变了一个一级指针的指向。三者之间的关系示意图如下。

    Fun_2函数结束 

    这里还有一句话,如果想要在函数中改变指针的指向,那么就要对指针进行“降维打击 ”,即使用二级指针或者指针的引用;如果想要在函数中改变指针所指向内容的值,那么就要对指针进行解引用。

    展开全文
  • C 语言指针

    千次阅读 2021-05-21 09:07:00
    C 语言指针在本教程中,您将学习指针。什么是指针,如何使用它们以及在示例的帮助下使用它们时可能遇到的常见错误。指针是 C和C ++ 编程的强大功能。...在此,用户输入的存储在var变量的地址中。...
  • 在python中,for循环相当于一个迭代器(Iterator),在循环体中改变循环变量的循环次数是没有影响的。 迭代器在一个独立的线程中工作,并且拥有一个mutex锁。迭代器被创建的时候,建立了一个内存索引表(单链表...
  • 一、修改基本类型变量(short、int、long、char、...该函数的本意是通过函数交换两个数的,可是在调用后函数的并未发生改变,这是因为该函数参数的传递方式为传递: 传递(passl-by-value)过程中,被调函数的
  • 循环语句中指针赋值出错

    千次阅读 2022-03-31 09:58:32
    最近在写人工智能作业的时候遇到了一点问题,就是在循环语句中对指针类型赋值出现错误,导致所有的结点的前驱指针最终指向自身。 问题描述 以下使用一个简单的示例来模拟当时出现的问题。 MyStruct 为一个自定义...
  • 在页面中添加三个按钮,当点击按钮时,按钮的值循环发生改变。 例如三个按钮的默认值都为A,当任意点击一个按钮时,其默认值变成B,再次点击变成C,再点一次又变为A. 2.源代码:  pageEncoding="utf-8"%>...
  • 循环链表合并(只带尾指针) 对循环链表,有时不给出头指针,而给出尾指针可以更方便的找到第一个和最后一个结点。 如何查找开始结点和终端结点? 开始结点:rear->next->next 终端结点:rear 循环...
  • char *t="www",我想让s内容变成"hellowww" 可以通过直接使用指针指向来做么,不要string.h函数 不要循环赋值。就是想通过修改指针指向来做 ``` 这个可以实现么 不要函数不要循环复制 为什么不能让s+5=t,就是让它...
  • python的list是一组可变变量的指针,有长度和容量区别,会自动调整容量,类似于golang的机制 a=[0,1,2] ​ b=[-1]*6 i=0 ​ #姑且称为前者,后者 #foreach 前者可以在循环过程中变化 for b[i] in a: i+=2 ....
  • C语言通过指针修改变量的

    万次阅读 2016-08-06 14:01:30
    C语言学习笔记之通过指针修改变量的 1.C语言的基本结构介绍 2.C语言的数据类型 3.通过指针改变变量的 总结:
  • package main import "fmt" func main() { type User struct { ... // 通过range获取数组的 -> 不能修改数组中结构体的: for _, user := range userArr { user.Name = "WangWu" } for _, userNa.
  • 单、双链表的循环链表(十五)

    千次阅读 2022-04-21 18:59:09
    1. 单链表的循环链表 <1>.单链表的循环链表特点 单链表只能向后操作,不能向前操作,如果从当前结点开始,无法访问该结点前面的结点。...单链表循环链表最后一个结点的next指针域不为空,而是指...
  • 这种方式遍历数组,会将遍历的数组的每一个元素进行复制,通过使用复制的,进行for循环的内容,在for循环中进行更改,不会影响原数组的 举例说明: func (student Student) rename() { student.n
  • 队列文档之循环队列

    千次阅读 2022-05-09 22:28:50
    循环队列就是将顺序队列臆造成一个环状的空间(实际上不是,只是把它看成是环状的),即把存储队列元素的顺序表从逻辑上视为一个环。
  • 循环链表尾指针

    千次阅读 2016-10-28 11:10:39
    循环链表-尾指针
  • C语言For循环详解

    千次阅读 2021-05-21 06:43:33
    c语言中的for循环语句...表达式 3)语句它的执行过程如下:(1)先求表达式 1.(2)求表达式2,若其为真(为非0),则执行for语句中指定的内嵌语句,然后执行下面第三步 做若为假(为0),则结束循环,转到第5步.(3)求解表达...
  • JAVA8stream嵌套循环并设置

    千次阅读 2020-03-19 11:49:27
    JAVA8stream嵌套循环并设置 简介: Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。 Stream 不存储数据、不改变源数据 详情请阅读stream官网 一.测试代码 public static void ...
  • 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,...
  • 指针类型转换后, 指针值改变

    千次阅读 2006-11-07 12:04:00
    #include cstdlib>#include iostream>using namespace std;struct IBase...{ int a; };struct IA: public IBase...{ int aaa;};struct IB: public IBase...{ int bbb;};struct CChild: pu
  • c++ 指针详解

    千次阅读 多人点赞 2022-03-28 14:37:51
    使用指针遍历数组 ;指针的概念与理解; 指针的含义;指针的创建与初始化 ;指针的基本操作;指针的解引用和取地址;指针的算数操作 ;指针相减 ;const指针;指向const的指针指针的数组和数组的指针;数组的指针...
  • 关于二级指针的作用

    千次阅读 2022-04-27 00:59:05
    一级指针:传递变量的地址进函数,使其改变函数外变量 函数传递是的传递,不会改变函数外变量,只有传递变量地址才能改变函数外变量 二级指针:传递一级指针的地址进函数,从而改变函数外一级指针的地址 .....
  • C语言通过指针参数返回值

    千次阅读 2020-12-15 20:28:25
    C语言巧用函数的指针参数,使得函数"返回"多个简单的案例深夜无聊而引发的问题回归正题简单的案例2.0链表中"迷人"的指针再度分析 简单的案例 深夜无聊而引发的问题 一般来说,在C语言中一个函数顶多只能返回一个...
  • 循环双链表实现下述功能: void meau(); //菜单函数 void Initlist(List *list); //初始化 void show(List *list); //打印链表内容 bool Push_back(List *list,ElemType x); //尾插法 b
  • C/C++ 指针详解

    千次阅读 多人点赞 2021-09-24 15:30:32
    指针详解 参考视频:https://www.bilibili.com/video/BV1bo4y1Z7xf/,感谢Bilibili@fengmuzi2003的搬运翻译及后续勘误,也感谢已故原作者Harsha Suryanarayana的讲解,RIP。 笔者亲测实验编译器版本: gcc版本 gcc ...
  • 如何用scanf语句为字符指针数组赋值

    千次阅读 2021-12-25 22:34:11
    指针地址是由系统自动分配的,想要自己指定指针地址有两种方法: 一、初始化赋值 例如: char* p[] = { "Blue","Yellow","Orange","Green","Red","black" };...每次循环后都会改变字符数组存储的字符串;
  • 目录 一.变量的内存实质到 1.1变量的实质 ...3.2.1.改变一级指针指向 3.2.2改变 N-1 级指针的指向 3.2.3二级指针的步长 四. 指针与数组 4.1 指针与数组名 4.1.1 通过数组名访问数组元素 4....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 204,047
精华内容 81,618
热门标签
关键字:

循环改变指针的值怎么改变