Xem thêm

Cấu Trúc C++

Huy Erick
Giới thiệu Cấu trúc là một tập hợp các biến của các kiểu dữ liệu khác nhau dưới một tên duy nhất. Nó tương tự như một lớp (class) ở chỗ, cả hai đều chứa...

Giới thiệu

Cấu trúc là một tập hợp các biến của các kiểu dữ liệu khác nhau dưới một tên duy nhất. Nó tương tự như một lớp (class) ở chỗ, cả hai đều chứa một tập hợp dữ liệu thuộc các kiểu dữ liệu khác nhau.

Cấu trúc C++

Ví dụ: Khi bạn muốn lưu trữ một số thông tin về một người như: tên, số căn cước, và mức lương của người đó. Bạn có thể dễ dàng tạo các biến khác nhau: name, citNo, salary để lưu trữ riêng lẻ các thông tin này.

Tuy nhiên, trong tương lai, khi bạn muốn lưu trữ thông tin của nhiều người hơn. Bây giờ, bạn cần tạo những biến khác nhau cho mỗi thông tin của mỗi người: name1, citNo1, salary1, name2, citNo2, salary2.

Bạn có thể dễ dàng hình dung ra code sẽ nhiều và lộn xộn như thế nào. Ngoài ra, vì không tồn tại mối quan hệ giữa các biến (thông tin) nên nhiệm vụ này sẽ lại càng khó khăn.

Một cách giải quyết tốt hơn đó là tạo một bộ sưu tập tất cả thông tin liên quan dưới một tên duy nhất là Person và sử dụng nó cho mọi người. Bây giờ, code trông sẽ gọn gàng hơn, dễ đọc và hiệu quả hơn.

Tập hợp tất cả các thông tin liên quan dưới một tên riêng Person gọi là một cấu trúc.

Cách khai báo cấu trúc trong lập trình C++

Từ khóa struct xác định một kiểu cấu trúc theo sau là một định danh (tên của cấu trúc).

Khi đó, bên trong dấu ngoặc nhọn, bạn có thể khai báo một hoặc nhiều thành phần (khai báo các biến bên trong dấu ngoặc nhọn) của cấu trúc đó. Ví dụ:

struct Person {  char name[50];  int age;  float salary; };

Đây là cấu trúc Person được xác định với ba thành phần: name, age và salary.

Khi một cấu trúc được tạo, không có bộ nhớ nào được cấp phát.

Định nghĩa cấu trúc chỉ là bản thiết kế để tạo các biến. Bạn có thể hình dung nó như một kiểu dữ liệu. Khi bạn xác định một số nguyên như sau:

int foo;

Int chỉ định rằng, biến foo chỉ có thể chứa phần tử nguyên. Tương tự, định nghĩa cấu trúc chỉ xác định thuộc tính mà một biến cấu trúc giữ khi nó được định nghĩa.

Lưu ý: Hãy nhớ kết thúc khai báo bằng dấu chấm phẩy (;)

Cách xác định biến cấu trúc

Khi bạn khai báo cấu trúc Person như ở trên. Bạn có thể xác định biến cấu trúc như sau:

Person bill;

Ở đây, biến cấu trúc được xác định có cấu trúc kiểu person.

Chỉ khi biến cấu trúc được xác định, bộ nhớ cần thiết mới được trình biên dịch cấp phát.

Nếu bạn có hệ thống 32 bit hoặc 64 bit, bộ nhớ của float là 4 byte, bộ nhớ của int là 4 byte và bộ nhớ của char là 1 byte.

Do đó, 58 byte bộ nhớ sẽ được cấp phát cho biến cấu trúc bill.

Cách truy cập thành phần của một cấu trúc

Các thành phần của biến cấu trúc được truy cập bằng cách sử dụng toán tử dấu chấm (.)

Giả sử, bạn muốn truy cập độ tuổi của biến cấu trúc bill và gán 50 cho nó. Bạn có thể thực hiện bằng cách sử dụng code sau:

bill.age = 50;

Cấu trúc và hàm trong C++

Các biến cấu trúc có thể được truyền cho một hàm và được trả về theo cách tương tự như các đối số thông thường.

Truyền cấu trúc cho hàm trong C++ Một biến cấu trúc có thể được truyền cho một hàm theo cách tương tự như đối số bình thường. Hãy xem ví dụ bên dưới:

struct Person {  char name[50];  int age;  float salary; };  void displayData(Person); // Function declaration  int main() {  Person p;   cout << “Enter Full name: “;  cin.get(p.name, 50);  cout << “Enter age: “;  cin >> p.age;  cout << “Enter salary: “;  cin >> p.salary;   // Function call with structure variable as an argument  displayData(p);   return 0; }  void displayData(Person p) {  cout << “\nDisplaying Information.” << endl;  cout << “Name: “ << p.name << endl;  cout << “Age: “ << p.age << endl;  cout << “Salary: “ << p.salary; }

Đầu ra Enter Full name: Magdalena Dankova Enter age: 27 Enter salary: 1024.4

Displaying Information. Name: Magdalena Dankova Age: 27 Salary: 1024.4

Ở đây, cấu trúc Person được khai báo có ba thành phần: name, age và salary. Bên trong hàm main(), một biến cấu trúc p1 được xác định. Sau đó, người dùng được yêu cầu nhập thông tin và dữ liệu do người dùng nhập sẽ được hiển thị.

Trả về cấu trúc từ hàm

#include  using namespace std;  struct Person {  char name[50];  int age;  float salary; };  Person getData(Person); void displayData(Person);  int main() {  Person p;   p = getData(p);  displayData(p);   return 0; }  Person getData(Person p) {  cout << “Enter Full name: “;  cin.get(p.name, 50);   cout << “Enter age: “;  cin >> p.age;   cout << “Enter salary: “;  cin >> p.salary;   return p; }  void displayData(Person p) {  cout << “\nDisplaying Information.” << endl;  cout << “Name: “ << p.name << endl;  cout << “Age: “ << p.age << endl;  cout << “Salary: “ << p.salary; }

Đầu ra: Enter Full name: Bill Jobs Enter age: 55 Enter salary: 34233.4

Displaying Information. Name: Bill Jobs Age: 55 Salary: 34233.4

Trong chương trình này, biến cấu trúc p của kiểu cấu trúc person được xác định dưới hàm main(). Biến cấu trúc p được truyền vào hàm getData() để nhận đầu vào từ người dùng sau đó được trả về hàm chính. p = getData(p);

Lưu ý: Giá trị của tất cả các thành phần của một biến cấu trúc có thể được gán cho một cấu trúc khác, bằng cách sử dụng toán tử gán = nếu cả hai biến cấu trúc cùng kiểu. Bạn không cần phải chỉ định từng thành phần theo cách thủ công.

Sau đó, biến cấu trúc p được chuyển đến hàm displayData(), cũng là hàm hiển thị thông tin.

Từ con trỏ đến cấu trúc trong C++ Một biến con trỏ có thể được tạo ra không chỉ cho các kiểu gốc (như int, float, double v.v...) mà còn có thể được tạo cho các kiểu do người dùng xác định như cấu trúc.

Nếu bạn không biết con trỏ là gì hãy xem con trỏ trong C++.

Đây là cách tạo con trỏ cho các cấu trúc:

#include  using namespace std;  struct temp {  int i;  float f; };  int main() {  temp *ptr;  return 0; }

Chương trình này tạo con trỏ ptr cho kiểu cấu trúc temp.

#include  using namespace std;  struct Distance {  int feet;  float inch; };  int main() {  Distance *ptr, d;   ptr = &d;   cout << “Enter feet: “;  cin >> (*ptr).feet;  cout << “Enter inch: “;  cin >> (*ptr).inch;   cout << “Displaying information.” << endl;  cout << “Distance = “ << (*ptr).feet << ” feet “ << (*ptr).inch << ” inches”;   return 0; }

Đầu ra: Enter feet: 4 Enter inch: 3.5

Displaying information. Distance = 4 feet 3.5 inches

Trong chương trình này, một biến con trỏ ptr và biến bình thường d của cấu trúc distance được xác định. Địa chỉ của biến d được lưu trữ trong biến con trỏ, tức là ptr đang trỏ tới biến d. Sau đó, hàm thành viên của biên d được truy cập bằng con trỏ.

Lưu ý: vì con trỏ ptr đang trỏ đến biến d trong chương trình này, (ptr).inch và d.inch chính xác cùng một ô. Tương tự. (ptr).feet và d.feet là cùng một ô.

Cú pháp để truy cập hàm thành viên bằng cách sử dụng con trỏ là không tốt nhưng có một ký hiệu thay thế phổ biến hơn là ->

ptr->feet is same as (ptr).feet ptr->inch is same as (ptr).inch

Liệt kê là một kiểu dữ liệu do người dùng xác định bao gồm các hằng số tích phân. Trong đó từ khóa enum được sử dụng để xác định một kiểu liệt kê.

enum season { spring, summer, autumn, winter };

Ở đây, tên của phép liệt kê là season. Và spring, summer, autumn và winter là các biến của season.

Theo mặc định, spring là 0, summer là 1, v.v...nhưng bạn vẫn có thể thay đổi giá trị mặc định của phần tử trong enum khi khai báo (nếu cần).

enum season { spring = 0, summer = 4, autumn = 8, winter = 12 };

4.1. Khai báo kiểu liệt kê

Khi bạn tạo kiểu liệt kê, chỉ có bản thiết kế cho biến được tạo. Đây là cách bạn có thể tạo các biến kiểu enum.

enum boolean { false, true };

// inside function enum boolean check;

Ở đây, biến check của kiểu enum boolean được tạo.

Cũng có cách khác để khai báo biến check bằng cách sử dụng cú pháp syntax:

enum boolean { false, true } check;

Ví dụ 1: Kiểu liệt kê

using namespace std;

enum week { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };

int main() { week today; today = Wednesday; cout << “Day “ << today+1; return 0; }

Đầu ra Day 4

Ví dụ 2: Thay đổi giá trị mặc định của Enums

using namespace std;

enum seasons { spring = 34, summer = 4, autumn = 9, winter = 32};

int main() {

seasons s;

s = summer; cout << “Summer = “ << s << endl;

return 0; }

Đầu ra Summer = 4

Trong chương trình này, một biến Enum seasons được xác định với giá trị mặc định khác nhau.

Các giá trị này được sử dụng để đại diện cho mùa của năm.

Tết Trung Thu

4.2. Tại sao enums được sử dụng trong lập trình C++

Một biến enum chỉ nhận một giá trị trong số nhiều giá trị có thể có. Ví dụ bên dưới sẽ chứng minh điều đó:

using namespace std;

enum suit { club = 0, diamonds = 10, hearts = 20, spades = 3 } card;

int main() { card = club; cout << “Size of enum variable “ << sizeof(card) << ” bytes.”; return 0; }

Đầu ra Size of enum variable 4 bytes.

Đó chính là vì kích thước của một số nguyên là 4 byte, làm cho enum trở thành một lựa chọn tốt để làm việc với các flag.

Bạn có thể hoàn thành tác vụ tương tự bằng cách sử dụng cấu trúc C++. Tuy nhiên, làm với enums sẽ mang lại cho bạn hiệu quả và linh hoạt hơn.

4.3. Cách sử dụng enums cho flag

Hãy xem một ví dụ:

enum designFlags { ITALICS = 1, BOLD = 2, UNDERLINE = 4 } button;

Giả sử bạn đang thiết kế một nút cho ứng dụng Windows. Bạn có thể đặt flag ITALICS, BOLD và UNDERLINE để làm việc với văn bản.

Có một lý do cho câu hỏi tại sao tất cả các hằng số tích phân là lũy thừa của 2 trong các mã giả trên.

// In binary

ITALICS = 00000001 BOLD = 00000010 UNDERLINE = 00000100

Vì hằng số tích phân là lũy thừa của 2, bạn có thể kết hợp hai hoặc nhiều flag cùng một lúc mà không chồng chéo bằng cách sử dụng bitwise OR | operator. Nó cho phép bạn chọn 2 hoặc nhiều flag cùng một lúc. Ví dụ:

using namespace std;

enum designFlags { BOLD = 1, ITALICS = 2, UNDERLINE = 4 };

int main() { int myDesign = BOLD | UNDERLINE;

// 00000001 // | 00000100 // ___ // 00000101

cout << myDesign;

return 0; }

Đầu ra 5

Khi đầu ra là 5, bạn luôn biết rằng BOLD và UNDERLINE được sử dụng.

Ngoài ra, bạn có thể thêm flag theo nhu cầu của mình.

if (myDesign & ITALICS) { // code for italics }

Ở đây, tôi đã thêm ITALICS vào thiết kế của mình. Lưu ý rằng chỉ code cho ITALICS được viết bên trong câu lệnh if.

Bạn có thể hoàn thành hầu hết mọi thứ trong lập trình C++ mà không sử dụng phép liệt kê. Tuy nhiên, chúng có thể rất tiện dụng trong một số trường hợp nhất định. Nó thể hiện sự khác biệt giữa những lập trình viên xuất sắc với những lập trình viên giỏi.

1