Lập Trình C++ B6: C++ Cấu Trúc Dữ Liệu

Chào mừng các bạn đến với chủ đề lập trình c++ cơ bản.

Hôm nay chúng ta cùng tìm hiểu về Cấu trúc dữ liệu trong c++

– Là kỹ thuật được sử dụng để thay thế cho những hạn chế của mảng.

– Nếu như mảng chỉ có thể khai báo một nhóm các đối tượng cùng kiểu dữ liệu,

thì struct lại có thể cho phép người dùng định nghĩa một nhóm các biến có kiểu dữ liệu khác nhau.

Giả sử bài toán lập trình là bài toán về quản lý thông tin của một con người, ví dụ là một sinh viên.

Thông tin của một sinh viên thường là như sau.
char * name_  // tên sinh viên
bool  sex_      // giới tính chỉ có 2 loại, nam hoặc nữ.
int age_         // tuổi là số nguyên
float mark_   //  Điểm số học tập, là một số thực.

Trong trường hợp này, mảng không thể nào đáp ứng được và do đó người ta sử dụng struct.

1.Cú pháp khai báo cấu trúc dữ liệu.

struct  tên kiểu
{
    //các thuộc tính
};

Ví dụ tôi sử dụng struct để định nghĩa một đối tượng nhân viên công ty như sau

//phattrienphanmem123az
#include <iostream>
#include <conio.h>
#include <string>

enum PosType
{
    POS_NONE = 0,
    POS_FRESHER = 1,
    POS_JUNIOR = 2,
    POS_SENIOR = 3,
};

enum SexType
{
    S_MAN = 0,
    S_FEMALE = 1,
};
struct Staff
{
    std::string s_name;
    unsigned int s_age;
    int s_sex;
    int s_pos;
};

int main()
{
    Staff sMan;
    sMan.s_name = (std::string)"Hoang Van A";
    sMan.s_age = 25;
    sMan.s_sex = SexType::S_MAN;
    sMan.s_pos = PosType::POS_JUNIOR;

    _getch();
    return 0;
}

 

+ Trong ví dụ trê, Staff là một kiểu dữ liệu đại diện cho một đối tượng là nhân viên công ty.

+ Staff có 4 trường dữ liệu cơ bản là : tên, tuổi, giới tính, cấp bậc.

Vì Staff được coi như là một kiểu dữ liệu, nên có thể sử dụng con trỏ.

 

2. Một vài tính chất của cấu trúc dữ liệu trong c++.

– Khi khai báo một struct với một tên kiểu đã xác định, người ta có thể sử dụng một định danh khác đại diện.

ví dụ như sau
struct Person
{
      // Member
}  PERSON;

Như vậy khi sử dụng, chúng ta có thể dùng PERSON để khai báo như một kiểu dữ liệu mới đại diện cho Person.

– Cấu trúc có thể khai báo lồng nhau, nghĩa là một trường trong cấu trúc có thể có kiểu dữ liệu là một cấu trúc khác.
struct A
{
      B b_;   // B là một cấu trúc khác nào đó.
}
– Một biến khi được khai báo kiểu struct thì nó sẽ được phân bổ vùng nhớ mà các thực hiện của nó được sắp xếp liên tục
theo thứ tự của việc khai báo.
– Cấu trúc có thể được hiểu như một kiểu dữ liệu, do đó có thể thực hiện được phép gán chúng cho nhau. A = B

– Các trường dữ liệu trong struct được mặc định là quyền truy nhập public.

3. Ứng Dụng.

Trong thực tế, struct cũng được sử dụng khá phổ biến, được coi như kỹ thuật xây dựng các kiểu dữ liệu có tính chất nhóm.

Ví dụ trong lập trình đồ họa. Một điểm trong không gian được định nghĩa bởi 3 giá trị tọa độ x,y,z

Vậy thì có thể định nghĩa một struct kiểu Point với 3 trường dữ liệu x,y,z

Một đối tượng màu sắc thể hiện bởi 3 giá trị  red, green, blue.

Vậy thì có thể định nghĩa một struct Color với 3 trường dữ liệu: int red, int green, int blue

Và rất nhiều các kiểu dữ liệu khác mà bạn có thể sử dụng struct để thể hiện.

4. Thực Hành.

Sử dụng struct để định nghĩa một lớp point2d với 2 tọa độ x,y

Sau đó nhập tọa độ 3 điểm p1, p2, p3 đại diện cho 1 tam giác.

Kiểm tra xem đó có phải là tam giác vuông, tam giác cân, hay tam giác đều.

Code Sample

//phattrienphanmem123az.com
#include <iostream>
#include <conio.h>
#include <string>
#include <math.h>

#define EXP 0.00001

struct Point2D
{
    float x;
    float y;
};

float GetDistance(const Point2D& p1, const Point2D& p2)
{
    float xSub = p2.x - p1.x;
    float ySub = p2.y - p1.y;
    float d = sqrt(xSub*xSub + ySub*ySub);
    return d;
}

bool CheckRightTriangle(const Point2D& p1, const Point2D& p2, const Point2D& p3)
{
    float d1 = GetDistance(p1, p2);
    float d2 = GetDistance(p2, p3);
    float d3 = GetDistance(p3, p1);

    float dd1 = d1*d1;
    float dd2 = d2*d2;
    float dd3 = d3*d3;

    if (fabs(dd1 + dd2 - dd3) <= EXP)
    {
        return true;
    }

    if (fabs(dd2 + dd3 - dd1) <= EXP)
    {
        return true;
    }

    if (fabs(dd3 + dd1 - dd2) <= EXP)
    {
        return true;
    }

    return false;
}

bool CheckEquilateralTriangle(const Point2D& p1, const Point2D& p2, const Point2D& p3)
{
    float d1 = GetDistance(p1, p2);
    float d2 = GetDistance(p2, p3);
    float d3 = GetDistance(p3, p1);

    float r1 = fabs(d1 - d2);
    float r2 = fabs(d2 - d3);
    float r3 = fabs(d3 - d1);
    if (r1 <= EXP && r2 < EXP && r3 < EXP)
    {
        return true;
    }

    return false;
}

bool CheckIsoscelesTriangle(const Point2D& p1, const Point2D& p2, const Point2D& p3)
{
    float d1 = GetDistance(p1, p2);
    float d2 = GetDistance(p2, p3);
    float d3 = GetDistance(p3, p1);

    float r1 = fabs(d1 - d2);
    float r2 = fabs(d2 - d3);
    float r3 = fabs(d3 - d1);
    if (r1 <= EXP || r2 < EXP || r3 < EXP)
    {
        return true;
    }
    return false;
}

int main()
{
    Point2D p1 = { 0.0, 0.0 };
    Point2D p2 = { 0.0, 100.0 };
    Point2D p3 = { 100.0, 0.0 };

    bool ret = CheckEquilateralTriangle(p1, p2, p3);
    if (ret == false)
    {
        ret = CheckIsoscelesTriangle(p1, p2, p3);
        if (ret == true)
        {
            std::cout << "p1,p2,p3 is Equilateral Triangle \n";
        }

        ret = CheckRightTriangle(p1, p2, p3);
        if (ret == true)
        {
            std::cout << "p1,p2,p3 is Right Triangle \n";
        }
    }
    else
    {
        std::cout << "p1,p2,p3 is Equilateral Triangle \n";
    }

    _getch();
    return 0;
}

 

Ok.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.