精华内容
参与话题
问答
  • C语言中的结构体(struct)

    万次阅读 多人点赞 2015-11-08 13:50:11
    C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型)。本文主要介绍关于结构体以下几部分。 1、概念为什么要有结构体?因为在实际问题中,一组数据往往有很多种不同的数据类型。...

    C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型)。本文主要介绍关于结构体以下几部分。
    这里写图片描述

    1、概念

    为什么要有结构体?

    因为在实际问题中,一组数据往往有很多种不同的数据类型。例如,登记学生的信息,可能需要用到 char型的姓名,int型或 char型的学号,int型的年龄,char型的性别,float型的成绩。又例如,对于记录一本书,需要 char型的书名,char型的作者名,float型的价格。在这些情况下,使用简单的基本数据类型甚至是数组都是很困难的。而结构体(类似Pascal中的“记录”),则可以有效的解决这个问题。
    结构体本质上还是一种数据类型,但它可以包括若干个“成员”,每个成员的类型可以相同也可以不同,也可以是基本数据类型或者又是一个构造类型。
    结构体的优点:结构体不仅可以记录不同类型的数据,而且使得数据结构是“高内聚,低耦合”的,更利于程序的阅读理解和移植,而且结构体的存储方式可以提高CPU对内存的访问速度。

    结构声明(structure declaration)

    结构声明(也见有称做定义一个结构体)是描述结构如何组合的主要方法。
    一般形式是:
    struct 结构名{
    成员列表
    };
    struct关键词表示接下来是一个结构。
    如声明一个学生的结构:

    struct Student{         //声明结构体
        char name[20];      //姓名
        int num;            //学号
        float score;        //成绩
    };

    上面的声明描述了一个包含三个不同类型的成员的结构,但它还没创建一个实际的数据对象,类似C++中的模板。每个成员变量都用自己的声明来描述,以分号结束。花括号之后的分号表示结构声明结束。结构声明可以放在函数外(此时为全局结构体,类似全局变量,在它之后声明的所有函数都可以使用),也可以放在函数内(此时为局部结构体,类似局部变量,只能放在该函数内使用,如果与全局结构体同名,则会暂时屏蔽全局结构体)。

    要定义结构变量,则一般形式是:
    struct 结构体名 结构体变量名;
    如:

    struct Student stu1;    //定义结构体变量

    这里写图片描述
    1)、结构体变量的定义可以放在结构体的声明之后:

    struct Student{         //声明结构体
        char name[20];      //姓名
        int num;            //学号
        float score;        //成绩
    };
    struct Student stu1;    //定义结构体变量

    2)、结构体变量的定义也可以与结构体的声明同时,这样就简化了代码:

    struct Student{        
        char name[20];       
        int num;             
        float score;         
    }stu1;                  //在定义之后跟变量名

    3)、还可以使用匿名结构体来定义结构体变量:

    struct {                //没有结构名
        char name[20];       
        int num;            
        float score;         
    }stu1;  
    

    但要注意的是这样的方式虽然简单,但不能再次定义新的结构体变量了。

    访问结构成员

    虽然结构类似一个数组,只是数组元素的数据类型是相同的,而结构中元素的数据类型是可以不同的。但结构不能像数组那样使用下标去访问其中的各个元素,而应该用结构成员运算符点(.)。即访问成员的一般形式是:
    结构变量名 . 成员名
    如 stu1 . name 表示学生stu1的姓名。

    但如果结构体中的成员又是一个结构体,如:

    struct Birthday{                //声明结构体 Birthday
        int year;
        int month;
        int day;
    };
    struct Student{                 //声明结构体 Student
        char name[20];              
        int num;                    
        float score;                 
        struct Birthday birthday;   //生日
    }stu1;

    则用 stu1.birthday.year 访问出生的年份。

    结构体变量的初始化

    1)、结构体变量的初始化可以放在定义之后:

    可以对结构体的成员逐个赋值:

    struct Student stu1, stu2;      //定义结构体变量
    strcpy(stu1.name, "Jack");
    stu1.num = 18;
    stu1.score = 90.5;

    注意:不能直接给数组名赋值,因为数组名是一个常量。如:

    stu1.name = "Jack"; //…main.c:26:15: Array type 'char [20]' is not assignable

    或者可以对结构体进行整体赋值:

    stu2 = (struct Student){"Tom", 15, 88.0};

    注意:此时要进行强制类型转换,因为数组赋值也是使用{},不转换的话系统无法区分!如:

    int arr[5] = {1, 2, 3, 4, 5};       //数组的初始化
    stu2 = {"Tom", 15, 88.0};           //…main.c:31:12: Expected expression

    2)、结构体变量的初始化也可以与定义同时:

    struct Student{                 //声明结构体 Student
        char name[20];               
        int num;                    
        float score;                 
    }stu = {"Mike", 15, 91};        //注意初始化值的类型和顺序要与结构体声明时成员的类型和顺序一致

    此时不需要强制类型转换
    也可以部分初始化:

    struct Student stu4 = {.name = "Lisa"};

    也可以按照任意的顺序使用指定初始化项目:

        struct Student st = { .name = "Smith",
                              .score = 90.5,
                              .num = 18 };

    3)、可以用一个已经存在的结构体去初始化一个新的相同类型的结构体变量,是整体的拷贝(每一个成员都一一赋值给新的结构体变量),而不是地址赋值。如:

    stu3 = stu1;
    printf("stu1 addr: %p\nstu3 addr: %p\n", &stu1, &stu3);
    printf("stu1.num: %d\nstu3.num: %d\n", stu1.num, stu3.num);
    printf("stu1.num addr: %p\nstu3.num addr: %p\n", &stu1.num, &stu3.num);
    //输出结果:
    stu1 addr: 0x10000104c
    stu3 addr: 0x100001084
    stu1.num: 18
    stu3.num: 18
    stu1.num addr: 0x100001060
    stu3.num addr: 0x100001098

    2、结构体变量的存储原理

    1)结构体数据成员对齐的意义

    内存是以字节为单位编号的,某些硬件平台对特定类型的数据的内存要求从特定的地址开始,如果数据的存放不符合其平台的要求,就会影响到访问效率。所以在内存中各类型的数据按照一定的规则在内存中存放,就是对齐问题。而结构体所占用的内存空间就是每个成员对齐后存放时所占用的字节数之和。
    计算机系统对基本数据类型的数据在内存中存放的限制是:这些数据的起始地址的值要求是某个数K的倍数,这就是内存对齐,而这个数 K 就是该数据类型的对齐模数(alignment modulus)。这样做的目的是为了简化处理器与内存之间传输系统的设计,并且能提升读取数据的速度。
    结构体对齐不仅包括其各成员的内存对齐(即相对结构体的起始位置),还包括结构体的总长度。

    2)结构体大小的计算方法和步骤
    i. 将结构体内所有数据成员的长度值相加,记为 sum_a ;
    ii. 将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到sum_a上,记为sum_b。
    对齐模数是 #pragma pack 指定的数值与该数据成员自身长度相比较得到的数值较小者。该数据相对起始位置应该是对齐模数的整数倍。
    iii. 将和 sum_b 向结构体模数对齐。
    该模数则是 #pragma pack 指定的数值与结构体内最大的基本数据类型成员长度相比较得到的数值较小者。结构体的长度应该是该模数的整数倍。

    数据类型自身对齐:
    这里写图片描述
    所谓“对齐在N上”,是指“存放的起始位置是%N = 0”.

    3)在没有#pragma pack宏的情况下:
    例子1:

    这里写图片描述

    内存分配状态为:

    这里写图片描述

    对于结构体的第一个成员 a,起始位置为0x…38 (也为 4 的倍数),所占内存为 0x…38 ~ 0x…3b,共占4个字节;
    对于结构体的第二个成员 b,自身长度为1,对齐模数也为1,所以内存分配可以紧接着a的结尾位置 0x…3b,所以起始位置为 0x…3c,共占1个字节;
    对于结构体的第三个成员 c,自身长度为2,对齐模数也为2,所以起始位置距离a 的起始位置应该是2的倍数,所以 0x…3d处只距离5,不符合要求,所以空着,继续往下找,而在 0x…3e处满足要求,所以可以作为c的起始位置,共占2个字节;
    此时3个成员及其中间空着的位置所占内存单元总和为8,而结构体内最大的基本数据成员是 a,其长度为4,所以结构体模数为 4,而8是4的倍数,满足要求,故不再加内存。

    例子2:
    与例子1相比,三个类型的声明顺序变了:

    这里写图片描述

    内存分配状态为:
    这里写图片描述

    要注意的是,对 a而言,对齐模数为 4,所以当 b的起始位置在0x7f…830之后,0x7f…831、0x7f…832、0x7f…833的位置距离起始位置0x7f…830分别是1,2,3,都不是 4 的倍数,所以那三个位置都空着,直到0x7f…834才满足要求,所以作为 a 的起始位置。当最后 一个成员 c 占的内存末尾在0x7f…839时,所有数据成员及其之间的空位所占内存单元总和为10,而结构体模数为4,10不是4的倍数,所以要扩大到12才满足要求,此时又多了2个空位置,就是0x7f…83a和0x7f…83b。

    例子3:
    当结构体中有数组时:

    这里写图片描述

    内存分配状态为:
    这里写图片描述

    亦即相同类型数据的数组之间多分配的空间会被相邻数组的元素所占用。

    4)在存在#pragma pack宏的情况下:
    方法类似,只是模数可能会按上面说的规则而有所变化。

    这里写图片描述

    内存分配状态为:
    这里写图片描述

    注意,当没有#pragma pack(2)时,成员a要确定自身的q起始位置,是以自身的长度4为对齐模数,但有了#pragma pack(2),则将括号里的2与a的长度4比较,2为较小者,所以以2为a的对齐模数,即地址从0x7f…839往下找到0x7f…83a时,已经距离结构体的起始位置0x7f…838为2,是2的倍数,满足要求(虽然不是4的倍数),可以作为a的起始位置。而最后,所有数据成员及其之间的空位所占内存单元总和为8,因为2和4(结构体中最大的数据成员长度)的较小者为2,而8是2的倍数,所以刚好满足要求,不用在分配空位置,所以结构体总长度即为8。

    3、结构体数组

    结构类型作为一种数据类型,也可以像基本数据类型那样,作为数组的元素的类型。元素属于结构类型的数组成为结构型数组。如开头提出的问题,生活中经常用到结构数组来表示具有相同数据结构的一个群体,如一个班的学生的信息,一个书店或图书馆的书籍信息等。

    1)结构数组定义
    一般格式:
    struct 结构名 {
    成员列表
    } 数组名[数组长度];
    如:

    struct Student{                 //声明结构体 Student
        char name[20];
        int num;
        float score;
    }stu[5];                        //定义一个结构结构数组stu,共有5个元素

    2)结构数组的初始化

    定义结构数组的同时进行初始化

    struct Student stu[2] = {{"Mike", 27, 91},{"Tom", 15, 88.0}};  

    先定义,后初始化
    整体赋值:

    stu[2] = (struct Student){"Jack", 12, 85.0};

    或者将结构体变量的成员逐个赋值:

    strcpy(stu[3].name, "Smith");
    stu[3].num = 18;
    stu[3].score = 90.5;

    输出结构体:

    //结构体数组的长度:
    int length = sizeof(stu) / sizeof(struct Student);
    //逐个输出结构数组的元素
    for (int i = 0; i < length; i++) {
        printf("姓名:%s  学号:%d  成绩:%f \n", stu[i].name, stu[i].num, stu[i].score);
    }

    //输出结果:
    这里写图片描述

    在这个例子中,要注意的是:
    这里写图片描述

    4、结构与指针

    当一个指针变量用来指向了一个结构变量,这个指针就成了结构指针变量。
    结构指针变量中的值是所指向的结构变量的首地址。可以通过指针来访问结构变量。

    1)定义结构指针变量的一般形式:
    struct 结构名 * 结构指针变量名
    如:

    struct Student *pstu;       //定义了一个指针变量,它只能指向Student结构体类型的结构体变量

    结构指针变量的定义也可以与结构体的定义同时。而且它必须先赋值后使用。
    数组名表示的是数组的首地址,可以直接赋值给数组指针。但结构变量名只是表示整个结构体变量,不表示结构体变量的首地址,所以不能直接赋值给结构指针变量,而应该使用 & 运算符把结构变量的的地址赋值给结构指针变量。即:

    这里写图片描述

    注意:结构名、结构变量名、结构体指针的区别。

    2)通过结构指针间接访问成员值

    访问的一般形式:
    (*结构指针变量). 成员名 或 结构指针变量 -> 成员名
    如:

    (*pstu).name    
    pstu->name

    注意(pstu)的小括号不能省略,因为成员符“.”优先级为1,取地址符“”优先级为2,去掉括号就相当于*(pstu.name)了。

    5、结构体的嵌套

    1)结构体中的成员可以又是一个结构体,构成结构体的嵌套:

    struct Birthday{                //声明结构体 Birthday
        int year;
        int month;
        int day;
    };
    struct Student{                 //声明结构体 Student
        char name[20];              
        int num;                    
        float score;                 
        struct Birthday birthday;   //生日
    }; 
    

    这里写图片描述
    2)结构体不可以嵌套跟自己类型相同的结构体,但可以嵌套定义自己的指针。如:

    struct Student{                 //声明结构体 Student
        char name[20];
        int num;
        float score;
        struct Student *friend;     //嵌套定义自己的指针
    }

    3)甚至可以多层嵌套:

    struct Time{                    //声明结构体 Time
        int hh;                     //时
        int mm;                     //分
        int ss;                     //秒
    };
    struct Birthday{                //声明结构体 Birthday
        int year;
        int month;
        int day;
        struct Time dateTime        //嵌套结构
    };
    struct Student{                 //声明结构体 Student
        char name[20];
        int num;
        float score;
        struct Birthday birthday;   //嵌套结构
    }
    //定义并初始化
    struct Student stud = {"Jack", 32, 85, {1990, 12, 3, {12, 43, 23}}};
    //访问嵌套结构的成员并输出
    printf("%s 的出生时刻:%d时 \n", stud.name, stud.birthday.dateTime.hh);
    //输出结果:Jack 的出生时刻:12时 

    注意如何初始化和对嵌套结构的成员进行访问。

    6、结构与函数

    结构体的成员可以作为函数的参数,属于值传递(成员是数组的除外)。如:

    struct Student{                 //声明结构体 Student
        char name[20];
        int num;
        float score;
    };
    void printNum(int num){         //定义一个函数,输出学号
        printf("num = %d \n", num);
    }
        struct Student student0 = {"Mike", 27, 91};
        printNum(student0.num);     //调用printNum 函数,以结构成员作函数的参数
    //运行结果:num = 27 

    注意,函数printNum并不知道也不关心实际参数是不是结构成员,它只要求实参是int类型的就可以了。

    结构变量名也可以作为函数的参数传递,如:

    void PrintStu(struct Student student){      //定义 PrintStu 函数,以结构变量作函数的形参
        student.num = 100;                      //修改学号
        printf("PrintStu 修改后:姓名: %s, 学号: %d, 内存地址: %p \n", student.name, student.num, &student);
    }
        struct Student student0 = {"Mike", 27, 91};
        PrintStu(student0);                     //调用 PrintStu 函数,以结构变量名作函数的参数
        printf("           原来:姓名: %s, 学号: %d,  内存地址: %p \n", student0.name, student0.num, &student0);
    

    //输出结果:
    这里写图片描述

    形参和实参的地址不一样,是在函数中创建了一个局部结构体,然后实参对形参进行全部成员的逐个传送,在函数中对局部结构体变量进行修改并不影响原结构体变量。这样传送的时间空间开销都比较大,特别是当成员有数组的时候,程序效率较低。所以可以考虑使用指针:

    void PrintStu2(struct Student *student){      //定义 PrintStu2 函数,以结构指针作函数的形参
        student->num = 100;                       //修改学号
        printf("PrintStu2 修改后:姓名: %s, 学号: %d, 内存地址: %p \n", student->name, student->num, student);
    }
        struct Student student0 = {"Mike", 27, 91};
        PrintStu2(&student0);                     //调用 PrintStu 函数,以结构变量的地址作函数的参数
        printf("           原来:姓名: %s, 学号: %d,  内存地址: %p \n", student0.name, student0.num, &student0);

    //输出结果:
    这里写图片描述

    形参和实参的地址是一样的,所以是地址传递,在 PrintStu2 函数中,student 与&student0 指向同一块内存单元,用指针student修改结构变量会影响原结构变量。

    展开全文
  • 使用java语言来实现数据结构中涉及到的算法,并针对每个算法搭配习题进行实现。
  • 结构型模式 描述 如何将类或对象结合在一起形成更大的结构 适配器模式 描述 将一个类的接口,转换成客户期望的另一个接口。 适配器可以让原本接口不兼容的类能够一起工作。 适用场合 现有类可满足客户类的功能需要...

    结构型模式

    描述

    如何将类或对象结合在一起形成更大的结构

    适配器模式

    描述

    将一个类的接口,转换成客户期望的另一个接口。

    适配器可以让原本接口不兼容的类能够一起工作。

    适用场合

    1. 现有类可满足客户类的功能需要,但接口不匹配

    结构

    包含角色:

    • Client:与符合Target接口的对象协同
    • Target:定义Client使用的与特定领域相关的接口
    • Adaptee:定义一个已经存在的接口,需要适配的接口类
    • Adapter:负责Adaptee的接口与Target接口进行适配

    类适配器

    描述

    用一个具体的Adapter类对Adaptee和Target进行匹配,Adapter类多重继承Adaptee和Target类。

    注意:Adapter可重定义Adaptee的部分行为,因为Adapter是Adaptee的一个子类。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ir2MTJFW-1604838707225)(%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F.assets/image-20201031195154355.png)]

    对象适配器

    描述

    允许一个Adapter与多个Adaptee同时工作,即Adaptee本身以及它 的所有子类(如果有子类的话)同时工作。Adapter可以一次给所有 的Adaptee添加功能 。

    使用组合,不仅可以适配某个类,也可以适配该类的任何子类。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KjseQaxn-1604838707228)(%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F.assets/image-20201031195458213.png)]

    类适配器和对象适配器比较

    类适配器(继承):属于静态结构,只能单继承

    对象适配器(委托):可以把多个不同的适配者适配到同一个目标。

    优点

    将目标类和适配者类解耦

    桥梁模式

    描述

    将抽象部分与实现部分分离,使它们可以独立的变化

    适用场合

    1.不希望在抽象和它的实现部分之间有一个固定的绑定关系

    2.类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充

    3.对客户隐藏抽象的实现部分,并且修改实现部分对客户不产生影响

    结构

    包含的角色:

    • Abstraction:定义抽象类的接口
    • RefinedAbstraction:扩充由Abstraction定义的接口
    • Implementor:定义实现类的接口
    • ConcreteImplementor:定义Implementor接口的具体实现

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-63p74xZZ-1604838707230)(%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F.assets/image-20201031201656899.png)]

    要点

    桥梁模式中的解耦就是指在一个软件系统的抽象和实现之间使用组合/聚合关系,而不是继承关系。从而使两者可以相对独立的变化。

    装饰模式

    描述

    动态地给对象添加额外职责。不是通过继承,而是通过组合实现。

    适用场合

    1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责

    2.当不能采用生成子类的方式进行扩充时

    结构

    包含角色:

    • Component:对象接口
    • ConcreteComponent:具体对象
    • Decorator:定义一个与Component接口一致的接口
    • ConcreteDecorator:向组件添加职责

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z6tVNljQ-1604838707233)(%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F.assets/image-20201031203458865.png)]

    对比适配器模式和装饰模式

    装饰模式:增强功能,不改变接口

    适配器模式:改变接口,不改变功能

    对比装饰模式和桥接模式

    1. 桥接模式桥接实现了两个不同的接口(抽象),作用也就与名字一样,只是为了桥接为另一种对象;

    2. 装饰模式是实现了同一个接口,可以像套娃一样无限扩展下去;

      共同点:都是把继承变组合,降低耦合。

    外观模式

    描述

    提供了一个统一的接口,用来访问子系统中的一群接口

    适用场合

    1.为复杂子系统提供一个简单接口,使子系统更加容易使用

    2.当需要构建层次结构的子系统时,使用外观模式定义每层的入口点。如果子系统间相互依赖,他们仅通过入口点进行通讯,简化了它们之间的依赖关系

    结构

    • Facade(门面角色):知道哪些子系统类负责处理请求,并将客户的请求代理给适当的子系统对象
    • Subsystem:子系统角色:实现子系统的功能,处理由Facade对象指派的任务,没有Facade的任何相关信息

    缺点

    1.增加了附加方法调用

    2.子系统中类的功能受到外观的限制

    3.封装组件接口改变导致外观跟着改变

    组合模式

    补充

    单一对象:键盘、鼠标、CPU、硬盘…

    组合对象:计算机、主机、主板…

    部件:单一对象和组合对象的统称

    组合对象既包括单一对象,也可以包括组合对象

    描述

    将对象组合成树形结构(部分/整体 的 层次结构),使用户对单一对象和组合对象使用一致性的接口

    适用场合

    1.表示对象的部分-整体层次结构

    2.忽略总体对象和单一对象的不同

    3.用户将统一使用组合结构的所有对象

    结构

    包含角色:

    • Component:为组合对象声明接口,用于访问和管理Component的子组件
    • Leaf:表示叶节点对象,没有子节点。定义图元对象的行为
    • Composite:定义复合部件的行为,存储子部件
    • Client:通过Component接口操纵组合部件的对象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7BTwwOhk-1604838707236)(%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F.assets/image-20201031210655675.png)]

    要点

    定义了包含基本对象和组合对象的类层次结构,用户使用Component类接口与组合结构中的对象进行交互。

    • 如果接收者是叶节点,直接处理请求
    • 如果接收者是Composite,将请求发给它的子部件

    和装饰模式的区别

    1.一定程度上,装饰模式是组合模式的一个特例

    2.装饰模式只能聚集一个对象,动态构建功能

    3.组合模式把对象组装为一个层次结构

    代理模式

    描述

    为其他对象提供一种代理以控制对这个对象的访问

    类型

    远程代理、虚拟代理、保护代理、智能引用代理…

    Protect Proxy

    控制对象的访问,可给不同用户提供不同级别的使用权限。在运行时对用户权限进行检查

    Cache Proxy

    为目标操作提供临时存储空间,以便多客户端共享

    Firewall Proxy

    保护目标,防止恶意用户接近

    Synchronization Proxy

    使多用户能同时使用一个对象而没有冲突

    结构

    包含角色:

    • Proxy(代理角色):保存一个对ConcreteSubject引用并提供一个与Subject相同的接口,这样代理就可以用来替代实体。控制对实体的存取、创建和删除。
    • Subject(抽象角色):定义ConcreteSubject和Proxy的公用接口
    • ConcreteSubject(真实角色):定义Subject的实现类
    • Client(客户端角色):维持一个对Subject的引用

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWDDbSa0-1604838707239)(%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F.assets/image-20201031212955362.png)]

    与装饰模式、适配器模式比较

    共同点

    1.都引入一个新的对象,含指向实际对象的引用

    2.请求和命令委托给实际对象执行

    区别

    1.代理模式使用实际对象相同接口,适配器转换接口

    享元模式

    未完待续…

    展开全文
  • C语言结构

    2020-11-22 20:51:03
    1、顺序结构 顺序结构的程序设计是最简单的,只要按照解决问题的顺序写出相应的语句就行,它的执行顺序是自上而下,依次执行。 例如;a = 3,b = 5,现交换a,b的值,这个问题就好像交换两个杯子水,这当然要用到第...

    1、顺序结构

    顺序结构的程序设计是最简单的,只要按照解决问题的顺序写出相应的语句就行,它的执行顺序是自上而下,依次执行。

    例如;a = 3,b = 5,现交换a,b的值,这个问题就好像交换两个杯子水,这当然要用到第三个杯子,假如第三个杯子是c,那么正确的程序为: c = a; a = b; b = c; 执行结果是a = 5,b = c = 3。

    如果改变其顺序,写成:a = b; c = a; b = c; 则执行结果就变成a = b = c = 5,不能达到预期的目的,初学者最容易犯这种错误。

    顺序结构可以独立使用构成一个简单的完整程序,常见的输入、计算,输出三步曲的程序就是顺序结构,例如计算圆的面积,其程序的语句顺序就是输入圆的半径r,计算s = 3.14159rr,输出圆的面积s。

    不过大多数情况下顺序结构都是作为程序的一部分,与其它结构一起构成一个复杂的程序,例如分支结构中的复合语句、循环结构中的循环体等。

    展开全文
  • 结构

    2018-10-21 10:13:44
    将不同种类型的数据有序地组合在一起,构造出一个新的数据类型,这种形式称为结构体。 结构体是多种类型组合的数据类型。 结构体变量的定义 先定义结构体类型,再定义结构体变量 一般形式:struct 结构体名 ...

    将不同种类型的数据有序地组合在一起,构造出一个新的数据类型,这种形式称为结构体。
    结构体是多种类型组合的数据类型。
    结构体变量的定义
    先定义结构体类型,再定义结构体变量
    一般形式:struct 结构体名
    {
    类型标识符 成员名;
    类型标识符 成员名;
    …………….
    };
    [struct] 结构体名 变量名表列
    定义结构体类型的同时定义结构体变量
    一般形式:struct 结构体名
    {
    类型标识符 成员名;
    类型标识符 成员名;
    …………….
    }变量名表列;
    直接定义结构体变量
    一般形式:struct
    {
    类型标识符 成员名;
    类型标识符 成员名;
    …………….
    }变量名表列;
    结构体类型与结构体变量概念不同
    类型:不分配内存; 变量:分配内存
    类型:不能赋值、存取、运算; 变量:可以
    结构体可嵌套
    结构体成员名与程序
    结构体变量的引用
    引用规则引用方式: 结构体变量名.成员名
    可以将一个结构体变量赋值给另一个结构体变量
    结构体类型变量的引用
    1、不能对结构体变量整体赋值或输出,只能分别对各个成员引用。
    2、嵌套的结构体变量必须逐层引用。
    3、结构体变量中的成员可以同一般变量一样进行运算。
    结构体变量的初始化
    形式一:struct 结构体名
    {
    类型标识符 成员名;
    类型标识符 成员名;
    …………….
    };
    struct 结构体名 结构体变量={初始数据};
    形式二:struct 结构体名
    {
    类型标识符 成员名;
    类型标识符 成员名;
    …………….
    }结构体变量={初始数据}
    形式三:struct
    {
    类型标识符 成员名;
    类型标识符 成员名;
    …………….
    }结构体变量={初始数据};
    关于结构类型变量的使用,说明以下几点:
    1、同类型的结构体变量之间可以直接赋值。这种赋值等同于各个成员的依次赋值。
    2、结构体变量不能直接进行输入输出,它的每一个成员能否直接进行输入输出,取决于其成员的类型,若是基本类型或是字符数组,则可以直接输入输出。
    3、结构体变量可以作为函数的参数,函数也可以返回结构体的值。当函数的形参与实参为结构体类型的变量时,这种结合方式属于值调用方式,即属于值传递。
    结构体数组
    结构体数组中的每个元素都是一个结构体类型的变量,其中包括该类型的各个成员。
    数组各元素在内存中连续存放
    3. 结构体数组应用举例
    定义一个结构体变量(包括:年、月、日),编写程序,要求输入年、月、日,程序能计算出该日在本年中是第几天。
    指向结构体变量的指针
    一个结构体变量的指针就是该变量所占据的内存段的起始地址。
    可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
    指针变量也可以用来指向结构体数组中的元素。
    指 针与内存动态分配
    通过使用new与delete单目运算符来实现动态变量的分配与撤消
    1)动态申请内存操作符 new
    使用格式:
    new <类型名> //动态变量
    new <类型名> ( <初值> )
    new <类型名> [ <元素个数> ] //动态数组

      功能:
      生成一个(或一批)所给类型的无名动态变量。
    

    结果值:
    成功:所生成变量类型的指针(首地址) ,指向新分配的内存。
    失败:0(NULL)
    以变量形式分配内存比较死板。有了new和delete,就可以实现一种动态分配内存的形式,即通过指针引用,而内存的分配和释放可以在程序的任何地方进行。
    int *pint; char *pchar; float *pfloat;
    pfloat = new float; //生成1个浮点型变量
    pchar = new char; //生成1个字符型变量
    pint = new int; //生成1个整型变量
    这些变量都没有名字。
    三个变量的地址分别存在指针pfloat,pchar 和pint,在程序中使用这三个变量时,全通过指针:
    *pchar = ‘A’;
    *pint = 5;
    *pfloat = 4.7;
    当不再需要这些变量时,可在程序的任何地点释放掉它们:
    delete pchar; delete pint; delete pfloat;
    这里释放的是动态的(char,int,float)变量,而不是指针变量(pchar, pint, pfloat)。
    在使用动态变量时应注意的是,要保护动态变量的地址。
    例如在执行
    pi=new int; 之后,不要轻易地冲掉指针pi中的值,假如执行了pi=&a;语句之后,再释放原来生成的动态变量:
    delete pi; 已经达不到原来的目标了。
    这将造成内存的泄漏,如果过多的话,将占用大量系统内存资源,造成内存资源的浪费。
    结构体类型数据作为函数参数
    将一个结构体变量中的数据传递给另一个函数,有下列方法:
    (1) 用结构体变量名作参数。一般较少用这种方法。
    (2) 用指向结构体变量的指针作实参,将结构体变量的地址传给形参。

    展开全文
  • 结构

    2019-05-28 22:00:00
    定义结构:定义结构,必须使用struct语句。struct 语句定义了一个包含多个成员的新的数据类型。访问结构体里面的成员的时候我们用 . 这个成员访问符。 1 struct type_name //关键字struct 2 { 3 type1 name1; /...
  • 数据结构:八大数据结构分类

    万次阅读 多人点赞 2018-09-05 18:23:28
    数据结构分类 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。 常用的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等,如图所示: 每一种数据结构都...
  • 数据结构分别为逻辑结构、(存储)物理结构和数据的运算三个部分。 为什么要学数据结构? 首先,因为数据结构作为计算机专业的专业基础课程,是计算机考研的必考科目之一,如果打算报考计算机专业的研究生,你...
  • 数据结构和算法视频教程

    万人学习 2015-01-29 08:45:17
    数据结构、算法视频培训课程,该教程主要是介绍在游戏开发中经常使用的数据结构,例如数组,链表,栈,队列,二叉树,递归等重要知识点讲解以及将它们里灵活的运用到算法里面。
  • 一、顺序查找:顾名思义,就是从头开始一直找到结束,找到了就返回,否则继续找,找完了没找到就返回-1 普通版 static int SequenceFind(int[] arr,int value) { for (int i = 0; i < arr.Length-1;...
  • 结构化数据、半结构化数据和非结构化数据

    万次阅读 多人点赞 2017-02-04 18:23:03
    结构化数据、半结构化数据和非结构化数据结构化数据结构化的数据是指可以使用关系型数据库表示和存储,表现为二维形式的数据。一般特点是:数据以行为单位,一行数据表示一个实体的信息,每一行数据的属性是相同的。...
  • YOLO v3网络结构分析

    万次阅读 多人点赞 2018-07-26 12:07:09
    相信阅读了YOLO v3论文的小伙伴们会发现为什么这次的论文篇幅这么少?除去参考文献就四面?Excuse me?我是下了篇假文献吧。读完后感觉内容确实不多,而且总感觉写的不够细致,很多地方都比较模糊,可能是作者想让...
  • 为什么要学数据结构

    万次阅读 多人点赞 2019-11-19 09:45:23
    一、前言 在可视化化程序设计的今天,借助于...1) 能够熟练地选择和设计各种数据结构和算法 2) 至少要能够熟练地掌握一门程序设计语言 3) 熟知所涉及的相关应用领域的知识 其中,后两个条件比较容易实现,而第一个...
  • 小猪的数据结构辅助教程——1.数据结构与算法绪论标签(空格分隔): 数据结构本节学习路线图与学习要点学习要点: 1.了解数据结构的相关概念 2.了解算法的相关概念 3.熟悉时间复杂度的计算 4.了解空间复杂度...
  • 数据结构

    千次阅读 多人点赞 2018-10-06 17:40:36
    数据结构 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或者多种特定关系的数据元素集合。通常情况下,精心选择的数据结构可以带来更高效的运行或者存储效率。数据结构往往同高效的检索算法...
  • Mac 生成项目目录树形结构

    万次阅读 2019-08-05 22:36:25
    经常看到别人在博客,教程上输出优美的目录结构,是不是自己也很想来一个~ 开始 mac 下安装 tree 插件 # 安装 brew install tree # 安装后在文件夹内执行 tree -a 常用命令 tree -d 只显示文件夹; tree -l n ...
  • 数据结构与算法思维导图
  • 小猪的数据结构辅助教程——前言

    万次阅读 多人点赞 2015-12-08 21:22:38
    面试给人上了一课,突然感觉数据结构很重要;还有,帮助后来者,刚接触数据结构的 童鞋们一点点方向,不至于学完什么都不知道!大部分学校采用的教程应该是严蔚敏老师的 《数据结构(C语言版)》吧,而讲数据结构课程...
  • R语言:结构方程模型、潜变量分析

    万次阅读 2019-06-13 08:46:15
    对于熟悉线性回归拟合结构方程模型的分析师来说,在R环境中,拟合结构方程模型涉及学习新的建模语法,新的绘图语法以及通常是新的数据输入方法。然而,拟合结构方程模型可以成为分析师工具箱中的强大工具。 设置 ...
  • C语言switch选择结构

    千次阅读 多人点赞 2019-06-10 10:40:10
    程序设计中选择结构的第二大语句就是:switch语句。switch和if—else if一样都可以做多分支选择,但是switch语句的思想是把程序所有可能出现的值 的情况,列出一个情况表,根据所输入的值判断与情况表中的的那种情况...

空空如也

1 2 3 4 5 ... 20
收藏数 5,535,578
精华内容 2,214,231
关键字:

结构