Ví dụ 5: Viết chương trình khai báo biến x và xem địa chỉ lưu trữ của giá trị biến x.
KHOA CƠNG NGHỆ THƠNG TIN Trang 126 Kết quả in ra màn hình
Hình 108: Kết quả chương trình chạy ví dụ 5 mục 6.2.2.1 Ví dụ 6: Viết hàm sử dụng con trỏ hốn đổi 2 số nguyên.
Hình 109: Màn hình giải ví dụ 6 mục 6.2.2.1
Kết quả in ra màn hình
KHOA CƠNG NGHỆ THƠNG TIN Trang 127 int *ptr;
int arr[10]; ptr = &arr[0];
Như ở trên, con trỏ chứa địa chỉ của phần tử đầu tiên của mảng. C cung cấp một cách khác để trỏ tới phần tử đầu tiên của mảng, ptr = arr;
Ghi chú: Cần nhớ rằng tên của một con trỏ mảng mà khơng cĩ kèm chỉ số thì nĩ là một con trỏ trỏ tới phần tử đầu tiên của mảng.
Quy tắc biến đổi mảng:
-Nếu arr1 là một mảng, thì biểu thức arr1 + 1 sẽ cho địa chỉ của phần tử thứ 2 trong mảng.
-Sử dụng tốn tử gián tiếp * đứng phía trước tên biến để lấy giá trị được chứa trong địa chỉ này. Như vậy *(arr1 + 1) sẽ cho giá trị được lưu trong phần tử thứ 2 của mảng.
-Vì thế chúng ta cĩ thể sử dụng quy tắc biến đổi này để chuyển đổi bất cứ mảng nào được tham chiếu tới bằng các biểu thức với con trỏ tương đương.
arr1[0] tương đương với *(arr1 + 0) arr1[1] tương đương với *(arr1 + 1) arr1[2] tương đương với *(arr1 + 2)
Lưu ý: Nếu khơng cĩ cặp ngoặc đơn thì phép tốn *arr1 + 1 sẽ cho một kết quả khác hồn tồn.
KHOA CƠNG NGHỆ THƠNG TIN Trang 128
Hình 111: Màn hình giải ví dụ 7 mục 6.2.2.2
Kết quả in ra màn hình
Hình 112: Kết quả chương trình chạy ví dụ 7 mục 6.2.2.2
Ví dụ 8: Viết chương trình nhập vào số phần tử của mảng, in ra danh sách mảng và tìm số lớn nhất trong mảng.
KHOA CƠNG NGHỆ THƠNG TIN Trang 129
Hình 113: Màn hình giải ví dụ 8 mục 6.2.2.2
KHOA CƠNG NGHỆ THƠNG TIN Trang 130
Hình 114: Kết quả chương trình chạy ví dụ 8 mục 6.2.2.2
6.2.2.3 Con trỏ và chuỗi
Do chuỗi ký tự bản chất cũng là mảng các ký tự nên phần này nĩ cũng xem như mảng 1 chiều.
Ví dụ 9: Viết chương trình xuất thơng báo hỏi tên và trả lời, in tên vừa nhập cho người dùng xem.
Hình 115: Màn hình giải ví dụ 9 mục 6.2.2.3
KHOA CƠNG NGHỆ THƠNG TIN Trang 131
Ví dụ 10: Viết chương trình khởi tạo danh sách mảng các tháng (từ tháng 1 đến tháng 12), khi người dùng nhập vào tháng nào sẽ xuất tháng đĩ cho người dùng xem.
Hình 117: Màn hình giải ví dụ 10 mục 6.2.2.3
Kết quả in ra màn hình
Hình 118: Kết quả chương trình chạy ví dụ 10 mục 6.2.2.3
Ví dụ 11: Viết chương trình nhập xuất mảng 2 chiều kiểu số thực dùng con trỏ để truy xuất mảng.
KHOA CƠNG NGHỆ THƠNG TIN Trang 132
Hình 119: Màn hình giải ví dụ 11 mục 6.2.2.3
KHOA CƠNG NGHỆ THƠNG TIN Trang 133
Hình 120: Kết quả chương trình chạy ví dụ 11 mục 6.2.2.3
6.2.2.4 Con trỏ trỏ đến con trỏ
Trong lập trình C++ cho phép sử dụng các con trỏ trỏ tới các con trỏ khác giống như là trỏ tới dữ liệu. Để làm việc đĩ chúng ta chỉ cần thêm một dấu sao (*) cho mỗi mức tham chiếu. char a; char * b; char ** c; a = 'z'; b = &a; c = &b;
giả sử rằng a,b,c được lưu ở các ơ nhớ 7230, 8092 and 10502, ta cĩ thể mơ tả đoạn mã trên như sau:
KHOA CƠNG NGHỆ THƠNG TIN Trang 134
c là một biến cĩ kiểu (char **) mang giá trị 8092*c là một biến cĩ kiểu (char*) mang giá trị 7230**c là một biến cĩ kiểu (char) mang giá trị 'z'
Ví dụ 12:
Hình 121: Màn hình giải ví dụ 12 mục 6.2.2.4
KHOA CƠNG NGHỆ THƠNG TIN Trang 135 4. Viết chương trình tìm phần tử cĩ giá trị nhỏ nhất và lớn nhất trong mảng một
chiều.
5. Viết chương trình tìm phần tử cĩ giá trị nhỏ nhất và lớn nhất trong mảng hai
KHOA CƠNG NGHỆ THƠNG TIN Trang 136
Bài 7 :
KIỂUDỮ LIỆU NGƯỜI DÙNG TỰ ĐỊNH NGHĨA
7.1 Mục tiêu
Sau khi học xong học sinh sẽ trình bày và vận dụng được các kỹ năng cơ bản sau: - Ý nghĩa, cách khai struct, emum
- Nhập, xuất struct. - Khởi tạo struct, enum
- Một số kỹ thuật thao tác trên struct, enum - Dùng struct tham số cho hàm.
7.2 Nội dung
7.2.1 Kiểu cấu trúc (Struct)
7.2.1.1 Khái niệm
Struct là một dạng cấu trúc được dùng để định nghĩa một tập hợp các biến dưới dạng một tên đơn giản.
Kiểu cấu trúc giúp các lập trình viên trong việc khai báo các thành phần là các kiểu dữ liệu khác nhau.
7.2.1.2 Khai báo kiểu structCú pháp: Cú pháp:
struct <tên_struct> {
//Danh_sách_biến };
typedef struct <tên_struct> <TÊN_STRUCT>;
Trong đĩ:
- Tên_struct: tên cấu trúc do người dùng định nghĩa - Danh_sách_biến:các tham số dữ liệu, thơng tin.
Giả sử chúng ta muốn biểu diễn định nghĩa một cấu trúc gọi là date gồm cĩ ba thành phần ngày, tháng và năm. Cú pháp của cấu trúc này như sau:
struct date //Từ khĩa struct và tên cấu trúc {
KHOA CƠNG NGHỆ THƠNG TIN Trang 137 { hoten char(20) ; float toan ; float ly ; float hoa ; } ;
typdedef struct hocsinh HOCSINH;
Ví dụ 2: Khai báo định nghĩa phân số kiểu struct gồm các thơng tin sau: tuso, mauso
struct phanso {
float tuso; float mauso; };
typdedef struct phanso PHANSO;
7.2.1.3 Tham khảo các thành phần trong struct
HOCSINH hoten[20] toan ly hoa
hs hs.hoten hs.toan hs.ly hs.hoa
Để tham chiếu đến hoten trong HOCSINH ta gán biến HOCSINH với tên là hs và tham chiếu đến biến dữ liệu như sau: hs.hoten tương tự cho các biến cịn lại.
Đối với biến khai báo kiểu con trỏ HOCSINH *hs thì tham chiếu đến bien hoten: hs -> hoten.
KHOA CƠNG NGHỆ THƠNG TIN Trang 138
Hình 123: Màn hình giải ví dụ 3 mục 7.2.1.3
Kết quả in ra màn hình
Hình 124: Kết quả chương trình chạy ví dụ 3 mục 7.2.1.3 Ví dụ 4: Viết chương trình nhập và in một học sinh dạng cấu trúc.
KHOA CƠNG NGHỆ THƠNG TIN Trang 139 float toan;
float ly; float hoa; };
typedef struct hocsinh HOCSINH; void nhap(HOCSINH hs) { float t,l,h; cout<<"nhap ho ten: "; fflush(stdin); gets(hs.hoten);
cout<<"nhap diem toan: "; cin>>t;
hs.toan=t;
cout<<"nhap diem ly: "; cin>>l;
hs.ly=l;
cout<<"nhap diem hoa: "; cin>>h;
hs.hoa=h; }
void xuat(HOCSINH hs) {
KHOA CƠNG NGHỆ THƠNG TIN Trang 140 cout<<"Ho ten: ";
puts(hs.hoten);
cout<<"Diem toan: "<<hs.toan<<"\tLy: "<<hs.ly<<"\tHoa: "<<hs.hoa; }
int main(int argc, char *argv[]) { HOCSINH n; nhap(n); xuat(n); printf("\n");system("PAUSE"); return EXIT_SUCCESS; } Kết quả in ra màn hình
Hình 125: Kết quả chương trình chạy ví dụ 4 mục 7.2.1.3 7.2.1.4 Khởi tạo struct
Việc khởi tạo các cấu trúc cĩ sự khác biệt so với dạng biến thơng thường, các phần tử trong cấu trúc được truy cập thơng qua tốn tử là dấu chấm. Các phần tử riêng biệt được khởi tạo như sau:
DATE d; d.day = 17;
KHOA CƠNG NGHỆ THƠNG TIN Trang 141 static struct DATE d = {17,12};
Với trường hợp trên thì phần tử: year sẽ được khởi tạo là 0
Chuẩn ANSI hiện tại cho phép gán tồn bộ một biến cấu trúc cho một biến cấu trúc khác cĩ cùng số phần tử và mỗi phần tử tương ứng cĩ cùng kiểu dữ liệu
7.2.1.5 Struct lồng nhau
Ví dụ 5: Viết chương trình định nghĩa tâm đường trịn kiểu số thực dạng cấu trúc, nhập và xuất tâm cho người dùng xem.
KHOA CƠNG NGHỆ THƠNG TIN Trang 142
Hình 126: Màn hình giải ví dụ 5 mục 7.2.1.5
Kết quả in ra màn hình
Hình 127: Kết quả chương trình chạy ví dụ 5 mục 7.2.1.5
Ví dụ 6: Viết chương trình định nghĩa đường trịn dạng cấu trúc, nhập và xuất thơng tin đường trịn cho người dùng xem.
#include <cstdlib> #include <iostream> using namespace std; struct diem { float x; float y; };
typedef struct diem DIEM; struct Duongtron
{
DIEM I; //Toa do tâm I float R;//Bán kính duong trịn };
typedef struct Duongtron DUONGTRON; void nhap(DIEM &d)
{
KHOA CƠNG NGHỆ THƠNG TIN Trang 143 cout<<"Toa do: ("<<d.x<<","<<d.y<<")";
}
void nhapdt(DUONGTRON &dt) { cout<<"Nhap tam:\n"; nhap(dt.I); cout<<"Ban kinh R="; cin>>dt.R; } void xuatdt(DUONGTRON dt) {
cout<<"Tam duong tron vua nhap:\n"; xuat(dt.I);
cout<<"\nBan kinh R="<<dt.R; }
int main(int argc, char *argv[]) { DUONGTRON n; nhapdt(n); xuatdt(n); printf("\n");system("PAUSE"); return EXIT_SUCCESS; } Kết quả in ra màn hình
KHOA CƠNG NGHỆ THƠNG TIN Trang 144
Hình 128: Kết quả chương trình chạy ví dụ 6 mục 7.2.1.5 7.2.1.6 Sử dụng mảng các struct
Ngơn ngữ C/C++ khơng giới hạn lập trình viên chỉ được lưu trữ các kiểu dữ liệu đơn giản trong một mảng. Người dùng cĩ thể định nghĩa các cấu trúc đĩng vai trị các phần tử của một mảng.
Ví dụ 7: Viết chương trình định nghĩa thơng tin học sinh gồm họ tên, điểm tốn, điểm lý, điểm hĩa kiểu cấu trúc, nhập và in danh sách học sinh.
#include <cstdlib> #include <iostream> using namespace std; struct hocsinh { char hoten[20]; float toan; float ly; float hoa; };
typedef struct hocsinh HOCSINH; void nhap(HOCSINH hs[],int &n) {
for(int i=0;i<n;i++) {
KHOA CƠNG NGHỆ THƠNG TIN Trang 145 cout<<"nhap diem ly: ";
cin>>l;hs[i].ly=l;
cout<<"nhap diem hoa: "; cin>>h;hs[i].hoa=h; }
}
void xuat(HOCSINH hs[],int n) {
cout<<"Danh sach hoc sinh vua nhap: \n"; for(int i=0;i<n;i++)
{
cout<<"\n"<<i+1<<")"; //puts(hs[i].hoten);
cout<<hs[i].hoten<<"\t\t\tDiem toan: "<<hs[i].toan<<"\tLy: "<<hs[i].ly<<"\tHoa: "<<hs[i].hoa;
} }
int main(int argc, char *argv[]) {
HOCSINH hs[100]; int n;
cout<<"Nhap so hoc sinh: "; cin>>n;
KHOA CƠNG NGHỆ THƠNG TIN Trang 146 xuat(hs,n); printf("\n");system("PAUSE"); return EXIT_SUCCESS; } Kết quả in ra màn hình
Hình 129: Kết quả chương trình chạy ví dụ 7 mục 7.2.1.5 Ví dụ 8: Cải tiến lại ví dụ trên như sau
#include <cstdlib> #include <iostream> using namespace std; struct hocsinh { char hoten[20]; float toan; float ly; float hoa;
KHOA CƠNG NGHỆ THƠNG TIN Trang 147 cout<<"nhap ho ten: ";
fflush(stdin); gets(hs.hoten);
cout<<"nhap diem toan: "; cin>>t;hs.toan=t;
cout<<"nhap diem ly: "; cin>>l;hs.ly=l;
cout<<"nhap diem hoa: "; cin>>h;hs.hoa=h;
return hs; }
void nhap(HOCSINH hs[],int &n) {
for(int i=0;i<n;i++) {
cout<<"Nhap hoc sinh thu "<<i+1<<endl; hs[i]=newhs();
} }
void xuat(HOCSINH hs[],int n) {
cout<<"Danh sach hoc sinh vua nhap: \n"; for(int i=0;i<n;i++)
KHOA CƠNG NGHỆ THƠNG TIN Trang 148 cout<<"\n"<<i+1<<")";
//puts(hs[i].hoten);
cout<<hs[i].hoten<<"\t\t\tDiem toan: "<<hs[i].toan<<"\tLy: "<<hs[i].ly<<"\tHoa: "<<hs[i].hoa;
} }
int main(int argc, char *argv[]) {
HOCSINH hs[100]; int n;
cout<<"Nhap so hoc sinh: "; cin>>n; nhap(hs,n); xuat(hs,n); printf("\n");system("PAUSE"); return EXIT_SUCCESS; } Kết quả in ra màn hình
KHOA CƠNG NGHỆ THƠNG TIN Trang 149
Hình 130: Kết quả chương trình chạy ví dụ 8 mục 7.2.1.5
Cấu trúc và con trỏ
Cũng giống như với một biến, chúng ta cĩ thể khai báo một con trỏ trỏ tới một cấu trúc và gán địa chỉ mở đầu của cấu trúc cho nĩ. Đoạn mã sau sẽ giúp bạn hiểu về khái niệm này.
Ví dụ 9: Sử dụng con trỏ cấp phát cho danh sách học sinh: Từ ví dụ trên, hiệu chỉnh hàm main lại như sau:
{
//HOCSINH hs[100]; int n;
cout<<"Nhap so hoc sinh: "; cin>>n;
HOCSINH *hs = (HOCSINH*)malloc(n * sizeof(HOCSINH));
nhap(hs,n); xuat(hs,n);
KHOA CƠNG NGHỆ THƠNG TIN Trang 150 return EXIT_SUCCESS;
}
7.2.2 Enum
7.2.2.1 Khái niệm
Một Enumeration (liệt kê) là một tập hợp các hằng số nguyên được đặt tên. Một kiểu enum được khai báo bởi sử dụng từ khĩa enum trong C#.
Các kiểu liệt kê trong C/C++ là kiểu dữ liệu giá trị. Nĩi cách khác, kiểu liệt kê chứa các giá trị của nĩ và khơng thể kế thừa hoặc khơng thể truyền tính kế thừa.
Cú pháp:
enum <tên_enum> {
danh_sách_enum
};
typedef enum <tên_enum> <TÊN_ENUM>;
Trong đĩ:
- tên_enum: xác định tên kiểu liệt kê.
- danh_sách_enum: là danh sách các định danh được phân biệt nhau bởi dấu phẩy.
Chú ý: enum phải viết bằng chữ thường.
Mỗi biến trong danh sách liệt kê này đại diện cho một giá trị nguyên. Theo mặc định, giá trị của biến kiểu liệt kê đầu tiên là 0, biến kế tiếp tăng dần lên 1 đơn vị.
Ví dụ 10: Định nghĩa kiểu enum về các hãng xe
enum e_acomany { Audi, BMW, Cadillac, Ford, Jaguar, Lexus Maybach, RollsRoyce,
KHOA CƠNG NGHỆ THƠNG TIN Trang 151 red=1, orange=2, yellow=3, green, blue=8, indigo=8, violet=16 } ;
typedef enum rainbowcolors RAINBOWCOLORS;
Nếu chúng ta chỉ định một giá trị nguyên cho một giá trị nào đĩ của biến kiểu dữ liệu liệt kê thì các giá trị tiếp theo sẽ là các giá trị nguyên tiếp theo.
7.2.2.3 Các ví dụ
Ví dụ 12: Thực hiện lựa chọn màu cho hoa quả cĩ 3 màu như sau: orange, guava, apple. #include <cstdlib> #include <iostream> using namespace std; enum Fruits{ orange, guava, apple };
typedef enum Fruits FRUITS; int main(int argc, char *argv[]) {
KHOA CƠNG NGHỆ THƠNG TIN Trang 152 FRUITS myFruit;
int i;
cout << "Please enter the fruit of your choice(0 to 2)::"; cin >> i;
switch(i) {
case orange:
cout << "Your fruit is orange"; break;
case guava:
cout << "Your fruit is guava"; break;
case apple:
cout << "Your fruit is apple"; break; } printf("\n");system("PAUSE"); return EXIT_SUCCESS; } Kết quả in ra màn hình
Hình 131: Kết quả chương trình chạy ví dụ 12 mục 7.2.2.3
Ví dụ 13: Viết chương trình nhập xuất biến giá trị kiểu dạng enum cho 2 loại xe Lexus và Maybach.
KHOA CƠNG NGHỆ THƠNG TIN Trang 153 Cadillac=11, Ford=44, Jaguar=45, Lexus, Maybach=55, RollsRoyce=65, Saab=111 };
typedef enum e_acomany E_ACOMANY; int main(int argc, char *argv[])
{ E_ACOMANY e; e=Lexus; cout<<"Lexus: "<<e<<endl; e=Maybach; cout<<"Maybach: "<<e<<endl; printf("\n");system("PAUSE"); return EXIT_SUCCESS; } Kết quả in ra màn hình
KHOA CƠNG NGHỆ THƠNG TIN Trang 154
Hình 132: Kết quả chương trình chạy ví dụ 13 mục 7.2.2.3
7.3 Bài tập
1. Viết chương nhập xuất điểm trong mặt phẳng kiểu số thực, tính khoảng cách giữa 2 điểm, tọa độ trọng tâm giữa 3 điểm.
2. Viết chương trình thực hiện: Nhập vào tạo độ 3 điểm A,B,C trong khơng gian, tính độ dài 3 đoạn thẳng AB, AC, BC và kiểm tra xem A, B, C cĩ thẳng hàng khơng?
3. Viết các hàm thực hiện: Nhập thơng tin SV gồm: họ tên, địa chỉ, tuổi, điểm tốn, lý, hĩa. Tính điểm tổng kết, in thơng tin sinh viên.
4. Viết chương trình nhập vào ngày tháng năm, xuất cho người dùng xem ngày hơm qua.
5. Định nghĩa 1 dãy cấu trúc cĩ thể được dùng làm danh bạ điện thoại, gồm cĩ tên, địa chỉ, số điện thoại, với số mẫu tin tối đa là 40. Viết chương trình với các chức năng sau: nhập thơng mới, tìm kiếm số điện thoại, in danh sách theo quận.
6. Viết chương trình đọc vào tên, địa chỉ, sắp xếp tên và địa chỉ theo thứ tự alphabet, sau đĩ hiển thị danh sách đã được sắp xếp.
7. Viết chương trình nhận vào các thơng tin sau: Tên đội bĩng, số trận thắng, số trận hịa, số trận thua. In ra đội bĩng cĩ số điểm cao nhất (với 1 trận thắng = 3 điểm, 1 trận hịa = 1 điểm và 1 trận thua = 0 điểm).
8. Xây dựng cấu trúc gồm: Họ tên, ngày sinh, trường, số báo danh, điểm thi. Trong đĩ, điểm thi là cấu trúc gồm 3 mơn: Tốn, Lý, Hĩa. Nhập liệu vào khoảng 10 thí sinh, tìm và in ra các thí sinh cĩ tổng điểm 3 mơn >= 15.
9. Viết chương trình tạo lập và tìm kiếm dữ liệu. Nội dung yêu cầu gồm: Nhập họ và tên, địa chỉ (gồm: Quận, phường, tổ), tuổi, lương. Tìm kiếm những người ở Quận 3 cĩ tuổi dưới 30 thu nhập từ 500.000đ trở lên và in ra màn hình.
10. Viết chương trình nhập vào kiểu cấu trúc phân số kiểu số thực, tính tổng, hiệu, tích, thương và rút gọn 2 phân số. Xuất kết quả cho người dùng xem.
KHOA CƠNG NGHỆ THƠNG TIN Trang 155 [4] Phạm Văn Ất, Giáo trình kỹ thuật lập trình C – Căn bản và Nâng cao, Giao thơng vận tải, 2006
[5] Nguyễn Ngọc Cương, Giáo trình ngơn ngữ lập trình C/C++, Thơng tin và truyền thơng, 2015
[6] https://voer.edu.vn/c/bien-va-bieu-thuc-trong-c/ab1e3116/b7247bc1, truy cập 2/6/2016 [7] http://www.oktot.com/category/lap-trinh/cc/, truy cập ngày 2/6/2016