为了账号安全,请及时绑定邮箱和手机立即绑定

趣味 C++ 进阶

难度初级
时长 8小时 0分
学习人数
综合评分9.60
10人评价 查看评价
10.0 内容实用
8.8 简洁易懂
10.0 逻辑清晰
  • .与->的不同用法

    查看全部
  • arr里面放的是数组内第一个元素的地址,等同于&arr【0】


    查看全部
  • #include <stdio.h>

    int main()
    {
       int i = 0x1122;
       char * p = (char *)&i;
       if (p[0] == 0x22 && p[1] == 0x11) {
           printf("Little Endian\n");
       }
       else if (p[0] == 0x11 && p[1] == 0x22) {
           printf("Big Endian\n");
       }
    }

    判断电脑是哪种字节序

    查看全部
    0 采集 收起 来源:强者争霸

    2021-07-30

  • 字节序,就是 大于一个字节类型的数据在内存中的存放顺序。

    计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。

    我们现在有一个整数是258。用16进制表示是0x0102,然后我们把这个整数拆分成两个字节,第一个字节为 0000 0001,第二个字节为 0000 0010。

    如果在一个使用大端字节序的电脑上,这个整数会被这样存放:


    如果一个使用小端字节序的电脑上,这个整数的高字节就会存放在高地址上:


    现在大部分的机器,都采用了小端字节序。但是在 IO 方面,则大部分使用大端字节序。例如,你要使用网络发送一个 int 类型的变量,要先把 int 转换成大端字节序,然后通过网络发送。

    大端字节序又被称之为网络细节序。

    查看全部
  • ~ 取反

    ^ 异或

    << 左移

    >> 右移

    查看全部
  • 浮点数会有一定的精度范围,一旦小数点后面位数过多,超出范围,就有可能失去精度。

    浮点数的存放复杂,运行起来速度也比较慢,如无必要,还是用整数方便快捷。

    查看全部
  • 复制一个员工:赋值构造函数

    上一小节中,我们介绍了构造函数和析构函数。这一小节,我们来介绍一个特殊的构造函数。

    先来看一个例程:

    int main(int argc,char **argv) {     Staff staffA;     Staff staffB = staffA;     return 0; }

    我们先实例化了一个对象 staffA,然后又实例化了一个对象 staffB。希望 staffB 和 staffA 具有相同的内容,或者说希望 staffB 是 staffA 的副本,那么我们一般直接在实例化的时候进行赋值就可以了。

    Staff staffB = staffA;

    这样做了之后,C++ 会自动为我们拷贝 staffA 中的成员变量到 staffB 的成员变量中,但是这种自动拷贝机制在某些情况下无法完成我们想要的动作,甚至有可能会出错。我们来具体看一下。

    在 Staff 类中添加一些内容:

    Staff.hpp

    #include <string>

    class Staff { 

    public:     

        Staff(std::string _name, int _age);     

        ~Staff(); 

    public:     

        std::string name;    

        int age;     

        char * mem = nullptr; };


    Staff.cpp

    #include "Staff.hpp" 

    #include <stdio.h> 

    Staff::Staff(std::string _name, int _age) {    

     mem = (char *)malloc(20);     

    name = _name;    

     age = _age;     

    printf("构造函数被调用\n"); 

    Staff::~Staff() {    

     if(mem != nullptr){         free(mem);         mem = nullptr;     }     

    printf("析构函数被调用\n"); 

    }

    在上面的代码中,在类中定义了一个指针,在构造函数中,通过 malloc 函数分配了一个 20 字节大小的堆内存,然后将这片堆内存的首地址赋值给了这个指针。在析构函数中,我们将这片堆内存释放掉。

    这个时候,我们再进行一开始的操作:

    Staff staffB = staffA;


    先来看看 staffA 在实例化之后的内存布局:

    http://img1.sycdn.imooc.com//61097bdc00019c8b08080243.jpg

    mem 指针指向了一片 20 个字节大小的堆内存。

    这个时候,再来看看执行了Staff staffB = staffA;之后,staffB 的内存布局会怎么样:

    http://img1.sycdn.imooc.com//61097bea00010da608030535.jpg

    可以看到,在 C++ 默认的复制模式之下,两个对象中的 mem 指针指向了同一片内存。因为 C++ 默认的复制模式只会简单得把成员的值进行复制,面对这个 mem 指针,他只会把指针的值进行拷贝,最后的结果就是 mem 指针指向了同一片内存。

    这种拷贝方式,被称之为浅拷贝。

    赋值构造函数

    Staff staffB = staffA;

    当我们使用这种方式实例化对象的时候,并不会调用普通构造函数,而是会调用一个特殊的构造函数,被称之为赋值构造函数或者拷贝构造函数。如果我们没有写,那么就会按照浅拷贝的方式来进行复制。一个拷贝构造函数看起来就像下面这样:

    Staff(const Staff & staff);

    这个函数中只有一个参数 staff,表示要拷贝的对象,在我们的例子中,就是 staffA。(const 和 & 我们在后续的课程中会具体讲解)

    那么我们来完整的编写一下这个函数

    Staff.h

    #include <string> 

    class Staff { 

    public:     

        Staff(std::string _name, int _age);    

         Staff(const Staff & staff);     

        ~Staff(); 

    public:    

         std::string name;     

        int age;     

        char * mem = nullptr; };


    Staff.cpp

    #include "Staff.hpp" 

    #include <stdio.h> 

    Staff::Staff(std::string _name, int _age) {     

        mem = (char *)malloc(20);     

        name = _name;     

        age = _age;     

        printf("构造函数被调用\n"); 

    Staff::Staff(const Staff & staff) {     

        name = staff.name;     

        age = staff.age;     

        mem = (char *)malloc(20);     

        memcpy(mem, staff.mem, 20); 

    Staff::~Staff() {     

        if(mem != nullptr){         free(mem);         mem = nullptr;     }     

        printf("析构函数被调用\n"); 

    }

    查看全部
  • 函数返回一个绳子:函数返回指针

    指针变量其实和普通变量没有什么区别,一个函数也是可以正常返回一个指针的。

    char * func() {     char * p = nullptr;     return p; } 

    int main(int argc,char **argv) {     return 0; }
    但是我们需要思考的是,什么情况下我们要返回一个指针,返回指针的时候需要我们注意些什么?通常情况下,我们是希望为函数外提供一片内存,例如,我们可以给函数外面提供一个数组。int * func() {     int arr[] = {1, 2, 3, 4};     return arr; }
    但是这样写得话,程序会崩溃掉。原因是,arr 数组是一个局部变量,在 func 结束之后,其内存就被销毁掉了。此时在函数外面对其进行操作,自然会出问题。所以,要完成这类操作,我们需要把内存分配到堆内存上面。

    int * func() {     int * arr = (int *)malloc(4 * sizeof(int));     return arr; }
    这样就没有问题了,当然,既然是分配在了堆内存上,就要记得手动销毁。

    int main(int argc,char **argv) {     int * p = func();     free(p);     return 0; }

    查看全部
  • #include<cstring>

    memcpy指的是C和C++使用的内存拷贝函数,函数原型为void *memcpy(void *destin, void *source, unsigned n);函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中。

    查看全部
    0 采集 收起 来源:强者争霸

    2021-07-19

  • 指针变量其实和普通变量没有什么区别,一个函数也是可以正常返回一个指针的。

    查看全部
  • 代码块中定义的变量被称之为局部变量。它们在其他函数的语句中是不可见的,也无法访问它们。

    全局变量是在所有函数体的外部定义的,程序的所有部分都可以使用。全局变量不受作用域的影响,其生命周期一直到程序的结束。

    查看全部
  • 无法确认指向的指针,或者指向一个无效地址的指针,我们把他叫做野指针

    查看全部
  • 数组名就是一个指针,不过数组名是一个常量指针,不能做累加或者累减操作

    查看全部
  • 指针的本质(*:解引用、&:取地址)

    查看全部
  • 我的笔记

    查看全部

举报

0/150
提交
取消
课程须知
你需要具备基础的 C++ 语法知识,在学习本课程之前,建议先学习《趣味 C++ 入门》,快速认识 C++,熟悉 C++ 基本语法,更加快速入手进阶课程!
老师告诉你能学到什么?
在本门课程中,你将学习到:计算机存储数据的原理、指针的进阶、面向对象编程、内存管理技巧等 C++ 高级语法。在课程的最后,将带领大家使用 C++ 编写一个五子棋游戏,通过实践,加深理解,巩固学习成果。

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!