Bài giảng Giới thiệu lập trình - Lê Nguyên Khôi
Trình Tự Xây Dựng Chương Trình
Soạn thảo
Biên dịch
Chạy chương trình
Kiểm thử
Gỡ lỗi
Giới Thiệu Lập Trình
Tải và cài đặt MinGW32
Biên soạn chương trình sử dụng Notepad
Lưu chương trình vào với phần mở rộng .cpp
Mở chương trình Command Prompt, truy cập
đến thư mục đã lưu tệp
Biên dịch chương trình sử dụng g++ được tệp
có phần mở rộng .exe (chương trình)
Chạy chương trình với các bộ dữ liệu khác
nhau để phát hiện lỗi
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Giới thiệu lập trình - Lê Nguyên Khôi", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
Tóm tắt nội dung tài liệu: Bài giảng Giới thiệu lập trình - Lê Nguyên Khôi
1Giới Thiệu Lập Trình
Giới Thiệu
TS. Lê Nguyên Khôi
Trường Đại học Công nghệ, ĐHQGHN
Nội Dung
1
Khái niệm về chương trình và lập trình
Cấu trúc một chương trình
Biên soạn, biên dịch chương trình
Chạy chương trình
Sửa và gỡ lỗi chương trình
Môi trường lập trình
Giới Thiệu Lập Trình
Chương Trình
2
Một dãy các lệnh (instruction) cho máy tính
Máy tính không thể tự vận hành
Cần mệnh lệnh để hoạt động
Máy tính chạy các lệnh của chương trình tại bộ
xử lý trung tâm (CPU)
Chương trình chạy sai
Không phải do lỗi máy tính
Do các lệnh hướng dẫn máy tính sai
Lập trình viên tìm và sửa lỗi
Giới Thiệu Lập Trình
Lập Trình
3
Quá trình tạo ra chương trình giải quyết vấn đề
cụ thể bằng máy tính, bao gồm:
Phân tích vấn đề
Xây dựng giải pháp
Đánh giá giải pháp
Cài đặt giải pháp
Kiểm thử
Gỡ lỗi
Tối ưu
Giới Thiệu Lập Trình
Tại Sao Cần Lập Trình
4
Điều khiển máy tính
Giải quyết nhiều vấn đề hiện đại
Trải nghiệm sáng tạo thú vị
Khai phá tiềm năng trí tuệ
Giới Thiệu Lập Trình
Đánh Giá Chương Trình
5
Tính đúng đắn (correctness)
Kết quả tương ứng với thông tin đầu vào
Tính chịu lỗi (robustness)
Xử lý: lỗi khi chạy, thông tin đầu vào sai
Tính dễ dùng (usability)
Người dùng dễ dàng sử dụng
Tính khả chuyển (portatbility)
Thích nghi trong các môi trường khác nhau
Tính bảo trì (maintainability)
Dễ dàng sửa đổi, nâng cấp
Tính hiệu quả (efficiency)
Độ tin cậy, tốc độ xử lý, tài nguyên sử dụng, ít rủi ro
Giới Thiệu Lập Trình
2Cài Đặt Giải Pháp
6
Sau khi xây dựng giải pháp, đánh giá giải
pháp, lập trình viên tiến hành giải đặt giải pháp
(viết chương trình)
Sử dụng ngôn ngữ:
Ngôn ngữ máy: trực tiếp điều khiển bộ vi xử lý
Ngôn ngữ tự nhiên: máy không hiểu
Ngôn ngữ bậc cao: C, C++, Java, C#, Python
Có thể chuyển thành ngôn ngữ máy
Sử dụng công cụ, chương trình dịch
Gần với ngôn ngữ tự nhiên
Dễ đọc, dễ hiểu, dễ trao đổi
Giới Thiệu Lập Trình
Trình Tự Xây Dựng Chương Trình
7
Soạn thảo
Biên dịch
Chạy chương trình
Kiểm thử
Gỡ lỗi
Giới Thiệu Lập Trình
Chương Trình Trong Ngôn Ngữ C++
8
Tải và cài đặt MinGW32
Biên soạn chương trình sử dụng Notepad
Lưu chương trình vào với phần mở rộng .cpp
Mở chương trình Command Prompt, truy cập
đến thư mục đã lưu tệp
Biên dịch chương trình sử dụng g++ được tệp
có phần mở rộng .exe (chương trình)
Chạy chương trình với các bộ dữ liệu khác
nhau để phát hiện lỗi
Giới Thiệu Lập Trình
Chương Trình Đầu Tiên
9
Yêu cầu máy tính in ra dòng “Hello, World !!!”
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
return 0;
}
Giới Thiệu Lập Trình
Chương Trình Đầu Tiên
10
Yêu cầu máy tính in ra dòng “Hello, World !!!”
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
return 0;
}
điểm bắt đầu
chương trình
bắt đầu
kết thúc
Giới Thiệu Lập Trình
Chương Trình Đầu Tiên
11
Yêu cầu máy tính in ra dòng “Hello, World !!!”
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
return 0;
}
tải thư viện
tải không gian
tên
Giới Thiệu Lập Trình
3Chương Trình Đầu Tiên
12
Yêu cầu máy tính in ra dòng “Hello, World !!!”
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
return 0;
}
mệnh lệnh in
ra màn hình xuống dòng
In tất cả giữa 2
dấu nháy kép “”
Giới Thiệu Lập Trình
Chương Trình Đầu Tiên
13
Yêu cầu máy tính in ra dòng “Hello, World !!!”
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
return 0;
}
Thông báo với hệ điều
hành không có lỗi xảy ra.
Giá trị khác 0, xảy ra lỗi
trong quá trình chạy.
Giới Thiệu Lập Trình
Chương Trình Đầu Tiên
14
Yêu cầu máy tính in ra dòng “Hello, World !!!”
sau đó dòng “I am a computer”
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
return 0;
}
Giới Thiệu Lập Trình
Chương Trình Đầu Tiên
15
In nhiều dòng liên tục
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
cout << "I am a computer" << endl;
return 0;
}
Giới Thiệu Lập Trình
Chương Trình Đầu Tiên
16
In nhiều dòng liên tục
#include
using namespace std;
int main()
{
cout << "Hello, World !!!" << endl;
cout << "I am a computer" << endl;
return 0;
}
không có dấu
chấm phẩy
Giới Thiệu Lập Trình
Chương Trình Tổng & Hiệu 2 Số Nguyên
17
Tính tổng & hiệu của 2 số nguyên a và b
Xây dựng giải pháp:
1. Nhập 2 số nguyên a và b
2. Tính tổng & hiệu của a và b
3. Lưu các giá trị của tổng & hiệu sau khi tính
4. In ra tổng & hiệu
Kiểm tra giải pháp với các cặp số khác nhau
Giới Thiệu Lập Trình
4Tổng & Hiệu 2 Số Nguyên Trong C++
18
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
int soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
int tong, hieu; // khai báo
tong = soThu1 + soThu2; // tính tổng
hieu = soThu1 – soThu2; // tính hiệu
cout << "tong: " << tong << endl; // in kết quả
cout << "hieu: " << hieu << endl; // in kết quả
return 0;
}
Giới Thiệu Lập Trình
Tổng & Hiệu 2 Số Nguyên Trong C++
chú thích cho lập trình viên
19
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
int soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
int tong, hieu; // khai báo
tong = soThu1 + soThu2; // tính tổng
hieu = soThu1 – soThu2; // tính hiệu
cout << "tong: " << tong << endl; // in kết quả
cout << "hieu: " << hieu << endl; // in kết quả
return 0;
}
Giới Thiệu Lập Trình
Tổng & Hiệu 2 Số Nguyên Trong C++
một phần ngôn ngữ C++ (từ khóa)
20
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
int soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
int tong, hieu; // khai báo
tong = soThu1 + soThu2; // tính tổng
hieu = soThu1 – soThu2; // tính hiệu
cout << "tong: " << tong << endl; // in kết quả
cout << "hieu: " << hieu << endl; // in kết quả
return 0;
}
Giới Thiệu Lập Trình
Tổng & Hiệu 2 Số Nguyên Trong C++
toán tử
21
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
int soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
int tong, hieu; // khai báo
tong = soThu1 + soThu2; // tính tổng
hieu = soThu1 – soThu2; // tính hiệu
cout << "tong: " << tong << endl; // in kết quả
cout << "hieu: " << hieu << endl; // in kết quả
return 0;
}
Giới Thiệu Lập Trình
Tổng & Hiệu 2 Số Nguyên Trong C++
thực hiện mệnh lệnh, kết thúc bằng dấu ;
22
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
int soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
int tong, hieu; // khai báo
tong = soThu1 + soThu2; // tính tổng
hieu = soThu1 – soThu2; // tính hiệu
cout << "tong: " << tong << endl; // in kết quả
cout << "hieu: " << hieu << endl; // in kết quả
return 0;
}
Giới Thiệu Lập Trình
Tổng & Hiệu 2 Số Nguyên Trong C++
khối câu lệnh, phân tách bởi ngoặc cong {}
23
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
int soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
int tong, hieu; // khai báo
tong = soThu1 + soThu2; // tính tổng
hieu = soThu1 – soThu2; // tính hiệu
cout << "tong: " << tong << endl; // in kết quả
cout << "hieu: " << hieu << endl; // in kết quả
return 0;
}
Giới Thiệu Lập Trình
5Tổng & Hiệu 2 Số Nguyên Trong C++
nhóm câu lệnh được đặt tên để thực hiện nhiệm vụ
24
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
int soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
int tong, hieu; // khai báo
tong = soThu1 + soThu2; // tính tổng
hieu = soThu1 – soThu2; // tính hiệu
cout << "tong: " << tong << endl; // in kết quả
cout << "hieu: " << hieu << endl; // in kết quả
return 0;
}
Giới Thiệu Lập Trình
Tổng & Hiệu 2 Số Nguyên Trong C++
phong cách viết chương trình, người khác đọc hiểu
25
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
....int soThu1, soThu2; // khai báo
....cin >> soThu1; // nhập dữ liệu
....cin >> soThu2; // nhập dữ liệu
....int tong, hieu; // khai báo
....tong = soThu1 + soThu2; // tính tổng
....hieu = soThu1 – soThu2; // tính hiệu
....cout << "tong: " << tong << endl; // in kết quả
....cout << "hieu: " << hieu << endl; // in kết quả
....return 0;
}
Giới Thiệu Lập Trình
Dịch & Chạy Chương Trình
26
Viết chương trình (sử dụng Notepad) và lưu
vào tệp TongHieu.cpp
Mở Command Prompt (cmd), chuyển đến thư
mục lưu tệp ucln.cpp
Dịch chương trình, gõ: g++ TongHieu.cpp, sẽ
chuyển mã nguồn ngôn ngữ bậc cao sang ngôn ngữ
máy và lưu vào a.exe
Gõ g++ TongHieu.cpp –o TongHieu.exe để lưu vào
tệp với tên mong muốn (TongHieu.exe)
Chạy chương trình, gõ TongHieu.exe
Giới Thiệu Lập Trình
Phát Hiện Lỗi Tự Động
27
Gõ sai chương trình
Dịch mã nguồn ngôn ngữ bậc cao (C++) báo lỗi
TongHieu.cpp:7:5: error: “in” was not declared in this scope
in soThu1, soThu2;
^
/* chương trình C++ tính tổng & hiệu 2 số nguyên */
#include
using namespace std;
int main()
{
in soThu1, soThu2; // khai báo
cin >> soThu1; // nhập dữ liệu
cin >> soThu2; // nhập dữ liệu
Giới Thiệu Lập Trình
Kiểm Tra Chương Trình
28
Kiểm tra kết quả chương trình
Dữ liệu: 3 và 10
Kết quả: Tong: 13 Hieu: -7
Luôn luôn kiểm tra chương trình với một bộ dữ
liệu được lựa chọn cẩn thận để phát hiện
những lỗi không mong muốn (lỗi chạy)
Kiểm tra thường bị quên
Giới Thiệu Lập Trình
Công Cụ Hỗ Trợ Lập Trình
29
CodeBlocks
Soạn thảo tệp văn bản chương trình
Ghi vào file có đuôi .cpp
Biên dịch: Build > Compile current file
Chạy: Build > Run
Giới Thiệu Lập Trình
6Bài Tập
30
Biên soạn và chạy 02 chương trình trên theo
các bước như trong slide 26
Tìm hiểu sự phát triển các ngôn ngữ lập trình
Mượn sách thư viện
Tìm hiểu codepower.vn
Tìm hiểu CodeBlocks
Slide bài giảng tải từ website môn học hoặc
website bài tập codepower.vn
Giới Thiệu Lập Trình
1Giới Thiệu Lập Trình
Kiểu Dữ Liệu Cơ Bản
TS. Lê Nguyên Khôi
Trường Đại học Công nghệ, ĐHQGHN
Nội Dung
1
Kiểu dữ liệu cơ bản
Phép toán
Biến số
Hằng số
Hàm số toán học
Giới Thiệu Lập Trình
Nhắc Lại: UCLN Trong C++
2Giới Thiệu Lập Trình
Kiểm tra sử dụng bộ dữ liệu (5, 15); (33, 110)
1 #include
2
3 int main()
4 {
5 int a, b;
6 std::cin >> a; std::cin >> b;
7 while (a != b)
8 {
9 if (a > b) a = a – b;
10 else b = b – a;
11 }
12 std::cout << "UCLN: " << a << std::endl;
13 return 0;
14 }
Sử dụng cặp số nguyên âm, không in kết quả
Mệnh lệnh cout << (dòng 12) không thực hiện
Chương trình (dòng 7-11) có sai hay không?
Nhắc Lại: UCLN Trong C++
3
..........
7 while (a != b)
8 {
9 if (a > b) a = a – b;
10 else b = b – a;
11 }
12 std::cout << "UCLN: " << a << std::endl;
13 return 0;
14 }
Giới Thiệu Lập Trình
Nhắc Lại: UCLN Trong C++
4
Chương trình không sai
Điều kiện trước (precondition) khi chạy ch.tr.
2 số nguyên dương (>0)
Điều kiện sau (postcondition) khi chạy ch.tr.
ch.tr. kết thúc và in ra ucln của a và b
Có thể sửa ch.tr. để tính được ucln của 2 số
nguyên âm
Cũng có thể đặt điều kiện trước khi tính, nếu
điều kiện trước sai, không tính và in thông báo
Giới Thiệu Lập Trình
Kiểu Số Nguyên Trong C++
5
Khi sử dụng kiểu dữ liệu, ví dụ int, cần biết
miền giá trị biểu diễn được
Kiểu dữ liệu int biểu diễn số nguyên
từ -2.147.483.648 đến +2.147.483.647
Có ảnh hưởng gì không?
Giới Thiệu Lập Trình
2Tên Lửa Đẩy Ariane 5
6
Cơ quan Vũ trụ châu Âu phóng tên lửa đẩy
ngày 04/06/1996, trị giá 7 tỷ đô la Mỹ
Ariane 5 dùng lại mã của hệ thống điều khiển
đẩy của Ariane 4
Tốc độ A5 lớn hơn A4, nhưng khi thiết kế
không kiểm tra miền dữ liệu biểu diễn
Khi A5 đạt tới tốc độ nhất định, xảy ra lỗi tràn
bộ nhớ, bộ xử lý tắt
A5 bị mất điều khiển, sau đó gây nổ
Giới Thiệu Lập Trình
Hệ Thống Số
7
Số nguyên dương
Số nguyên âm: sử dụng bit trái ngoài cùng để biểu diễn
Giới Thiệu Lập Trình
Cơ số 10 (3 chữ số)
= ∗ + ∗ + ( ∗ )
Cơ số 2 (3 chữ số)
= ∗ + ∗ + ( ∗ )
= ∗ − + ∗ + ( ∗ ) = −
= ∗ − + ∗ + ( ∗ ) = −
Kiểu Số Nguyên char
8
Trong C++ kiểu dữ liệu char là kiểu nhỏ nhất
Sử dụng 1 byte bộ nhớ
1 byte trong máy tính gồm 8 bit
Như vậy, khoảng biểu diễn từ -128 đến +127
10000000 = −128 và 01111111 = 127
Khoảng biểu diễn từ −2 đến +2 − 1
Giới Thiệu Lập Trình
−2 2 2 2 2 2 2 2
−128 64 32 16 8 4 2 1
Kiểu Cơ Bản Trong C++ - Số Nguyên
9
Kiểu Độ Lớn Miền Giá Trị
char 1 byte -128 đến
+127
(−2, +2 − 1)
short 2 byte -32.768 đến
+32.767
(−2, +2 − 1)
int 4 byte -2.147.483.648 đến
+2.147.483.647
(−2, +2 − 1)
Giới Thiệu Lập Trình
Kiểu Cơ Bản Trong C++ - Số Thực
10
Kiểu Độ Lớn Miền Giá Trị
float 4 byte (−10 , +10 )
double 8 byte (−10 , +10 )
long
double
10 byte (−10!, +10!)
Giới Thiệu Lập Trình
Phép Toán Số Học Trong C++
kiểu của toán hạng, xác định phép toán tương ứng
11
Phép Toán Toán Tử Ví Dụ Áp Dụng
Cộng +
a + b
1 + 2
1.1 + 2.2
số nguyên &
số thực
Trừ -
a - b
1 – 2
1.1 – 2.2
số nguyên &
số thực
Nhân *
a * b
1 * 2
1.1 * 2.2
số nguyên &
số thực
Chia /
a / b
1 / 2
1.1 / 2.2
số nguyên &
số thực
Phần dư % a % b1 % 2 chỉ số nguyên
Giới Thiệu Lập Trình
3Phép Chia Số Học Trong C++
12
Chia nguyên: cả hai toán hạng là số nguyên
Chia thực: một trong hai toán hạng là số thực
1 int main()
2 {
3 int i = 1, j = 2, k;
4 double f = 1.0, g = 2.0, h;
5 k = i / j; // chia nguyên k = 0
6 k = j / i; // chia nguyên k = 2
7 h = f / g; // chia thực h = 0.5
8 h = i / g; // chia thực h = 0.5
9 h = f / j; // chia thực h = 0.5
10 return 0;
11 }
Giới Thiệu Lập Trình
Biến Số - Đặc Tính
13
Để sử dụng hiệu quả kết quả của các phép
toán, cần lưu kết quả sau khi tính toán vào các
biến số
Biến số dùng để lưu giá trị thuộc một kiểu dữ
liệu nhất định, ví dụ: int, double
Mỗi biến số có 03 thuộc tính: tên, kiểu, giá trị
Để sử dụng biến số, phải đặt tên hợp lệ bằng
cách khai báo biến số
Phải khai báo biến số trước khi sử dụng
Nếu không trình biên dịch ... 5 tương đương v1 = v2;
Giới Thiệu Lập Trình
1 {
2 int v1 = 10, v2 = 20;
3 int *p = &v1;
4 int *p = &v2;
5 *p = *q;
6 } 0x22ff32
q
20
v2
0x22ff32
0x44ab12
p
10 20
v1
0x44ab12
Toán Tử =
9
Gán con trỏ
Dòng 3, 4: p chỉ tới v1, q chỉ tới v2
Dòng 5: gán p bằng q
p không quản lý v1
p và q cùng quản lý v2
Giới Thiệu Lập Trình
1 {
2 int v1 = 10, v2 = 20;
3 int *p = &v1;
4 int *p = &v2;
5 p = q;
6 } 0x22ff32
q
20
v2
0x22ff32
0x44ab12
p
10
v1
0x44ab12
0x22ff32
Bài Tập
10Giới Thiệu Lập Trình
1 {
2 int i = 10, j = 20, k;
3 int *p = &i;
4 int *q = &j;
5 *p += 1;
6 p = &k;
7 *p = *q;
8 p = q;
9 *p = i;
0 }
j
0x7756
p
0x64cc
p
0x16aa
k
0x9948
i
0x2232
Toán Tử new
11
Sử dụng toán tử new để tạo một vùng nhớ mới
cho con trỏ, vùng nhớ này không có tên
int * p = new int;
Khởi tạo một vùng nhớ mới cho con trỏ p, giá
trị tại vùng nhớ này không biết
int * p = new int(10);
Khởi tạo một vùng nhớ mới cho con trỏ p, giá
trị tại vùng nhớ này được khởi tạo là 10
Giới Thiệu Lập Trình
3Bài Tập
12Giới Thiệu Lập Trình
1 {
2 int *p1, *p2;
3 p1 = new int;
4 *p1 = 10;
5 p2 = p1;
6 *p2 = 20;
7 p1 = new int;
8 *p1 = 30;
9 }
?p1
?p2
p1
?p2
?
p1
?p2
10
p1
p2
10
p1
p2
20
p1
p2 20
?
p1
p2 20
30
Toán Tử delete
13
Sử dụng toán tử delete để giải phóng vùng
nhớ động được tạo ra bởi toán tử new
Lưu ý: chỉ giải phóng vùng nhớ được tạo ra bởi
new, không phải xóa biến con trỏ p
Giới Thiệu Lập Trình
{
int * p = new int;
delete p;
}
Toán Tử delete
14
Vùng nhớ động có thể được trả về bởi hàm
Vùng nhớ động chỉ được giải phóng khi sử
dụng delete, do đó vùng nhớ động tạo ra
trong hàm không bị xóa sau khi kết thúc hàm
Chỉ các biến khai báo trong hàm bị xóa, trong
đó có biến con trỏ p
Giới Thiệu Lập Trình
int * f(int * q) {
int * p = new int;
return p;
}
Mảng Động
15
Biến mảng thực chất là biến con trỏ
Mảng thông thường (int a[10])
Độ dài mảng cố định
Không thể thay đổi độ dài sau khi khai báo
Có thể coi là con trỏ hằng (con trỏ tĩnh)
Mảng động (int * a = new int[10])
Độ dài mảng có thể thay đổi sau khi khai báo
Sử dụng lại toán tử new
int * a = new int[10];
a = new int[50];
Giới Thiệu Lập Trình
Mảng Động – Mảng Tĩnh
16
int * a = new int[10];
int * p;
a và p đều là biến con trỏ, nhưng a là hằng
Có thể gán (được phép)
p = a;
p chỉ tới địa chỉ mà a đang chỉ tới
Nhưng không được phép (lỗi dịch)
a = p;
a là hằng, không thay đổi giá trị của a
Giới Thiệu Lập Trình
Nhắc Lại: cstring & Lớp string
17
char aCString[];
string stringVar;
Chuyển cstring sang string (hợp lệ)
stringVar = aCString;
Chuyển string sang cstring (không hợp lệ)
aCString = stringVar;
Giới Thiệu Lập Trình
4Mảng Động
18
Hạn chế của mảng thông thường:
Phải khai báo độ dài trước
Độ dài mảng có thể không biết tới khi chạy
chương trình
Phải ước lượng độ dài lớn nhất
Lãng phí bộ nhớ
Mảng động
Có thể tăng và giảm khi cần thiết
Giới Thiệu Lập Trình
Giải Phóng Mảng Động
19
Cũng được thực hiện khi chạy
d = new double[10];
// thao tác với d
delete [] d;
Giải phóng tất cả bộ nhớ cho mảng động
[] thông báo giải phóng bộ nhớ cho mảng
Vẫn chỉ tới vùng nhớ đó
Nên gán d = NULL;
Giới Thiệu Lập Trình
Bài Tập
20Giới Thiệu Lập Trình
int a[10] = {2,3,5,1,4,7,0};
int *p = a;
cout << a[0] << *p << "\n";
p++;
cout << *p << p[2] << "\n";
p++; a[2] = 0;
cout << p[1] << *p << "\n";
p -= 2;
cout << p[3] << p[1] << "\n";
2 2
3 1
1 9
1 3
Hàm Trả Về Mảng
21
Kiểu mảng không được phép là kiểu trả về
Không hợp lệ
int[] someFunction();
Phải trả về kiểu con trỏ
int * someFunction();
Giới Thiệu Lập Trình
Con Trỏ Trong C++
22
Con trỏ là khối kiến thức đặc biệt quan trọng
trong C++
Phải nắm vững khái niệm con trỏ cũng như
thao tác với con trỏ
Con trỏ sẽ được sử dụng trong các kiểu dữ
liệu phức tạp
INT 2203 Cấu trúc Dữ liệu & Giải thuật
Giới Thiệu Lập Trình
1Giới Thiệu Lập Trình
Cấu Trúc struct
TS. Lê Nguyên Khôi
Trường Đại học Công nghệ, ĐHQGHN
Nội Dung
1
Cấu trúc struct
Kiểu dữ liệu nhóm
Định nghĩa
Khai báo / Khởi tạo
Sử dụng
Truyền biến cho hàm
Giới Thiệu Lập Trình
Kiểu Dữ Liệu Nhóm
2
Kiểu Mảng:
Tập hợp dữ liệu cùng kiểu
Khai báo sau đó sử dụng như biến đơn lẻ
Truyền cho hàm: truyền địa chỉ
Kiểu cấu trúc struct:
Tập hợp dữ liệu có thể khác kiểu
Phải định nghĩa trước khi sử dụng
Khai báo sau đó sử dụng như biến đơn lẻ
Truyền cho hàm: giống biến đơn lẻ
Giới Thiệu Lập Trình
Kiểu DL Cấu Trúc struct
3
Tập hợp dữ liệu, có thể khác kiểu, được nhóm
Mỗi dữ liệu được lưu trong một biến (trường)
Mỗi dữ liệu có kiểu dữ liệu cụ thể
Hỗ trợ tổ chức dữ liệu phức tạp vào cùng một
đối tượng
Hỗ trợ làm việc giữa các dữ liệu trên đối tượng
Giới Thiệu Lập Trình
Kiểu DL Cấu Trúc struct – Ví Dụ
4
Tên Trường Kiểu Dữ Liệu Dữ Liệu
MSSV string 12345678
HoTen string Trach Van Doanh
NgaySinh string 01/01/1999
GioiTinh bool true
Giới Thiệu Lập Trình
Kiểu DL Cấu Trúc struct – Định Nghĩa
5
Định nghĩa bởi từ khóa struct
Định nghĩa toàn cục
Ngoài và trước int main()
Tất cả các hàm đều hiểu
Không được cấp phát bộ nhớ
Chỉ có mục đích miêu tả cấu trúc
Chỉ cấp phát bộ nhớ
Khi khai báo biến kiểu cấu trúc
Miêu tả:
Các thành phần (trường) và kiểu của chúng
Giới Thiệu Lập Trình
2struct sinhvien – Định Nghĩa
6
struct sinhvien {
string MSSV;
string HoTen;
string NgaySinh;
bool GioiTinh;
} ;
Giới Thiệu Lập Trình
Tên Trường Kiểu Dữ Liệu Dữ Liệu
MSSV string 12345678
HoTen string Trach Van Doanh
NgaySinh string 01/01/1999
GioiTinh bool true
struct sinhvien – Khai Báo/Khởi Tạo
7
struct sinhvien {
string MSSV;
string HoTen;
string NgaySinh;
bool GioiTinh;
} ;
int main() {
struct sinhvien sv1;
struct sinhvien sv2 = { "12345678" ,
"Trach Van Doanh" ,
"01/01/1999" ,
true } ;
}
Giới Thiệu Lập Trình
Truy Cập Thành Phần struct
8
Sử dụng toán tử chấm (.)
sv1 . MSSV
sv1 . HoTen
sv1 . NgaySinh
sv1 . GioiTinh
Gọi tên là “biến thành phần”
Các thành phần của biến kiểu cấu trúc
Kiểu cấu trúc struct khác nhau có thể có cùng tên
biến thành phần
Biến thành phần là biến cục bộ
Giới Thiệu Lập Trình
Truy Cập Thành Phần struct – Ví Dụ
9
struct sinhvien {
string MSSV;
string HoTen;
string NgaySinh;
bool GioiTinh;
} ;
int main() {
struct sinhvien sv1;
sv1.MSSV = "12345678";
sv1.HoTen = "Trach Van Doanh";
sv1.NgaySinh = "01/01/1999";
sv1.GioiTinh = true;
}
Giới Thiệu Lập Trình
struct ngaythangnam
10
struct ngaythangnam {
int ngay;
int thang;
int nam;
} ;
int main() {
struct ngaythangnam homNay = {1, 4, 2000};
struct ngaythangnam ngayMai;
ngayMai.ngay = homNay.ngay + 1;
ngayMai.thang = homNay.thang;
ngayMai.nam = homNay.nam;
}
Giới Thiệu Lập Trình
Cấu Trúc struct – Phép Gán
11
Với cấu trúc struct ngaythangnam
Khai báo 2 biến cấu trúc
struct ngaythangnam homQua, homNay;
Cả 2 biến đều kiểu struct ngaythangnam
Thực hiện phép gán đơn giản hợp lệ
homQua = homNay;
Sao chép giá trị biến thành phần homNay của cho
các biến thành phần của homQua, tương đương
homQua.ngay = homNay.ngay;
homQua.thang = homNay.thang;
homQua.nam = homNay.nam;
Giới Thiệu Lập Trình
3Cấu Trúc struct – Phép Toán Khác
12
Các phép toán khác không được định nghĩa
cho kiểu cấu trúc struct
So sánh bằng/khác (==, !=)
(homQua == homNay biểu thức không hợp lệ)
So sánh thứ tự (, ...)
(homQua < homNay biểu thức không hợp lệ)
Các phép toán
(homQua + homNay biểu thức không hợp lệ)
Nhập & in
(cin & cout không hợp lệ)
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
13
struct toado {
int x, y;
} ;
typedef struct toado ToaDo;
void _nhapToaDo(ToaDo & td) {
cin >> td.x >> td.y;
}
void _inToaDo(const ToaDo & td) {
cout << "(" << td.x << "," << td.y << ")";
}
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
14
struct toado { int x , y ; } ;
typedef struct toado ToaDo;
void _nhapToaDo ( ToaDo & td ) ;
void _inToaDo ( const ToaDo & td ) ;
int main ( ) {
ToaDo td1;
_nhapToaDo ( td1 ) ;
_inToaDo ( td1 ) ;
ToaDo td2;
_nhapToaDo ( td2 ) ;
_inToaDo ( td2 ) ;
}
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
15
void _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ,
ToaDo & trungDiem ) {
trungDiem.x = ( td1.x + td2.x ) / 2;
trungDiem.y = ( td1.y + td2.y ) / 2;
}
ToaDo * _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ) {
ToaDo * trungDiem = new ToaDo;
(*trungDiem).x = ( td1.x + td2.x ) / 2;
(*trungDiem).y = ( td1.y + td2.y ) / 2;
return trungDiem;
}
Giới Thiệu Lập Trình
Truyền Biến Cấu Trúc struct Cho Hàm
16
int main ( ) {
ToaDo td1 ;
_nhapToaDo ( td1 ) ;
ToaDo td2 ;
_nhapToaDo ( td2 ) ;
ToaDo tdTrgD1 ;
_trungDiem ( td1 , td2 , tdTrgD1 ) ;
ToaDo * tdTrgD2 = new ToaDo;
tdTrgD2 = _trungDiem ( td1 , td2 ) ;
_inToaDo ( tdTrgD1 ) ;
_inToaDo ( *tdTrgD2 ) ;
}
Giới Thiệu Lập Trình
Cấu Trúc struct & Con Trỏ
17
Giống các kiểu dữ liệu khác:
struct toado * là con trỏ tới struct toado
Toán tử & trả về địa chỉ của biến cấu trúc
Theo thứ tự ưu tiên: “.” được ưu tiên trước “*”
Nếu td là con trỏ tới cấu trúc struct toado:
*p.x tương đương *(p.x) không hợp lệ
Phải sử dụng (*p).x
Để thuận tiện, có thể dùng toán tử ->:
kết hợp con trỏ (*) với truy cập trường (.)
p->a tương đương (*p).a
Giới Thiệu Lập Trình
4struct thoigian
18Giới Thiệu Lập Trình
struct thoigian
19Giới Thiệu Lập Trình
struct sohuuti
20Giới Thiệu Lập Trình
struct sohuuti
21Giới Thiệu Lập Trình
struct dathuc
22Giới Thiệu Lập Trình
struct dathuc
23Giới Thiệu Lập Trình
1Giới Thiệu Lập Trình
Hàm – Nâng Cao
TS. Lê Nguyên Khôi
Trường Đại học Công nghệ, ĐHQGHN
Nội Dung
1
Nhắc lại Hàm – Cơ Bản
Nạp chồng hàm
Nạp chồng toán tử
Giới Thiệu Lập Trình
Hàm – Cơ Bản
2
Khai báo hàm
int bin ( int , int ) ;
Định nghĩa hàm
int bin ( int so1 , int so2 ) {
// thân hàm miêu tả định nghĩa
// không khai báo lại so1 , so2
}
Chữ ký hàm
int bin ( int , int )
Lời gọi hàm
int a = bin ( so1 , so2 ) ;
Sử dụng tên hàm, tên tham số, không có kiểu
Giới Thiệu Lập Trình
Hàm – Cơ Bản – Truyền Tham Số
3
Truyền giá trị
int bin ( int , int ) ;
Tạo và truyền một bản sao > tốn chi phí
Thay đổi bản sao , bản gốc ngoài hàm không đổi
Xóa bản sao khi kết thúc hàm
Truyền tham chiếu
int bin ( int & , int & ) ;
Chính bản gốc được truyền (địa chỉ bản gốc)
Thay đổi trong hàm, bản gốc thay đổi
Không xóa bản gốc khi kết thúc hàm
Giới Thiệu Lập Trình
Hàm – Cơ Bản – Sử Dụng const
4
Truyền tham chiếu
int bin ( int & , int & ) ;
Thay đổi trong hàm, bản gốc thay đổi
Không muốn hàm thay đổi, sử dụng từ khóa const
Bảo vệ dữ liệu, không cho thay đổi, dữ liệu “chỉ-đọc”
int bin ( const int & , const int & ) ;
Quy ước:
Luôn truyền tham chiếu
Dữ liệu không thay đổi, dùng const
Dữ liệu thay đổi, không dùng const
Giới Thiệu Lập Trình
Hàm Nạp Chồng (Function Overloading)
5
Các hàm thực hiện công việc tương tự
Trùng tên, nhưng khác nhau về tham số
Số lượng tham số
Kiểu tham số
Xác định hàm nào được gọi:
Sử dụng thông tin về tham số
Số lượng & kiểu tham số
Kiểu của hàm
Giới Thiệu Lập Trình
2Hàm Nạp Chồng – Ví Dụ
6
void _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ,
ToaDo & trungDiem ) {
trungDiem.x = ( td1.x + td2.x ) / 2;
trungDiem.y = ( td1.y + td2.y ) / 2;
}
ToaDo * _trungDiem ( const ToaDo & td1 ,
const ToaDo & td2 ) {
ToaDo * trungDiem = new ToaDo;
(*trungDiem).x = ( td1.x + td2.x ) / 2;
(*trungDiem).y = ( td1.y + td2.y ) / 2;
return trungDiem;
}
Giới Thiệu Lập Trình
Hàm Nạp Chồng
7
Khác số lượng tham số
Hàm tính tổng các số truyền vào
Tính tổng 3 số nguyên
int _tong ( int , int , int ) ;
Tính tổng 2 số nguyên
int _tong ( int , int ) ;
Tính tổng 1 số nguyên
int _tong ( int ) ;
Dựa trên số lượng tham số để gọi hàm tương ứng
Giới Thiệu Lập Trình
Hàm Nạp Chồng
8
Tham số mặc định
int _tong(int so1, int so2 = 0, int so3 = 0)
{
return so1 + so2 + so3;
}
Có thể gọi
_tong ( 1 , 2 , 3 )
_tong ( 1 , 2 )
_tong ( 1 )
Có định nghĩa hàm int _tong ( int , int )
_tong ( 1 , 2 ) gọi hàm nào
Giới Thiệu Lập Trình
Hàm Nạp Chồng
9
Khác kiểu tham số
Hàm tính tổng 2 số truyền vào
int _tong ( int , int ) ;
double _tong ( double , double ) ;
Dựa trên kiểu tham số để gọi hàm tương ứng
Tại sao không sử dụng chuyển đổi kiểu tự động
Kiểu trả về không đúng
Nguy hiểm
_tong(1,2) gọi int _tong(int, int);
_tong(1.0,2.0) gọi double _tong(double, double);
Giới Thiệu Lập Trình
Hàm Nạp Chồng
10
Khác kiểu tham số
Hàm tính tổng 2 số truyền vào
double _tong ( int , double ) ;
double _tong ( double , int ) ;
Dựa trên kiểu tham số để gọi hàm tương ứng
Sử dụng chuyển đổi kiểu tự động
_tong ( 3 , 3 ) hoặc _tong ( 3.5 , 3.5 )
Gọi hàm nào
Thêm đầy đủ
int _tong ( int , int ) ;
double _tong ( double , double ) ;
Giới Thiệu Lập Trình
Toán Tử
11
Toán tử thực chất là hàm
Sử dụng toán tử giống lời gọi hàm
Viết theo một cách khác
Ví dụ: so sánh bằng
1 == 2 thực chất == ( 1 , 2 )
Giới Thiệu Lập Trình
3Toán Tử Nạp Chồng
12
Giống như hàm, toán tử cũng có thể nạp chồng
Định nghĩa toán tử cho kiểu dữ liệu mới
Nạp chồng toán tử so sánh cho kiểu cấu trúc
struct PS { int ts , ms ; } ;
bool operator == ( const PS & ps1 ,
const PS & ps2 ) {
return ( ps1.ts * ps2.ms
== ps2.ts * ps1.ms ) ;
}
bool operator != ( const PS & ,
const PS & ) ;
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
13
struct PS { int ts , ms ; } ;
bool operator == ( const PS & ,
const PS & ) ;
bool operator != ( const PS & ,
const PS & ) ;
int main() {
PS ps1 , ps2 ;
// nhập dữ liệu
if ( ps1 == ps2 )
if ( ps1 != ps2 )
}
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
14
struct PS { int ts , ms ; } ;
PS operator + ( const PS & ps1 ,
const PS & ps2 ) {
PS tongPS;
// cập nhật tongPS
return tongPS;
}
int main() {
PS ps1 , ps2 , tongPS ;
tongPS = ps1 + ps2 ;
}
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
15
struct PS { int ts , ms ; } ;
PS operator + ( const PS & ps ,
const int & i ) {
PS tongPS;
// cập nhật tongPS
return tongPS;
}
int main() {
PS ps , tongPS ;
tongPS = ps + 1 ;
}
Giới Thiệu Lập Trình
Toán Tử Nạp Chồng
16
ostream & operator << (
ostream & outStream ,
const PS & ps ) {
outStream << ps.ts << "/" << ps.ms ;
return outStream;
}
int main() {
PS ps , tongPS ;
tongPS = ps + 1 ;
cout << tongPS;
}
Giới Thiệu Lập Trình
Template – Giới Thiệu
17
int _getMax(int so1 , int so2) {
if (so1 < so2) return so2;
return so1;
}
double _getMax(double so1 , double so2) {
if (so1 < so2) return so2;
return so1;
}
PS _getMax(PS so1 , PS so2) {
if (so1 < so2) return so2;
return so1;
}
Giới Thiệu Lập Trình
4Template – Giới Thiệu
18
template
T _getMax ( T so1 , T so2 ) {
if ( so1 < so2 ) return so2;
return so1;
}
int main() {
PS ps1 , ps2 , psMax;
psMax = _getMax ( ps1 , ps2 ) ;
}
Giới Thiệu Lập Trình
File đính kèm:
bai_giang_gioi_thieu_lap_trinh_le_nguyen_khoi.pdf

