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

变量的值传递,地址引用

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

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

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

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

例如 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.

 

 

我们来讲一讲最基本最重要的一个小小知识点:(首先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 = 1int * 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了一个对象,指向,即存放了对象的地址

 


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

 

只要记住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(String[] args) {
               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);
}

 

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

 

参考:https://www.cnblogs.com/protected/p/6419217.html

 

下次有空再整理一点自己的笔记

 

 

 

                          

 

 

 

 
 
 

版权声明:本文为shan333原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/shan333/p/14367121.html