Một biến con trỏ không chỉ lưu trữ địa chỉ của các biến có kiểu dữ liệu cơ bản như int, float, double,… Mà còn có thể trỏ tới kiểu dữ liệu do người dùng định nghĩa như kiểu dữ liệu cấu trúc (struct).
1. Địa chỉ của biến cấu trúc (struct)
Chương trình C++ in địa chỉ của biến cấu trúc
#include <iostream>
using namespace std;
struct STUDENT
{
string id;
string name;
string birthday;
bool gender;
float math, physics, chemistry;
};
int main() {
STUDENT sv1;
cout<<"Address of struct variable sv1:"<<&sv1<<endl;
cout<<"Address of member variables of sv1 in order id, name, birthday, gender, math, physics, chemistry:"<<endl;
cout<<&sv1.id<<" "<<&sv1.name<<" "<<&sv1.birthday<<" "<<&sv1.gender<<" "<<&sv1.math<<" "<<&sv1.physics<<" "<<&sv1.chemistry<<endl;
system("pause");
}
Kết quả trên hệ thống 32 bit
Address of struct variable sv1: 00FDFBE0
Address of member variables of sv1 in order id, name, birthday, gender, math, physics, chemistry:
00FDFBE0 00FDFC00 00FDFC20 00FDFC40 00FDFC44 00FDFC48 00FDFC4C
Đổi địa chỉ qua hệ cơ số 10
Address of struct variable sv1:16645088
Address of member variables of sv1 in order id, name, birthday, gender, math, physics, chemistry:
16645088 16645120 16645152 16645184 16645188 16645192 16645196
Dễ thấy, địa chỉ của biến cấu trúc STUDENT sv1 (&sv1) có cùng địa chỉ với biến thành viên đầu tiên của struct là id (&id). Các biến thành viên trong struct cũng được cấp phát dãy các ô nhớ liên tục trên bộ nhớ.
2. Con trỏ và cấu trúc (struct)
Con trỏ trỏ đến biến cấu trúc
Có thể sử dụng một biến con trỏ để lưu trữ địa chỉ của biến cấu trúc. Bản chất là biến con trỏ lưu trữ địa chỉ của biến thành viên đầu tiên của cấu trúc.
Lưu ý: Biến con trỏ phải có kiểu dữ liệu là kiểu dữ liệu cấu trúc mà nó trỏ đến.
struct STUDENT
{
string id;
string name;
string birthday;
bool gender;
float math, physics, chemistry;
};
STUDENT sv1 = {"01","Nguyen Van A", "01/02/2001", 0, 5.6, 9.8, 7.5};
STUDENT *psv;
psv = &sv1;
Sử dụng con trỏ để truy xuất các thành viên trong cấu trúc
Có 2 cách để truy xuất các thành viên trong cấu trúc thông qua con trỏ:
Cách 1: <tên biến con trỏ cấu trúc>-><tên thành phần>
Cách 2: (*<tên biến con trỏ cấu trúc>).<tên thành phần>
struct STUDENT
{
string id;
string name;
string birthday;
bool gender;
float math, physics, chemistry;
};
STUDENT sv1 = {"01","Nguyen Van A", "01/02/2001", 0, 5.6, 9.8, 7.5};
STUDENT *psv;
psv = &sv1;
sv1.id = "100"; sv1.math = 8.0;
psv->name = "Nguyen Van B";psv->physics = 9.5;
(*psv).chemistry = 9.9; (*psv).birthday = "25/01/2001";
Nhập giá trị cho các thành viên của cấu trúc thông qua con trỏ
#include <iostream>
#include <string>
using namespace std;
struct STUDENT
{
string id;
string name;
string birthday;
bool gender;
float math, physics, chemistry;
};
int main() {
STUDENT sv1;
STUDENT *psv;
psv = &sv1;
cout<<"input student"<<endl;
cout<<"id:";getline(cin, psv->id);
cout<<"name:";getline(cin, psv->name);
cout<<"birthday:";getline(cin, psv->birthday);
cout<<"gender:";cin>>psv->gender;
cout<<"math:";cin>>psv->math;
cout<<"physics:";cin>>psv->physics;
cout<<"chemistry:";cin>>psv->chemistry;
cout<<endl<<"output student"<<endl;
cout<<"id:"<<(*psv).id<<endl;
cout<<"name:"<<(*psv).name<<endl;
cout<<"birthday:"<<(*psv).birthday<<endl;
cout<<"gender:"<<(*psv).gender<<endl;
cout<<"math:"<<(*psv).math<<endl;
cout<<"physics:"<<(*psv).physics<<endl;
cout<<"chemistry:"<<(*psv).chemistry<<endl;
system("pause");
}
Kết quả
input student
id:01
name:Nguyen Van A
birthday:01/02/2001
gender:0
math:5.8
physics:9.8
chemistry:5.7
output student
id:01
name:Nguyen Van A
birthday:01/02/2001
gender:0
math:5.8
physics:9.8
chemistry:5.7
3. Thành viên của cấu trúc là con trỏ
Thành viên của một cấu trúc có thể là con trỏ. Trong một số trường hợp đặc biệt, một cấu trúc chứa một thành viên con trỏ mà con trỏ đó trỏ tới chính cấu trúc đó. Ví dụ:
struct PHIM
{
string TuaPhim;
int NamSanXuat;
PHIM *pNextPhim;
};
Kiểu cấu trúc PHIM gồm: thành viên TuaPhim có kiểu chuỗi, thành viên NamSanXuat kiểu số nguyên và một con trỏ pNextPhim.
Thành viên pNextPhim là con trỏ trỏ tới chính kiểu cấu trúc PHIM chứa nó. Ta gọi đó là “cấu trúc tự trỏ”. Cấu trúc đặc biệt này có thể được liên kết với nhau để hình thành các cấu trúc dữ liệu hữu ích như danh sách liên kết, hàng đợi, ngăn xếp và cây.