• 【C++学习教程06】指针


    参考资料

    • 范磊C++(第8课)
    • VS2015

    指针

    指针的基本概念

    在这里插入图片描述

    空指针

    在这里插入图片描述

    指针与类型

    在这里插入图片描述

    #include "stdafx.h"
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    
    int main(int argc, const char * argv[]) {
    	double a = 3.14;
    	cout << "double is " << sizeof(a) << "byte" << endl;
    	int b = 6;
    	cout << "int is " << sizeof(b) << "byte" << endl;
    	int *p1 = &b;
    	double *p2 = &a;
    	cout << "double adress is:" << p2 << endl;
    	cout << "int adress is:" << p1 << endl;
    	p1++;
    	p2++;
    	cout << "after move" << endl;
    	cout << "double adress is:" << p2 << endl;
    	cout << "int adress is:" << p1 << endl;
    	system("pause");
    	return 0;
    }
    

    结果:
    在这里插入图片描述

    用指针来访问

    在这里插入图片描述在这里插入图片描述

    #include "stdafx.h"
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    
    int main(int argc, const char * argv[]) {
    	double a = 3.14;
    	cout << "double is " << sizeof(a) << "byte" << endl;
    	int b = 6;
    	cout << "int is " << sizeof(b) << "byte" << endl;
    	int *p1 = &b;
    	double *p2 = &a;
    	cout << "double adress is:" << p2 << endl;
    	cout << "int adress is:" << p1 << endl;
    	cout << "double num is:" << *p2 << endl;
    	cout << "int num is:" << *p1 << endl;
    	p1++;
    	p2++;
    	cout << "after move" << endl;
    	cout << "double adress is:" << p2 << endl;
    	cout << "num is:" << *p2 << endl;
    	cout << "int adress is:" << p1 << endl;
    	cout << "num is:" << *p1 << endl;
    	system("pause");
    	return 0;
    }
    

    运行结果:
    在这里插入图片描述

    容易混淆的概念

    在这里插入图片描述

    #include <iostream>
    using namespace std;
    int main(int argc, const char * argv[]) {
        // insert code here...
        int i=1;
        int *p=NULL;
        cout<<"i的值:"<<i<<endl;
        cout<<"i的地址:"<<&i<<endl;
        cout<<"p的值:(P所保存的地址)"<<p<<endl;
        //cout<<"p所指向地址的值"<<*p<<endl;//访问零脂针会发生报错“程序崩溃“
        cout<<"p的地址:"<<&p<<endl;
        p=&i;
        cout<<"赋值后"<<endl;
        cout<<"p的值:(P所保存的地址)"<<p<<endl;
        cout<<"p所指向地址的值"<<*p<<endl;
        cout<<"p的地址:"<<&p<<endl;
        return 0;
    }
    

    运行后结果:
    在这里插入图片描述

    指针对数值的操作

    #include <iostream>
    using namespace std;
    int main(int argc, const char * argv[]) {
        // insert code here...
        typedef unsigned short int ut;
        cout<<sizeof(ut)<<endl;//2个字节
        ut i=5;
        ut *p=NULL;
        p=&i;
        cout<<"i="<<i<<endl;
        cout<<"*p="<<*p<<endl;
        cout<<"用脂针来修改存放在i中的数据"<<endl;
        *p=90;
        cout<<"i="<<i<<endl;
        cout<<"*p="<<*p<<endl;
        cout<<"用i来修改存放在i中的数据"<<endl;
        i=9;
        cout<<"i="<<i<<endl;
        cout<<"*p="<<*p<<endl;
        return 0;
    }
    

    输出结果:
    在这里插入图片描述

    为什么使用指针

    在这里插入图片描述

    栈和堆

    在这里插入图片描述

    • 栈的数据寿命短但全局区是在程序结束后才能完全释放;
    • 堆可以由程序员决定,自由度高,优于栈和全局区;
    • 堆是通过匿名的方式来保存数据的,只能通过指针才能访问到这些匿名的数据。他的安全性是最好的。

    以下为详细解释:
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    ⬆️合理利用内存空间

    在这里插入图片描述

    ⬆️ 空间使用灵活

    在这里插入图片描述

    在这里插入图片描述

    用图来解释栈的工作原理:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    对于堆来说:

    在这里插入图片描述

    总结:
    在这里插入图片描述

    指针与堆

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    #include <iostream>
    using namespace std;
    int main(int argc, const char * argv[]) {
        // insert code here...
        int *p1;
        p1=new int;//new建立堆变量
        cout<<p1<<endl;
        double *p2=new double;
        cout<<p2<<endl;
        return 0;
    }
    

    输出:
    在这里插入图片描述

    用指针删除堆中的空间

    内存泄露
    在这里插入图片描述

    #include <iostream>
    using namespace std;
    int main(int argc, const char * argv[]) {
        // insert code here...
        int *p=new int;//new建立堆变量
        *p=36000;
        cout<<*p<<endl;
        delete p;//释放内存而不删除指针
        cout<<*p<<endl;
        p=NULL;
        p=new int;
        *p=8;
        cout<<*p<<endl;
        delete p;
        cout<<*p<<endl;
        //delete p;//反复delete会导致程序崩溃
        return 0;
    }
    

    运行结果:

    在这里插入图片描述

    在这里内存并没有被释放掉,值得深思。

    • VS2015
    #include "stdafx.h"
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    int main(int argc, const char * argv[]) {
    	int *p = new int;
    	*p = 23;
    	delete p;
    	cout << *p << endl;
    	system("pause");
    	return 0;
    }
    

    输出结果:
    在这里插入图片描述
    参考链接: 某论坛.

    内存泄漏

    在这里插入图片描述

    在堆中创建对象与删除对象&访问堆中的成员数据

    #include <iostream>
    using namespace std;
    class Human
    {
    public:
        Human(){cout<<"构造函数执行"<<endl; i=9999;}
        ~Human(){cout<<"析构函数执行"<<endl;}
        int get()const{return i;}
    private:
        int i;
    };
    int main(int argc, const char * argv[]) {
        Human Jack; //调用存放在栈中对象的方法
        cout<<Jack.get()<<endl;
        cout<<"************"<<endl;
        //以下存放在为堆中的对象
        Human *p=new Human;//此时已经创建了一个human类的对象!!他是一个匿名的!!!只能用指针找到他。
        cout<<p->get()<<endl;
        delete p;//删除这个对象也可以用p
        return 0;
    }//栈中的对象会在遇到}自动析构掉
    

    this指针

    在这里插入图片描述

    //
    #include <iostream>
    using namespace std;
    class A
    {
    public:
        int get()const{return i;}
        void set(int x){i=x; cout<<"this变量保存的内存:	"<<this<<endl;}
    private:
        int i;
    };
    int main(int argc, const char * argv[]) {
        A a;
        a.set(9);
        cout<<"对象a的内存地址:	"<<&a<<endl;
        cout<<a.get()<<endl;
        
        A b;
        b.set(9);
        cout<<"对象b的内存地址:	"<<&b<<endl;
        cout<<b.get()<<endl;
        
        return 0;
    }
    

    输出结果:在这里插入图片描述

    在这里插入图片描述

    指针的常见错误

    在这里插入图片描述

    #include <iostream>
    using namespace std;
    int main(int argc, const char * argv[]) {
        int *p=new int;
        *p=3;
        cout<<"将3付给p的地址后,读取指针p的值:	"<<*p<<endl;
        delete p;
        //p=NULL;//用程序崩溃的代价来保证不会引起使用野指针
        cout<<"删除空间后,读取指针p的值:	"<<*p<<endl;
        long *p1=new long;//p1指向了p所释放的空间
        cout<<"创建新空间后,指针p保存的地址:	"<<p<<endl;
        *p1=9999;
        cout<<"指向新空间的指针P1保存的地址:	"<<p<<endl;
        *p=23;//其实是将23赋给P1指向的内存空间
        cout<<"将23付给p的地址后,读取指针p的值:	"<<*p<<endl;
        cout<<"将23付给p的地址后,读取指针p1的值:	"<<*p1<<endl;
        return 0;
    }
    

    输出结果:

    在这里插入图片描述

    常量指针和指向常量的指针

    常量指针

    在这里插入图片描述
    在这里插入图片描述

    指向常量的指针

    在这里插入图片描述
    在这里插入图片描述

    指向常量的常指针

    及上面两个的结合,指针和指向的目标都不能改变。

    总结

    在这里插入图片描述

  • 相关阅读:
    yii AR 模式操作
    sql 注入命令大全
    PHP 防xss攻击
    yii rbac管理
    yii2.0 表单小部件常用的默认选中
    yii 表单小部件使用
    多个API接口
    iwebshop 增删改查
    搜索引擎接口
    2003终端服务器授权,120天试用期限制
  • 原文地址:https://www.cnblogs.com/vrijheid/p/14222988.html
Copyright © 2020-2023  润新知