• 温故知新----封装(struct)


    上次提到class是最常见的封装,今天发现别人开发的SDK里面有大量的结构体struct

    转载:

    1. https://blog.csdn.net/a_forever_dream/article/details/88843230           (直接简单)

    2.(更为详细https://blog.csdn.net/weixin_42018112/article/details/82429514?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2

    3. https://blog.csdn.net/veryitman/article/details/89578484(提供了另一种初始化方法)

    废话
    struct是个很有用的东西呢!
    进入正题
    struct的用处是定义一个新的类型,而这个类型里面可以是各种各样的东西。


    比如:
    struct node{//定义一个新的类型叫node
     int a;
     int b[110];
     char c;
     double d;
    };//别忘了分号,毕竟这是个语句呢



    当然里面还可以放一些更厉害的东西,就像这个!


    struct node{
     int y(int p)
     {
      return p+1;
     }
     int z;
     void add()
     {
      z++;//这个z和上面那个是同一个
     }
    };

    定义的话直接用就行了,譬如:
    node x;

    需要调用里面的元素时,加个点就行了,就像这样:
    x.a=10;
    x.b[1]++;
    x.c='a';
    x.d=3.1415;
    x.z=x.y(x.z);
    x.add();

    struct还有一个神奇的东西:构造函数
    那有人可能会问,这比直接定义里面的元素好在哪里呢?
    既然struct是把一些不相关的东西整合到一起,那么这些不相关的东西就有了某些神奇的联系,比如说可以用来定义线段树的顶点之类的。
    看下面一段代码:
    struct node{
        node *zuo,*you;
        int l,r,z;
        void build(int ll,int rr)
        {
            l=ll,r=rr;z=0;
            int mid=l+r>>1;
            if(l==r)zuo=you=NULL;
            else zuo=new node,zuo->build(ll,mid),you=new node,you->build(mid+1,rr);
        }
    };

    这是利用指针和struct写的一个构建线段树的代码,可以说是很精简了。
    并且还有一个很方便的功能:
    node a,b;
    a=b;//可以直接把b中所有东西直接丢给a

    C++中的结构体
    在C语言中,结构体不能包含函数。
    在面向对象的程序设计中,对象具有状态(属性)和行为,状态保存在成员变量中,行为通过成员方法(函数)来实现
    C语言中的结构体只能描述一个对象的状态,不能描述一个对象的行为。在C++中,考虑到C语言到C++语言过渡的连续性,对结构体进行了扩展,C++的结构体可以包含函数,这样,C++的结构体也具有类的功能,与class不同的是,结构体包含的函数默认为public,而class中默认是private。
    结构体的定义与声明


    实例代码1:
    struct tag
    {
        member-list
    }variable-list;
    注:struct为结构体关键字;
       tag为结构体的标志;
       member-list为结构体成员变量及成员函数列表,其必须列出其所有成员;
       variable-list为此结构体声明的变量;


    实例代码2:
    #include <iostream>

    using namespace std;

    struct SAMPLE
    {
        int x;
        int y;
        int add() {return x+y;}
    }s1;

    int main()
    {
        cout<<"没初始化成员变量的情况下:"<<s1.add()<<endl;
        s1.x = 3;
        s1.y = 4;
        cout<<"初始化成员变量的情况下:"<<s1.add()<<endl;
        system("pause");
        return 0;
    }
    =>没初始化成员变量的情况下:0
      初始化成员变量的情况下:7


    C++中的结构体与类的区别: (1)class中默认的成员访问权限是private的,而struct中则是public的。 (2)class继承默认是private继承,而从struct继承默认是public继承。
    结构体也可以继承结构体或者类。
    结构体的作用

    在实际项目中,结构体是大量存在的。研发人员常使用结构体来封装一些属性来组成新的类型由于C语言内部程序比较简单,研发人员通常使用结构体创造新的“属性”,其目的是简化运算。
    结构体在函数中的作用不是简便,最主要的作用就是封装。封装的好处就是可以再次利用。让使用者不必关心这个是什么,只要根据定义使用就可以了。

    请看转载的原文链接:https://blog.csdn.net/veryitman/article/details/89578484

    本篇文章的所有代码都经 gcc-7 编译器编译过。关于在 macOS 中如何安装和使用 gcc,可以参考 GCC: Homebrew 安装 GCC 和 Binutils 这篇文章。
    结构体成员指针的初始化

    结构体成员指针的初始化,指的是初始化结构体中指针变量的成员。

    我们举个例子,下面是 Animal 的结构体。
    struct Animal {
        char *name; //指针成员
        int age;
        char info[200]; //字符数组
        struct Animal *nextAnimal; //指针成员
    };

    结构体 Animal 含有4个成员变量,其中 name、info 和 nextAnimal 是指针变量。
    写一段测试代码,如下:
    int main(int argc, const char *argv[])
    {
        struct Animal animal;
       
        printf("animal's name: %s, age: %i, info: %s ", animal.name, animal.age, animal.info);
       
        return 0;
    }

    运行结果正常,终端输出如下:
    animal's name: (null), age: 0, info:
    1
    我们来验证一下 Animal *nextAnimal 在没有初始化的情况下,会不会有什么问题。
    int main(int argc, const char *argv[])
    {
        struct Animal animal;
       
        printf("animal's name: %s, age: %i, info: %s ", animal.name, animal.age, animal.info);
       
        printf("animal.nextAnimal: %p ", animal.nextAnimal);
       
        printf("animal.nextAnimal->name: %s, age: %i, info: %s ", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info);
       
        return 0;
    }

    程序编译没有问题,运行报错
    animal's name: (null), age: 0, info:
    animal.nextAnimal: 0x1127fa036
    Segmentation fault: 11

    修改一下代码,初始化一下 animal.nextAnimal 这个指针,如下:
    int main(int argc, const char *argv[])
    {
        struct Animal animal;
       
        printf("animal's name: %s, age: %i, info: %s ", animal.name, animal.age, animal.info);
       
        printf("animal.nextAnimal: %p ", animal.nextAnimal);
       
        // 初始化指针变量
        animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
       
        printf("animal.nextAnimal->name: %s, age: %i, info: %s ", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info);
       
        return 0;
    }

    再次编译重新运行,还是报错。还需要初始化 animal.nextAnimal->name 这个变量。
    int main(int argc, const char *argv[])
    {
        struct Animal animal;
       
        printf("animal's name: %s, age: %i, info: %s ", animal.name, animal.age, animal.info);
       
        printf("animal.nextAnimal: %p ", animal.nextAnimal);
       
        // 初始化指针变量
        animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
       
        // 初始化 name 变量
        animal.nextAnimal->name = "cat";
       
        printf("animal.nextAnimal->name: %s, age: %i, info: %s ", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info);
       
        return 0;
    }

    编译运行,一切正常。
    animal's name: (null), age: 0, info:
    animal.nextAnimal: 0x10f0f1036
    animal.nextAnimal->name: cat, age: 0, info:
    123
    通过上面的例子,结构体指针变量有些会给默认值,有些又不会给,所以都要初始化指针变量。
    修改一下代码,示例如下:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    struct Animal {
        char *name; //指针成员
        int age;
        char info[200]; //字符数组
        struct Animal *nextAnimal; //指针成员
    };

    int main(int argc, const char *argv[])
    {
        struct Animal animal;
       
        animal.name = "cat";
        strcpy(animal.info, "This is a cat.");
        printf("animal's name: %s, age: %i, info: %s ", animal.name, animal.age, animal.info);
       
        printf("animal.nextAnimal: %p ", animal.nextAnimal);
       
        // 初始化指针变量
        animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
       
        // 初始化变量
        animal.nextAnimal->name = "cat";
        strcpy(animal.nextAnimal->info, "This is a cat.");
       
        printf("animal.nextAnimal->name: %s, age: %i, info: %s ", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info);
       
        return 0;
    }


    结构体指针的初始化

    指的是初始化结构体指针变量。

    int main(int argc, const char *argv[])

        struct Animal *ptAnimal;
           
        printf("ptAnimal's name: %s, age: %i, info: %s ", ptAnimal->name, ptAnimal->age, ptAnimal->info);
       
        return 0;
    }

    编译运行报错:
    Segmentation fault: 11
    1
    同样的道理,需要初始化指针变量。完成后的示例代码如下:
    int main(int argc, const char *argv[])
    {
        struct Animal *ptAnimal;
       
        // 初始化结构体指针
        ptAnimal = (struct Animal *)malloc(sizeof(struct Animal));
       
        ptAnimal->name = "dog";
        strcpy(ptAnimal->info, "This is a big dog");
       
        printf("ptAnimal's name: %s, age: %i, info: %s ", ptAnimal->name, ptAnimal->age, ptAnimal->info);
       
        // 初始化结构体指针的成员指针变量 nextAnimal
        ptAnimal->nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
        ptAnimal->nextAnimal->name = "dog";
        strcpy(ptAnimal->nextAnimal->info, "This is a big dog");
       
        printf("ptAnimal->nextAnimal's name: %s, age: %i, info: %s ",
               ptAnimal->nextAnimal->name, ptAnimal->nextAnimal->age, ptAnimal->nextAnimal->info);
       
        return 0;
    }

    完整示例
    main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    struct Animal {
        char *name; //指针成员
        int age;
        char info[200]; //字符数组
        struct Animal *nextAnimal; //指针成员
    };

    int main(int argc, const char *argv[])
    {
        /// 验证结构体指针成员变量
        {
            struct Animal animal;
           
            animal.name = "cat";
            strcpy(animal.info, "This is a cat.");
            printf("animal's name: %s, age: %i, info: %s ", animal.name, animal.age, animal.info);
           
            printf("animal.nextAnimal: %p ", animal.nextAnimal);
           
            // 初始化指针变量
            animal.nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
           
            // 初始化变量
            animal.nextAnimal->name = "cat";
            strcpy(animal.nextAnimal->info, "This is a cat.");
           
            printf("animal.nextAnimal->name: %s, age: %i, info: %s ", animal.nextAnimal->name, animal.nextAnimal->age, animal.nextAnimal->info);
        }
       
        /// 验证结构体指针
        {
            struct Animal *ptAnimal;
           
            // 初始化结构体指针
            ptAnimal = (struct Animal *)malloc(sizeof(struct Animal));
           
            ptAnimal->name = "dog";
            strcpy(ptAnimal->info, "This is a big dog");
           
            printf("ptAnimal's name: %s, age: %i, info: %s ", ptAnimal->name, ptAnimal->age, ptAnimal->info);
           
            // 初始化结构体指针的成员指针变量 nextAnimal
            ptAnimal->nextAnimal = (struct Animal *)malloc(sizeof(struct Animal));
            ptAnimal->nextAnimal->name = "dog";
            strcpy(ptAnimal->nextAnimal->info, "This is a big dog");
           
            printf("ptAnimal->nextAnimal's name: %s, age: %i, info: %s ",
                   ptAnimal->nextAnimal->name, ptAnimal->nextAnimal->age, ptAnimal->nextAnimal->info);
        }
       
        return 0;
    }

    编译
    gcc-7 main.c -o main
    1
    运行
    ./main
    1
    运行结果如下:
    animal's name: cat, age: 0, info: This is a cat.
    animal.nextAnimal: 0x0
    animal.nextAnimal->name: cat, age: 0, info: This is a cat.
    ptAnimal's name: dog, age: 0, info: This is a big dog
    ptAnimal->nextAnimal's name: dog, age: 0, info: This is a big dog
    ————————————————

  • 相关阅读:
    卡常技巧
    Java经典习题3
    Java经典习题4
    VC++ MFC 文件处理unicode
    批处理更换ip地址
    C#实现系统托盘
    驱动打印
    c++ vs2010 GetWindowText GetWindowTextW
    VC++ MFC ListBox 复选框
    C# 获取本机ip地址
  • 原文地址:https://www.cnblogs.com/MCSFX/p/12693411.html
Copyright © 2020-2023  润新知