MỤC LỤC
1 Mục tiêu . 3
2 Sửa bài tập tuần 02 . 3
2.1 File Ngay.h . 3
2.2 File Ngay.cpp . 4
2.3 File SinhVien.h . 4
2.4 File SinhVien.cpp. 5
2.5 File Main.cpp . 11
3 Giới thiệu về con trỏ . 12
3.1 Vấn đề 1: Các toán tử liên quan đến con trỏ . 12
3.2 Vấn đề 2: Delete con trỏ hai lần . 13
3.3 Vấn đề 3: Quản lý bộ nhớ . 13
4 Mảng động . 15
5 Bài tập . 17
5.1 Bài 01 . 17
5.2 Bài 02 . 18
5.3 Bài 03 . 18
19 trang |
Chia sẻ: netpro | Lượt xem: 4624 | Lượt tải: 1
Bạn đang xem nội dung tài liệu Giáo trình kỹ thuật lập trình, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN TP.HCM
KHOA CÔNG NGHỆ THÔNG TIN
BỘ MÔN CÔNG NGHỆ PHẦN MỀM
HỆ CHÍNH QUI
MÔN: KỸ THUẬT LẬP TRÌNH
GVLT: TS. ĐINH BÁ TIẾN
HƯỚNG DẪN THỰC HÀNH
TUẦN 03 – CON TRỎ
NGUYỄN SƠN HOÀNG QUỐC
NGUYỄN HOÀNG KHAI
HỒ TUẤN THANH
TP.HCM, ngày 13 tháng 03 năm 2011
htthanh@fit.hcmus.edu.vn
Trang 2
MỤC LỤC
1 Mục tiêu ........................................................................................................................ 3
2 Sửa bài tập tuần 02 ........................................................................................................ 3
2.1 File Ngay.h ............................................................................................................. 3
2.2 File Ngay.cpp ......................................................................................................... 4
2.3 File SinhVien.h ...................................................................................................... 4
2.4 File SinhVien.cpp................................................................................................... 5
2.5 File Main.cpp ....................................................................................................... 11
3 Giới thiệu về con trỏ ................................................................................................... 12
3.1 Vấn đề 1: Các toán tử liên quan đến con trỏ ........................................................ 12
3.2 Vấn đề 2: Delete con trỏ hai lần ........................................................................... 13
3.3 Vấn đề 3: Quản lý bộ nhớ .................................................................................... 13
4 Mảng động .................................................................................................................. 15
5 Bài tập ......................................................................................................................... 17
5.1 Bài 01 ................................................................................................................... 17
5.2 Bài 02 ................................................................................................................... 18
5.3 Bài 03 ................................................................................................................... 18
htthanh@fit.hcmus.edu.vn
Trang 3
1 Mục tiêu
- Sửa bài tập tuần 02.
- Các vấn đề về con trỏ.
- Giới thiệu về mảng con trỏ.
2 Sửa bài tập tuần 02
- Phần này, các GV HDTH sẽ sửa bài 03 trong phần bài tập về nhà, của tuần 02.
- Trong bài này có đề cập để mảng sinh viên, và ngày sinh của sinh viên. Để đơn
giản và rõ ràng, ta có thể tổ chức thành 5 file: Ngay.h, Ngay.cpp, SinhVien.h,
SinhVien.cpp và Main.cpp. Cụ thể như sau:
2.1 File Ngay.h
- Chứa khai báo struct Ngày, và 2 hàm nhập và xuất thông tin ngày. 2 hàm này sẽ
được sử dụng trong các hàm liên quan đến struct Sinh Viên.
- Lưu ý ở đầu file ta sử dụng câu lệnh #pragma once.
htthanh@fit.hcmus.edu.vn
Trang 4
2.2 File Ngay.cpp
- Ta viết code xử lý cho 2 hàm nhập và xuất ngày đã khai báo ở trên.
2.3 File SinhVien.h
- Tương tự như trên, file này ta dùng để khai báo struct SinhVien và các hàm liên
quan đền struct đó cũng như các hàm xử lý trên mảng sinh viên. Trong đây ta cũng
khai báo một enum GIOITINH
- Do đó sử dụng struct Ngày ở file Ngay.h nên trong file này ta nhớ phải #include
“Ngay.h”
htthanh@fit.hcmus.edu.vn
Trang 5
2.4 File SinhVien.cpp
- Ta viết code xử lý cho các hàm.
- Đầu tiên là hàm nhập mảng sinh viên.
htthanh@fit.hcmus.edu.vn
Trang 6
- Trong đây có sử dụng hàm NhapSinhVien, sau đây là đoạn mã nguồn của nó.
Trong đoạn code này có một số điểm lưu ý sau:
o Trước mỗi lần đọc chuỗi, ta đều gọi câu lệnh flushall(). Nguyên nhân: sinh
viên thử bỏ câu lệnh này sẽ biết.
o Giá trị của một enum là một số nguyên. Ở đây cho người dùng nhập 0, 1 rồi
từ đó set giá trị enum cho phù hợp.
htthanh@fit.hcmus.edu.vn
Trang 7
- Hàm xuất mảng sinh viên.
htthanh@fit.hcmus.edu.vn
Trang 8
- Hàm xuất thông tin sinh viên.
- Hàm tìm sinh viên có điểm trung bình cao nhất.
htthanh@fit.hcmus.edu.vn
Trang 9
- Ở bước đơn giản, ta có thể viết khai báo hàm này như sau:
o Tuy nhiên, ta sẽ gặp khó khăn khi mảng 0 có phần tử. Khi đó, không có
sinh viên nào tìm được, ta phải trả về cái gì?
o Một bước cải tiên là khai báo hàm như trên. Ở đây hàm trả về kiểu int với 2
giá trị:
0: không tìm thấy sinh viên nào.
1: tìm thấy.
- Đoạn code cho hàm liệt kê.
htthanh@fit.hcmus.edu.vn
Trang 10
- Hàm kiểm tra một sinh viên có sinh trong tháng nào đó ko?
- Hàm tìm sinh viên nữ có điểm trên 7.
o Lập luận như hàm tìm sinh viên có điểm trung bình cao nhất.
htthanh@fit.hcmus.edu.vn
Trang 11
2.5 File Main.cpp
- Chứa duy nhất một hàm main.
- Ta viết code xử lý cho chức năng được yêu cầu.
htthanh@fit.hcmus.edu.vn
Trang 12
- Lưu ý 2 dòng code đầu tiên lấy ra ngày tháng năm hiện hành trên máy. Tm là một
struct có các thuộc tính lưu giữ giá trị ngày, tháng, năm, giờ, phút, giây.
3 Giới thiệu về con trỏ
3.1 Vấn đề 1: Các toán tử liên quan đến con trỏ
Xét đoạn chương trình sau
void main()
{
int i = 2;
int *j;
j = &i;
htthanh@fit.hcmus.edu.vn
Trang 13
}
Câu hỏi
a) i = ...
b) j = ...
c) *j = ...
d) &j = ...
e) &i = ...
3.2 Vấn đề 2: Delete con trỏ hai lần
Xét đoạn chương trình sau:
void main()
{
int *a = new int;
int *b = new int;
*a = 2;
b = a;
delete a;
delete b;
}
Hai biến a và b cùng giữ địa chỉ chung một địa chỉ vùng nhớ ==> bị delete hai lần
Không nên có hai con trỏ cùng giữ chung một địa chỉ vùng nhớ
Cách khắc phục
void main()
{
int *a = new int;
int *b = new int;
*a = 2;
*b = *a;
delete a;
delete b;
}
3.3 Vấn đề 3: Quản lý bộ nhớ
Xét chương trình sau:
void main()
{
while (true)
{
int *number = new int;
}
}
Hiện tượng:
htthanh@fit.hcmus.edu.vn
Trang 14
- Bộ nhớ sử dụng rất nhiều (Hình 1)
- Chương trình sẽ tự động bị ngắt khi hết bộ nhớ.
Hình 1 Tình trạng bộ nhớ khi sử dụng con trỏ không tốt
Sửa lại chương trình
void main()
{
while (true)
{
int *number = new int;
delete number;
}
}
Nhận xét:
- Bộ nhớ sử dụng ít hơn (Hình 2)
- Chương trình không bị tự động ngưng khi hết bộ nhớ.
htthanh@fit.hcmus.edu.vn
Trang 15
Hình 2 Tình trạng bộ nhớ khi sử dụng con trỏ tốt
Kết luận:
- Nên xóa (delete) các con trỏ đã tạo ra (new) khi sử dụng xong.
4 Mảng động
- Về cơ bản mảng động cũng tương tự như mảng tĩnh. Tuy nhiên, khi sử dụng mảng
động phải tiến hành thao tác cấp phát vùng nhớ, và vùng nhớ được cấp vừa bằng
số phần tử của mảng thôi (ko cấp 1 lần 100 hay 1000 phần tử mà chỉ sử dụng có
10 ô đầu để chứa phần tử). Hãy so sánh hai đoạn code sau:
htthanh@fit.hcmus.edu.vn
Trang 16
- Và sau khi sử dụng mảng động xong, vì mảng động chính là một con trỏ, nên ta
cũng phải delete mảng đó.
- Các thao tác trên mảng tĩnh đã học, có thể làm y chang trên mảng tĩnh. Ví dụ sau
đây là hàm nhập mảng số nguyên.
- Tuy nhiên, thay đổi số phần tử trong mảng thì có đôi chút khác biệt. Do lúc đầu
mảng của chúng ta chỉ cấp phát đủ cho bấy nhiêu đó phần tử.
- Chẳng hạn, đây là đoạn code của hàm thêm phần tử x và vị trí k trong mảng động
a có n phần tử.
htthanh@fit.hcmus.edu.vn
Trang 17
- Tương tự với thao tác xóa.
5 Bài tập
5.1 Bài 01
Xét các chương trình sau xem quản lý vùng nhớ có tốt không và viết chương trình khắc
phục
Chương trình 1:
htthanh@fit.hcmus.edu.vn
Trang 18
void main()
{
int *a = new int;
int *b = new int;
*a = 2;
b = a;
delete a;
}
Chương trình 2:
void main()
{
int n = 100;
int m = 100;
int **a;
a = new int*[n];
for (int i = 0;i < n; i++)
{
a[i] = new int[m];
}
delete []a;
}
5.2 Bài 02
Viết chương trình thực hiện chức năng sau đây (sử dụng mảng động).
1. Nhập vào một mảng các số phức (số phức gồm 2 thành phần thực và ảo).
2. Xuất mảng các số phức ra màn hình.
3. Tính tổng các số phức có trong mảng.
4. Tìm số phức thứ hai trong mảng có phần thực là một số không âm.
5. Thêm một số phức vào mảng (vị trí thêm do người dùng chọn, tính từ 0).
6. Xóa các số phức có phần thực chỉ định ra khỏi mảng (người dùng sẽ nhập giá trị
phần thực cần xóa).
5.3 Bài 03
Biết thông tin một quyển sách cần lưu giữ gồm:
- Mã sách: chuỗi, không khoảng trăng, tối đa 7 ký tự.
- Tên sách: chuỗi, tối đa 50 ký tự.
- Tên tác giả: chuỗi, tối đa 50 ký tự.
- Tên nhà xuất bản: chuỗi, tối đa 50 ký tự.
- Giá bán: ngàn đồng. Ví dụ: 50 50 ngàn đồng
- Số trang.
- Năm xuất bản.
Viết một chương trình thực hiện các chức năng sau (sử dụng mảng động):
htthanh@fit.hcmus.edu.vn
Trang 19
7. Nhập danh sách các quyển sách.
8. Xuất danh sách các quyển sách ra màn hình.
9. Sắp xêp các quyển sách trong mảng theo thứ tự tăng dần của năm xuất bản.
10. Tìm quyển sách ít hơn k trang có giá bán cao nhất trong mảng. Cho phép người
dùng nhập giá trị k.
11. Thêm một quyển sách vào trong mảng. Cho người dùng nhập thông tin sách và vị
trí cần thêm vào. Kiểm tra tính hợp lệ của vị trí mà người dùng thêm vào.
12. Xóa các quyển sách có năm xuất bản trước năm chỉ định ra khỏi mảng (người
dùng sẽ nhập vào năm).