变量的值传递,地址引用(和对象成员变量、局部变量创建和初始化的内存机制)

简介: 变量的值传递,地址引用(和对象成员变量、局部变量创建和初始化的内存机制)

变量的值传递,地址引用


搞懂=含义,=即指向,看指向的内存块是否发生改变,还有是否是新内存块,

通过指向可以控制内存块的值。

普通变量 =,就是值的赋值(简单这么记住,其实是变量指向存放数字的内存块,但是数字不存在就创建数字的内存块

指针变量 =,就是地址指向,通过指针操作空间内部值

例如 int i = 1;就是i=1;

例如 int b = 1;int * a = &b;

最后记住局部变量的作用域就彻底搞懂了。



一、引用(指向)


boy and girl 先看一个特别特别简单的例子哈:

int a = 1;
int b = 1;
b = 2;

打印a、b结果是1、2.


3.png


我们来讲一讲最基本最重要的一个小小知识点:(首先int a = 1; 首先它会在栈中创建一个变量a的引用,然后查找栈中是否有1这个值,如果没找到,就将1存放进来,然后将a指向1。同理,int b = 1;b = 2;)


ps:规定变量定义需要初始化。是不是经常遇到The local variable 某个变量 may not have been initialized;
例如这样:主函数中 int m;调用某个函数(m);这时候开始报错啦!!!
当然你可能会直接在主函数中写int a; 然后问没有报错,其实是编译器“被调教了”,帮你默认初始化为int a = 0;


(注意,这里的引用二字没有任何问题,理解一下,对于指针的地址引用就一通百通了)

int a = 1; 理解是a 指向 1

int b = 1; 理解是b 指向 1(已经存在)

b = 2;     理解是b  指向 2 (只要记住1和2是两块空间中的不同小内存

 

指针情况举例:


int a = 1;
int * p1 =  &a;  //指针p1指向a
int * p2 =  &a;   //指针p2也指向a
*p2 = 3;     //修改指向a的内部值


打印printf("%d\t%d",*p1,*p2);结果会是3,3。

 

此刻适合讲java中的new对象:

String str1 =new String ("abc");

String str2 =new String ("abc");

System.out.println(str1==str2); // false
每次new,都在堆某个位置new了一个对象,指向,即存放了对象的地址


4.png

(ps:数字的话是在栈内,
a = 1;b = 1;因为栈内1,出现过了没有在创建另外一个1的地址,so 其实a存放1的地址,b存放1
的地址。)


5.png


只要记住p1和p2指向是同一块空间内存a,通过p2修改了a内部情况,p1还指向a,当a内部情况变了,p1打印内部就改变

举个结构体例子更容易明白点:


#include <stdio.h>
#include <string.h>
struct Stu{
    int id;
    char name[20];
};
int main()
{
    Stu student = {1, "小明"};
    Stu *stu1 = &student;
    Stu *stu2 = &student;
    stu1->id = 2;
    strcpy(stu2->name,"小小明");
    printf("%d\t%s\n",student.id,student.name);
    printf("%d\t%s\n",stu1->id,stu1->name);
    printf("%d\t%s",stu2->id,stu2->name); 
   return 0;
}


结果:2  小小明

   2  小小明

          2  小小明


二、值传递,地址引用


利用前面的搞懂引用+理解局部变量作用域就一通百通

局部变量:形参,方法中定义的变量,代码块中定义的变量

局部变量作用域:从出现到遇到 }

代码举例:

值传递+局部变量作用域


void main() {
   int a = 1;
   add(a);   
   printf("%d",a);
 }  
void add(int i){
 i++;
  printf("%d",i);
}


结果:1

           2

过程分析:首先值传递-- add(a);相当于函数add(int i = a),i 指向 a (a = 1),进入函数内部,这时值传递后 i = 1; 然后结合局部变量作用域,遇到方法的 },i 就被销毁了

要想拿到方法处理的结果,利用可以返回值,例如函数改写:

public static int add(int i){
  i++;
  return i;
}
然后主函数修改一下:
int a = 1;
a = add(a);
System.out.println(a);

 

引用传递(也叫地址传递):

#include <stdio.h>void add(int *i);int main(){    int b = 1;    int * a = &b;    //a指向b    add(a);    printf("%d\n",*a);  } void add(int *i) {    //相当于int *i = &b;    (*i)++;       //修改了b     printf("%d\n",*i);}



对象成员变量、局部变量创建和初始化的内存机制:

目录
相关文章
|
2月前
|
存储 监控 算法
Java中的内存管理:理解Garbage Collection机制
本文将深入探讨Java编程语言中的内存管理,着重介绍垃圾回收(Garbage Collection, GC)机制。通过阐述GC的工作原理、常见算法及其在Java中的应用,帮助读者提高程序的性能和稳定性。我们将从基本原理出发,逐步深入到调优实践,为开发者提供一套系统的理解和优化Java应用中内存管理的方法。
|
17天前
|
缓存 监控 算法
Python内存管理:掌握对象的生命周期与垃圾回收机制####
本文深入探讨了Python中的内存管理机制,特别是对象的生命周期和垃圾回收过程。通过理解引用计数、标记-清除及分代收集等核心概念,帮助开发者优化程序性能,避免内存泄漏。 ####
30 3
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
86 4
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
79 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
1月前
|
存储 算法 Java
Go语言的内存管理机制
【10月更文挑战第25天】Go语言的内存管理机制
31 2
|
1月前
|
存储 运维 Java
💻Java零基础:深入了解Java内存机制
【10月更文挑战第18天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
35 1
|
2月前
|
Java 测试技术 Android开发
让星星⭐月亮告诉你,强软弱虚引用类型对象在内存足够和内存不足的情况下,面对System.gc()时,被回收情况如何?
本文介绍了Java中四种引用类型(强引用、软引用、弱引用、虚引用)的特点及行为,并通过示例代码展示了在内存充足和不足情况下这些引用类型的不同表现。文中提供了详细的测试方法和步骤,帮助理解不同引用类型在垃圾回收机制中的作用。测试环境为Eclipse + JDK1.8,需配置JVM运行参数以限制内存使用。
37 2
|
2月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
60 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
2月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
40 2
|
2月前
|
存储 安全 NoSQL
driftingblues9 - 溢出ASLR(内存地址随机化机制)
driftingblues9 - 溢出ASLR(内存地址随机化机制)
43 1