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

趣味 C++ 进阶

难度初级
时长 8小时 0分
学习人数
综合评分9.60
10人评价 查看评价
10.0 内容实用
8.8 简洁易懂
10.0 逻辑清晰
  • 函数返回值类型+(指针变量名)+(函数传入的参数)=函数名

    第25行的代码表示用指针的形式调用函数

    dowork()回调函数的用法

    查看全部
  • 指针可以指向一个数组,例如:

    #include <stdio.h>

    int main(int argc,char **argv)
    {
       int arr[] = {1, 2, 3, 4};
       int * p = arr;
       return 0;
    }

    比较特殊的是,数组名就是一个指针,不过数组名是一个常量指针,不能做累加或者累减操作。

    我们可以通过指针来访问数组元素:

    *(p + 2)

    同样,这句话等价于:

    p[2]

    查看全部
  • 指针可以指向一个变量,例如:

    #include <stdio.h>

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

    如果想要通过指针操作变量,只需要使用解引用就可以了:

    *p = 20;

    查看全部
  • .与->的不同用法

    查看全部
  • 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; }

    查看全部
  • 💊吧把v(vv m筋m哦哦看看那几句台词mmnhhy搞个y

    查看全部
  • conat修饰成员函数类似c#中的static,不能调用非const函数、不能修改成员变量

    查看全部
  • const表示常量的修饰符,可以修饰定义的变量,表示常量不可改变,修饰指针表示指针只能指向固定的位置,修饰指针指向的变量,表示指针指向变量不可修改(但是指针可以指向其他位置),修饰函数表示返回的数据不能修改;

    查看全部
  • 多态:即是通过继承虚函数来实现不同子类的具体实现,基类的析构函数设置为虚函数目的是让子类实现,这样就可以调用子类的析构过程,进而释放内存。

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

    2021-07-22

举报

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

微信扫码,参与3人拼团

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

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