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