C++栈区和引用

Posted boyboy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++栈区和引用相关的知识,希望对你有一定的参考价值。

栈区

  • 栈的数据由编译器管理开辟和释放;

  • 注意不要返回局部变量的地址

  • 系统会保存一次,但只可以打印一次数据,

堆区

  • 由程序员释放,在程序运行结束后会出现一个堆区。不释放系统自动回收

  • 用new可开辟堆区,指针在栈区可用指针接受堆区的数据。因为指针在栈区指向和堆区一样的地址。可获取堆区的数据

  • int*fun()

    int*p=new int (10);
    return p;

    void text01()

    int*p=fun();
    cout<<*p<<endl;
    delete p;//由程序员释放了.

    int main()

    int*p=fun();
    cout<<*p<<endl;
  • 在堆区开辟数组

  • void text02()
    int *arr=new int [10];//数组有十个元素
    for(int i=0;i<10;i++)

    cout<<arr[i];

    delete [] arr;
    int main()

    text02();

    引用

    • 引用给变量起别名。

    • 语法:数据类型&别名=原名;

    • int &b=a;
      b=20;//修改别名,原名的值也会变
      cout<<a<<endl;//输出的a的值为20
    • 引用必须要初始化

    • int&b;//该操作时错误的

    • 引用一旦初始化后,就不可以更改。也就是只能赋值给b,b不能引用别的数值了。

    • 在main函数中引用本身需要一个合法的内存空间,因此

      int &ret=10;

      const int&ret=10;//加入const后不可以修改变量

    • 引用可以优化指针,不用像指针一样复制一份内存。引用直接给实参起别名。

    • //指针
      void test01(int *a,int *b)
      int main()

      test01(&a,&b);
      ;
      //引用
      void test01(int &a,int &b)
      int main()

      test01(&a,&b);
      ;
    • //返回局部变量引用
      int &test01()

      int a=10;//局部变量
      return a;

      //返回静态变量引用
      int &test02()

      static int a=20;
      return a;

      int main()

      int &ref1=test01();//不能返回局部变量的引用,第一次还会保存。
      int &ref2=test02();
      test02()=1000;//函数可以作为左值。
      cout<<ref2<<endl;//输出的值为1000;
    • 只有函数静态变量的引用返回值可以作为左值。

       

       

      • 引用的本质就是指针常量,上边的引用可以看成指针常量。系统自动转换int *const ref=&a;指向不可以变,值可以变。

      • 引用在修改方法中的形参时,实参也会改变。故用常量引用const来防止实参被修改

      • void showvalue(const int&a)
      •  

Java02

数组动态初始化

格式 arrayName=new type[length];
实例:int arr[]=new int[3]
     arr[0]=1; arr[2]=6;   结果:1 0 6

数组内存分析

主要分为栈区和堆区 栈区主要存放引用地址 堆区主要存放大块的实际数据,比如对象,数组;
我们可以把栈区理解成电视遥控器,堆区就是电视机,我们的遥控器操作电视机总比直接操作电视机方便,所以这就是栈区的意义;栈区里的引用地址指向堆区的具体数据。

二维数组静态初始化

格式 arrayName=new type[][]{{element1,element2},{element1,element2},{element1,element2}};
实例: int[][]arr=new int[][]{{1,2,3},{4,5,6},{7,8,9}};  //一个中括号一行
二维数组动态初始化 格式: arrayName=new type[length][length];
实例: int[][]arr2=new int[3][3]; arr2[1][2]=3;

public class HelloWorld {
public static void main(String[] args) {
int arr[][]=new int[][]{{1,2,3},{4,5,6},{7,8,9}}; 
for(int i=0;i<arr.length;i++){
    for(int j=0;j<arr[i].length;j++){
        System.out.print(arr[i][j]+" ");
    }
    System.out.println();
}
 }
}
结果:
1 2 3 
4 5 6 
7 8 9 

数组排列实例——起泡法

对4,21,0,-12,-3排序升序

public class HelloWorld {
public static void main(String[] args) {
int arr[]={4,21,0,-12,-3};
int temp;
//循环次数n-1次
for(int i=0;i<arr.length;i++){
//比较次数n-1-i
    for(int j=0;j<arr.length-1-i;j++){
        //假如前面的一个数大于后面一个数,则交换数据
        if(arr[j]>arr[j+1]){
            temp=arr[j];
            arr[j]=arr[j+1];
            arr[j+1]=temp;
        
        }
    }
}
for(int a:arr){
    System.out.print(a+" ");
}
}
}

Java 面向对象

三大特性:封装;继承;多态
类中可以放属性和方法
简单的对象和调用方法
public class Person {

String name;//在类中定义一个姓名name字符串属性,可以存放字符串zhangsan
int age; //在类中,定义一个年龄age属性
public void speak(){
System.out.println("我叫"+name+" 我今年"+age);
}
public static void main(String[] args) {
//定义一个Person类的对象zhangsan
Person zhangsan;
//实例化对象
zhangsan=new Person(); //Person zhangsan=new Person();
zhangsan.name="张三";//给对象的name属性赋值
zhangsan.age=11;//给对象的age赋值
zhangsan.speak();//调用对象的方法
}
}
运行结果:我叫张三 我今年11

方法

参数之间用 ,隔开,普通方法必须先new一个对象,有了对象才能调用方法
public class Person {
String name;
int age;
public void speak(String name,int age){
System.out.println("我叫"+name+" 我今年"+age);
}
public static void main(String[] args) {
Person zhangsan=new Person();
zhangsan.speak("张三",23);//调用对象的方法
}
}
不固定参数
public class Person {
String name;
int age;
public void speak(String name,int age,String...hobbies){
System.out.println("我叫"+name+" 我今年"+age);
for(String hobby:hobbies){
System.out.print(hobby+" ");
}
}
public static void main(String[] args) {
Person zhangsan=new Person();
zhangsan.speak("张三",23,"游泳","唱歌");//调用对象的方法
}
}
运行结果:
我叫张三 我今年23
游泳 唱歌

直传递
public class Person {
void speak(int age){
System.out.println("我今年"+age);
age=24; //方法里是24
}
public static void main(String[] args) {
Person zhangsan=new Person();
int age=11;
zhangsan.speak(age);
}
}
运行结果:
我今年11
引用传递
class SanWei{
int b;
int w;
int h;
}
public class Person {

void speak(int age,SanWei sanWei ){
System.out.println("我今年"+age);
System.out.println("我的三围是:"+sanWei.b+","+sanWei.w+","+sanWei.h);
age=24;
System.out.println("方法里age"+age);
sanWei.b=80;//胸围缩水
}
public static void main(String[] args) {

Person zhangsan=new Person();
int age=11;
SanWei sanWei=new SanWei();
sanWei.b=90;
sanWei.w=60;
sanWei.h=90;
 zhangsan.speak(age,sanWei);
 System.out.println(age);
 System.out.println("调用地方,胸围"+sanWei.b);//和直传递有区别,传的是地址

}
}
运行结果:
我今年11
我的三围是:90,60,90
方法里age24
11
调用地方,胸围80

方法的重载,方法名字一样,但参数个数不一样
long add(int a,int b){return a+b;}和int add(int a,int b){return a+b;}不算重载,也会错误。参数类型个数一样,返回值类型不一样 不算重载,直接会报错,说方法重名。

静态方法 是加了static修饰词的方法,我们使用的时候 一般用类名.方法 方式调用;
当然也可以用对象.方法 调用; 一般java里的工具类里的工具方法 用static修饰,作为静态方法;
public class Demo02 {
void fun1(){
System.out.println("这是一个普通方法");
}
static void fun2(){
System.out.println("这是一个静态方法");
}
public static void main(String[] args) {
Demo02 demo=new Demo02();
// 调用普通方法 对象.方法
demo.fun1();
// 调用静态方法 类名.方法
Demo02.fun2();
demo.fun2();
}
}

递归的话 我们首先要找到规律 还有必须有一个出口;

Java面向对象-构造方法,this关键字

构造方法是一个特殊的方法,这个特殊方法用于创建实例时执行初始化操作;
People(){} 构造方法
特点 1,没有返回值类型,区别于其他一般方法;
2,方法名和类名一样;




































































































以上是关于C++栈区和引用的主要内容,如果未能解决你的问题,请参考以下文章

Java02

堆和栈区

C与C++申请动态内存空间的异同

数据结构中的堆和栈 与 内存分配中的堆区和栈区 分析

在C++中,你真的会用new吗?

virtualbox怎么保存java