Bài giảng Ngôn ngữ lập trình bậc cao - Trần Thị Ngọc Linh

ppt 175 trang huongle 3200
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Ngôn ngữ lập trình bậc cao - Trần Thị Ngọc Linh", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pptbai_giang_ngon_ngu_lap_trinh_bac_cao_tran_thi_ngoc_linh.ppt

Nội dung text: Bài giảng Ngôn ngữ lập trình bậc cao - Trần Thị Ngọc Linh

  1. Bài giảng NGÔN NGỮ LẬP TRÌNH BẬC CAO Ths. Trần Thị Ngọc Linh
  2. NỘI DUNG Chương 1. Giới thiệu ngôn ngữ C và C++ Chương 2. Các thành phần cơ bản, các kiểu dữ liệu cơ sở và các phép toán Chương 3. Các thao tác xử lý INPUT/OUTPUT Chương 4. Cấu trúc điều khiển
  3. Chương 1. Giới thiệu ngôn ngữ C và C++ 1.1 Lịch sử ngôn ngữ C và C++ - Do tác giả Dennis Ritchie và Brian Kerninghan xây dựng vào những năm 1970 - Đặc điểm căn bản: vừa có đặc trưng của ngôn ngữ bậc cao và có khá đầy đủ các chức năng của ngôn ngữ bậc thấp - Có nhiều ngôn ngữ C: Hãng Borland: Turbo C→ C++→Delphi Hãng Microsoft: MicrosoftC→C++→Visual C++
  4. 1.2 Lịch sử phát triển của lập trình hướng đối tượng Lập trình hướng đối tượng(LTHĐT) không phải là đặc quyền của một ngôn ngữ đặc biệt nào. Các khái niệm trong LTHĐT được thể hiện trong nhiều ngôn ngữ lập trình khác nhau. Những ngôn ngữ cung cấp được khả năng LTHĐT được gọi là ngôn ngữ LTHĐT. Do đó sự phát triển của lập trình hướng đối tượng. Ta có thể tổng quan chúng như sau:
  5. SIMULAR(66) SMALLTALK(71) SMALLTALK(80) ADA(83) C++(86) EIFFEL(90) ADA(95) JAVA(95)
  6. Khái niệm về lập trình hướng đối tượng ◼ Lập trình hướng đối tượng (Object Oriented Programming- gọi tắt là OOP) chính là phương pháp lập trình lấy đối tượng (Object) làm nền tảng để xây dựng thuật giải, xây dựng chương trình. ◼ Khái niệm hướng đối tượng được xây dựng trên nền tảng của khái niệm lập trình có cấu trúc và sự trừu tượng hóa dữ liệu. Sự thay đổi căn bản ở chỗ, một chương trình hướng đối tượng được thiết kế xoay quanh dữ liệu mà chúng ta có thể làm việc trên đó, hơn là theo bản thân chức năng của chương trình. Điều này hoàn toàn tự nhiên một khi chúng ta hiểu rằng mục tiêu của chương trình là xử lý dữ liệu
  7. 1.3. Một số khái niệm trong lập trình hướng đối tượng Đối tượng - Trong thế giới thực, khái niệm đối tượng được hiểu như là một thực thể, nó có thể là người, vật hoặc một bảng dữ liệu cần xử lý trong chương trình, Trong LTHĐT thì đối tượng là biến thể hiện của lớp. Lớp - Là một bản mẫu mô tả các thông tin cấu trúc dữ liệu và các thao tác hợp lệ của các phần tử dữ liệu. - Khi một phần tử dữ liệu được khai báo là phần tử của một lớp thì nó được gọi là đối tượng. - Các hàm được định nghĩa hợp lệ trong một lớp được gọi là các phương thức (method) và chúng là các hàm duy nhất có thể xử lý dữ liệu của các đối tượng của lớp đó.
  8. - Mỗi đối tượng có riêng cho mình một bản sao các phần tử dữ liệu của lớp. Mỗi lớp bao gồm: danh sách các thuộc tính (attribute) và danh sách các phương thức để xử lý các thuộc tính đó. - Công thức phản ánh bản chất của kỹ thuật LTHĐT là: Đối tượng = Dữ liệu + Phương thức Ví dụ: Xét lớp HINH_CN bao gồm các thuộc tính: (x1,y1) toạ độ góc trên bên trái, d,r là chiều dài và chiều rộng của HCN. Các phương thức nhập số liệu cho HCN, hàm tính diện tích, chu vi và hàm hiển thị. Lớp HINH_CN có thể được mô tả như sau:
  9. Mô tả lớp HINH_CN HINH_CN Thuộc tính: x1,y1 d,r Phương thức: Nhập_sl Diện tích Chu vi Hiển thị
  10. Chú ý: Trong LTHĐT thì lớp là khái niệm tĩnh, có thể nhận biết ngay từ văn bản chương trình, ngược lại đối tượng là khái niệm động, nó được xác định trong bộ nhớ của máy tính, nơi đối tượng chiếm một vùng bộ nhớ lúc thực hiện chương trình. Đối tượng được tạo ra để xử lý thông tin, thực hiện nhiệm vụ được thiết kế, sau đó bị hủy bỏ khi đối tượng đó hết vai trò.
  11. Trừu tượng hóa: Là cách biểu diễn những đặc tính chính và bỏ qua những chi tiết vụn vặt hoặc những giải thích. Khi xây dựng các lớp, ta phải sử dụng khái niệm trừu tượng hóa. Ví dụ: Ta có thể định nghĩa một lớp để mô tả các đối tượng trong không gian hình học bao gồm các thuộc tính trừu tượng như là kích thước, hình dáng, màu sắc và các phương thức xác định trên các thuộc tính này.
  12. BAO GÓI THÔNG TIN - Việc đóng gói dữ liệu và các phương thức vào một đơn vị cấu trúc lớp được xem như một nguyên tắc bao gói thông tin. - Dữ liệu được tổ chức sao cho các đối tượng ở lớp khác không truy nhập vào, mà chỉ cho phép các phương thức trong cùng lớp hoặc trong những lớp có quan hệ kế thừa với nhau mới được quyền truy nhập. Chính các phương thức của lớp sẽ đóng vai trò như là giao diện giữa dữ liệu của đối tượng và phần còn lại của chương trình. - Nguyên tắc bao gói dữ liệu để ngăn cấm sự truy nhập trực tiếp trong lập trình được gọi là sự che giấu thông tin
  13. KẾ THỪA Là quá trình mà các đối tượng của lớp này được quyền sử dụng một số tính chất của các đối tượng của lớp khác. Sự kế thừa cho phép ta định nghĩa một lớp mới trên cơ sở một hay nhiều lớp đã có, ta còn nói các phương thức đó trong lớp con cháu (descendant) được dẫn xuất (derivation) từ các lớp tổ tiên (ancestor). Lớp mới này, ngoài những thành phần được kế thừa, sẽ có thêm những thuộc tính và các hàm mới. Nguyên lý kế thừa hỗ trợ cho việc tạo ra cấu trúc phân cấp các lớp.
  14. Tương ứng bội - Là khả năng của một khái niệm (chẳng hạn các phép toán) có thể sử dụng với nhiều chức năng khác nhau. Ví dụ: Phép cộng (+) có thể dùng để thực hiện cho các toán hạng là số, là xâu và cả lớp. - Hành vi của phép toán tương ứng bội phụ thuộc vào kiểu dữ liệu mà nó sử dụng để xử lý. - Tương ứng bội đóng vai quan trọng trong việc tạo ra các đối tượng có cấu trúc bên trong khác nhau nhưng cùng dùng chung một giao diện bên ngoài (như tên gọi).
  15. Liên kết động Là dạng liên kết các thủ tục và hàm khi chương trình thực hiện lời gọi tới các hàm, thủ tục đó. Như vậy trong liên kết động, nội dung của đoạn chương trình ứng với thủ tục, hàm sẽ không được biết cho đến khi thực hiện lời gọi tới thủ tục, hàm đó.
  16. TRUYỀN THÔNG BÁO - Truyền thông báo cho một đối tượng là yêu cầu đối tượng thực hiện một việc gì đó. Cách ứng xử của đối tượng được mô tả bên trong lớp thông qua các phương thức. - Trong chương trình, thông báo gửi đến cho một đối tượng chính là yêu cầu thực hiện một công việc cụ thể, nghĩa là sử dụng những hàm tương ứng để xử lý dữ liệu đã được khai báo trong đối tượng đó. Vì vậy, trong thông báo phải chỉ ra được hàm cần thực hiện trong đối tượng nhận thông báo. Thông báo truyền đi cũng phải xác định tên đối tượng và thông tin truyền đi.
  17. Ví dụ: Lớp CONGNHAN có thể là đối tượng cụ thể được đại diện bởi Hoten nhận được thông báo cần tính lương thông qua hàm TINHLUONG đã được xác định trong lớp CONGNHAN. Thông báo đó sẽ được xử lý như sau: CONGNHAN.TINHLUONG (Hoten) ↑ ↑ ↑ Đối tượng Thông báo Thông tin Trong chương trình hướng đối tượng, mỗi đối tượng chỉ tồn tại trong thời gian nhất định. Đối tượng được tạo ra khi nó được khai báo và sẽ bị hủy bỏ khi chương trình ra khỏi miền xác định của đối tượng đó. Sự trao đổi thông tin chỉ có thể thực hiện trong thời gian đối tượng tồn tại.
  18. Các ưu điểm của lập trình hướng đối tượng ◼ Thông qua thừa kế, loại bỏ được đoạn chương trình dư thừa khi mô tả dữ liệu ◼ Chương trình được xây dựng từ các đơn thể có khả năng trao đổi với nhau nên việc thiết kế và lập trình sẽ tuân theo quy trình nhất định ◼ Sự che giấu thông tin đảm bảo cho sự an toàn, không bị ảnh hưởng bởi chương trình khác
  19. ◼ Dễ mở rộng và nâng cấp hệ thống ◼ Kỹ thuật truyền thông báo giúp cho việc mô tả giao diện với các hệ thống bên ngoài trở nên đơn giản hơn ◼ Có thể quản lý được độ phức tạp của phần mềm ◼ Có thể xây dựng được ánh xạ giữa các đối tượng có thực bên ngoài với các đối tượng trong chương trình
  20. 1.4. Cài đặt C++ - Có sẵn trong bộ nhớ gốc - Chạy chương trình Install trong disk 1 và làm theo hướng dẫn 1.5. Môi trường Borland C++ 1.6. Thiết lập cấu hình cho môi trường
  21. Chương 2. Các thành phần cơ bản, các kiểu dữ liệu cơ sở và các phép toán 2.1. Các thành phần cơ bản 2.1.1. Bộ ký tự Bao gồm: - Các chữ cái: a, z,A ,Z - Các chữ số: 0, ,9 - Các ký hiệu phép toán: +,-,*,/, so sánh, () - Ký tự nối và dấu gạch dưới - Các ký hiệu: “;”,”,”,”,’,[,%,
  22. 2.1.2. Tên - Là tên gọi các biến, tên các hàm, tên lớp do người sử dụng tạo ra và tuân theo qui tắc sau: - Bắt đầu bằng chữ cái - Không được trùng với từ khóa 2.1.3. Từ khóa - Là từ được C dành riêng cho việc xây dựng các câu lệnh, các khai báo, các phép tính, asm, car, bool, break, marry, catch, to char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, explicit, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public,
  23. 2.1.4. Lời giải thích - Có thể đặt bất kỳ chỗ nào trong chương trình và được viết sau ký hiệu: /* 2.1.5. Cấu trúc của một chương trình C và qui tắc viết chương trình KHAI BÁO THƯ VIỆN MAIN() FUNC1() FUNC2() FUNCN() 2.2. Các kiểu dữ liệu và cách khai báo 2.2.1. Khái niệm về kiểu dữ liệu - Là kiểu được định nghĩa trong C để giải quyết các bài toán. Gồm kiểu dữ liệu cơ sở, kiểu dẫn xuất, kiểu do người dùng định nghĩa
  24. 2.2.2. Kiểu dữ liệu cơ sở và khai báo 2.2.2.1. Kiểu số nguyên - Các kiểu số nguyên bao gồm: Tên kiểu Phạm vi giá trị Số byte short int (enum, int) có dấu: -32768 to 32767 2 unsigned int không dấu: 0 to 65535 long có dấu:-2147483648 to 2147483647 4 Unsigned long không dấu: 0 to 4294967295
  25. 2.2.2.2. Kiểu số thực - Gồm các kiểu sau: Tên kiểu Phạm vi giá trị Số byte float 3.4e + / - 38 (7 digits) 4 double 1.7e + / - 308 (15 digits) 8 long double 1.2e + / - 4932 (19 digits) 10 2.2.2.3. Kiểu ký tự Tên kiểu Phạm vi giá trị Số byte char có dấu: -128 to 127 1 unsigned char không dấu: 0 to 255
  26. 2.2.2.4. Kiểu Boolean Tên kiểu Phạm vi giá trị Số byte bool true hoặc false 1 2.2.3. Các kiểu dữ liệu được định nghĩa bởi người dùng ◼ STRUCTURE ◼ UNION ◼ CLASS ◼ Enumeration
  27. Structure struct [ ] { [ ] ; [ ] ; } [ ] ; ◼ Thực chất, struct giống như bản ghi (record) trong Pascal.
  28. UNION union [ ] { ; } [ ] ; ◼ Thực chất, union giống như struct, nhưng cho phép các biến chia sẻ vùng nhớ, giống như bản ghi động trong Pascal.
  29. Class class [ ] { } [ ] ; : Là dữ liệu (data) và các phương thức (methods) : Các lớp cơ sở (ancestor).
  30. Enumeration enum [ ] { [= ], } [var_list]; : Tên hằng, được gán giá trị mặc định nếu có = . Ví dụ: Enum Color {White, Black, Red=3, Yellow}; Như trên, While=0, Black=1, Red=3 và Yellow=4.
  31. 2.2.4. Sự tương thích giữa các kiểu Mặc dù một số kiểu có cùng số byte nhưng chúng không tương thích. Để gán giá trị cho nhau, phải sử dụng phép quy đổi kiểu. Cú pháp: ( ) ; Ví dụ: unsigned Ch=65; Khi đó (char) Ch sẽ là ‘A’.
  32. 2.2.5. Định nghĩa và khai báo hằng - Hằng là đại lượng có giá trị không đổi. Có các loại hằng(int, long, Float, double, xâu, ký tự) - Định nghĩa: #define - Khai báo hằng như sau: Sử dụng const: const = ; Ví dụ: #define PI 3.14159265 #define NEWLINE '\n' #define WIDTH 100 const unsigned char A[2][3] = {65,66,67,68,69,70}; const unsigned n=10;
  33. 2.2.6. Các hình thức chuyển đổi kiểu giá trị - Với các kiểu dữ liệu chuẩn ta có thể thực hiện các phép chuyển kiểu ngầm định. - Có hai loại chuyển kiểu: Chuyển kiểu ngầm định(tự động): được thực hiện bởi trình biên dịch Chuyển kiểu tường minh(ép kiểu): thường được dùng trong các câu lệnh gọi hàm để gửi các tham số có kiểu khác với các tham số hình thức tương ứng Cú pháp: Kiểu(biểu thức) hoặc (kiểu)biểu thức
  34. 2.2.7. Các tham chiếu ◼ Biến tham chiếu thực chất là bí danh của biến khác đã được khai báo, và được sử dụng như với biến bình thường. Ví dụ: Int m=10, n, &Rm=m, &Rn=n; ◼ Như vậy, Rm và Rn tương ứng là tham chiếu của m và n, được sử dụng như m và n. Giá trị của biến sẽ thay đổi khi thay đổi giá trị của biến tham chiếu tương ứng với nó.
  35. 2.2.8. Biến con trỏ ◼ Biến con trỏ được sử dụng rộng rãi trong Borland C++. Mỗi con trỏ chiếm bốn byte và trỏ tới vùng nhớ gồm một số byte liên tục. Kích thước vùng nhớ này phụ thuộc kiểu mà con trỏ trỏ tới. ◼ Cú pháp (chú ý đến dấu *): * ; ◼ Ví dụ: int m=10, *p=m, *q=20, *r; char *s=”This is a pointer”, *t; Trong ví dụ này, p, q và r là ba con trỏ, trỏ tới kiểu int. Con trỏ p cụ thể đã trỏ tới vùng nhớ của biến m, con trỏ q đã được cấp phát vùng nhớ và vùng nhớ đó chứa giá trị 20.
  36. Các con trỏ s và t đều trỏ tới kiểu char, tức là xâu ký tự. Vùng nhớ của s gồm 18 byte đã được cấp phát, byte cuối cùng là ký tự NULL báo kết thúc xâu, có T dạHngI: S I S A P O I N T E R \0 Các con trỏ r và t đều chưa được cấp phát vùng nhớ. Chúng có thể được sử dụng để trỏ tới các vùng nhớ của các con trỏ cùng kiểu. Đặc biệt, với khai báo: char u[20]=” This is a pointer”; thì thực chất u là mảng các ký tự (char). Ta có thể cho s hoặc t trỏ tới u, nhưng không thể thay đổi địa chỉ của u và cũng không thể trực tiếp thay đổi giá trị của u.
  37. 2.3. BIỂU THỨC CÂU LỆNH VÀ CÁC PHÉP TOÁN 2.3.1. Biểu thức và các phép toán Biểu thức là một công thức tính toán để đạt được một giá trị thông qua một công thức toán học nào đó. Một biểu thức bao gồm: - Toán tử(operator): được viết ra bằng dấu phép toán - Toán hạng(operand): Có thể là hàng, biến, là
  38. 2.3. BIỂU THỨC CÂU LỆNH VÀ CÁC PHÉP TOÁN ❖ Biểu thức được phân loại: - Biểu thức số học: là biểu thức tính ra giá trị bằng số. - Biểu thức logic: là biểu thức về nguyên tắc chỉ nhận hai giá trị True hoặc False - Biểu thức quan hệ: là biểu thức chứa các toán tử quan hệ
  39. CÁC PHÉP TOÁN (Toán tử) ❖ Phép toán xử lý một toán hạng Toán tử lấy địa chỉ * Phép số âm - Phép số dương + Toán tử đảo bit ! Toán tử tăng lên 1 ++ Toán tử giảm đi 1 Phép lấy phần bù một ~
  40. ❖ Phép toán xử lý hai toán hạng Phép nhân, chia, chia dư *, /,% Phép công, trừ +, - Phép dịch trái, phải > Phép đảo bit ! các phép toán quan hệ >,>=,<, <= các phép toán trên bit &,^,|,& &,||
  41. 2.3.2. QUY TĂC THỰC HIỆN BT HAY THỨ TỰ ƯU TIÊN CÁC PHÉP TOÁN Quy tắc ◼ Khi viết các biểu thức phức tạp với nhiều toán hạng chúng ta chưa rõ được toán hạng nào được tính trước, toán hạng nào được tính sau. ◼ Ví dụ: a = 5 + 7 % 2 Có thể có hai cách hiểu sau: a = 5 + (7 % 2) với kết quả là 6, hoặc a = (5 + 7) % 2 với kết quả là 0 ◼ Câu trả lời đúng là biểu thức đầu tiên. Vì nguyên nhân nói trên, ngôn ngữ C++ đã thiết lập một thứ tự ưu tiên giữa các toán tử, không chỉ riêng các toán tử số học mà tất cả các toán tử có thể xuất hiện trong C++. Thứ tự ưu tiên của chúng được liệt kê trong bảng sau theo thứ tự từ cao xuống thấp
  42. 2.3.2. QUY TĂC THỰC HIỆN BT HAY THỨ TỰ ƯU TIÊN CÁC PHÉP TOÁN Thứ tự Toán tử Mô tả Associativity 1 :: scope Trái 2 () [ ] -> . sizeof Trái ++ tăng/giảm ~ Đảo ngược bit ! NOT 3 & * Toán tử con trỏ Phải (type) Chuyển đổi kiểu + - Dương hoặc âm 4 * / % Toán tử số học Trái
  43. 2.3.2. QUY TĂC THỰC HIỆN BT HAY THỨ TỰ ƯU TIÊN CÁC PHÉP TOÁN 5 + - Toán tử số học Trái 6 > Dịch bit Trái 7 >= Toán tử quan hệ Trái 8 == != Toán tử quan hệ Trái 9 & ^ | Toán tử thao tác bit Trái 10 && || Toán tử logic Trái 11 ?: Toán tử điều kiện Phải = += -= *= /= %= 12 Toán tử gán Phải >>= <<= &= ^= |= 13 , Dấu phẩy Trái
  44. 2.3.3. CÂU LỆNH ✓ Câu lệnh được cách nhau bởi dấu chấm phẩy ✓ Câu lệnh được chia ra làm hai lạo: câu lện đơn giản và câu lệnh có cấu trúc. ➢ Lện đơn giản: là những lệnh không chứa các lênh khác, như lệnh gán, lời gọi hàm loại hàm Void ➢ Lệnh có cấu trúc: là khối lệnh, lệnh rẽ nhánh và lệnh lặp, như if( ) else, switch,for( ),do while
  45. 2.3.4. LỆNH HỢP THÀNH ▪ Lệnh hợp thành hay lệnh gép bao gồm hay hay nhiều lệnh đơn giản thậm chí có cả lệnh ghép bên trong nó. Lệnh ghép được đặt trong cập { }. ▪ Câu lệnh được cách nhau bởi dấu chấm phẩy(;), ▪ Dấu chấm phẩy chỉ có tác dụng ngăn cách các câu lệnh chứ không phải là dấu kết thúc câu lệnh và nó không phụ thuộc vào câu lệnh.
  46. 2.3.5. CÁC HÀM SỐ HỌC CHUẨN ✓ Các hàm số học chuẩn là các hàm được định nghĩa sẵn, được sử dụng với số nguyên và đối số là số thực. Chúng được nằm trong tệp thư viện ✓ Việc chuyển số thực sang sô nguyên nhờ hai hàm chuản: hàm làm tròn và hàm cắt. ✓ Quy ước tham số nguyên là i, tham số thực là f.
  47. BẢNG CÁC HÀM SỐ HỌC CHUẨN Hàm Kiểu gt nhận Tác dụng được abs(i) int trả về trị tt của sô nguyên i fabs(d) double trả về trị tđ của sô thực d sin(d), cos(d) double exp(d) double pow(x,y) double Trả về giá tri của x mu y floOr(d) double hàm cắt tròn số ceil double hàm làm tròn số fmod(x,y) double hàm lấy phần dư của phép chia x cho y
  48. 2.3.6. CÁC PHÉP TOÁN THEO BIT ◼ Ngoài các phép toán số học , thì số nguyên còn được dùng với các phép tính theo bit: Như Not(^), And(&), Or(|). Các tác vụ này không dùng được với kiểu dữ liệu float, double. ◼ Các phép tính này liên quan đến cách biểu diễn nhị phân trong máy. ◼ Số nhị phân được được biểu diễn bằng chữ số 0 và 1.
  49. 2.3.6. CÁC PHÉP TOÁN THEO BIT Bảng toán tử theo bít Toán tử Ý nghĩa VDụ & And theo từng bít a & b | OR theo từng bít a | b ^ XORtheo từng bít a ^ b > Phép dịch phải I>>M ~ Phép đảo bit ~a
  50. 2.3.7. Toán tử Sizeof ◼ Toán tử sizeof(x) là hàm trả lại số byte mà tham số x chiếm. hay đồng nghĩa với việc xác định số byte của kiểu dữ liệu của x. Vi dụ: #include Main() { int x; sizeof(x);cout<<x;} Cho ta kết quả là 2 vì x là biến kiểu int.
  51. 2.3.8. Toán tử điều kiện Dạng thức: BTđkiẹn ? Bt1:Bt2 ; ◼ Toán tử điều kiện này thực hiện như sau: Thoạt đầu tính toán biểu thức điều kiện nếu giá trị của biểu thức này đúng thì nhận giá trị của Bt1, trái lại nhận giá trị của Bt2. VDụ: (a>b)? (max=a): (max=b);
  52. 2.3.9. CÁC PHÉP TĂNG, GIẢM ĐI 1 Phép tăng và giảm đi 1 C++ cho phép viết gọn lại như sau: i = i +1 i ++ hoặc ++ i i= i -1 i hoặc i Sự khác nhau giữa hai cách viết i++ và ++i là: trong biểu thức: Biến= biểuthức; - nếu biểu thức ++i thì i sẽ được tăng giá trị trước khi gán - nếu biểu thức i++ thì i sẽ được tăng giá trị sau khi thực hiện phép gán.
  53. 2.3.10. Toán tử dãy ◼ Là dãy các biểu thức tính toán được cách nhau bởi dấu phẩy, có dang: tb1,bt2 , trong đó biểu thức có thể chứa một dãy các lệnh. Vdu1: a*b,x+y, trong đó biểu thức tính a*b như một giá trị,sau đó tính giá trị biểu thức x+y. Vd2: (a>b)? (max=a, min=b): (max=b,min=a);
  54. Chương 3. Các thao tác xử lý INPUT/OUTPUT 3.1. Thực hiện INPUT/OUTPUT 3.1.1. INPUT - Thao tác vào chuẩn trong C++ được thực hiện bằng cách sử dụng toán tử đã quá tải >> với dòng cin. Theo sau toán tử này là biến sẽ lưu trữ dữ liệu được đọc vào.
  55. Ví dụ: int age; cin >> age; khai báo biến age có kiểu int và đợi nhập dữ liệu từ cin (bàn phím) để lưu trữ nó trong biến kiểu nguyên này. ◼ cin chỉ bắt đầu sử lý dữ liệu nhập từ bàn phím sau khi phím Enter được gõ. Vì vậy dù bạn chỉ nhập một kí tự thì cin vẫn sẽ kiên nhẫn chờ cho đến khi bạn gõ phím Enter.
  56. #include Please enter an integer int main value: 702 (){ int i; cout > i; cout << 1404. "The value you entered is " << i; cout << " and its double is " << i*2 << ".\n"; return 0;}
  57. Bạn có thể dùng cin để nhập một lúc nhiều dữ liệu từ người dùng: cin >> a >> b; tương đương với cin >> a; cin >> b; Trong cả hai trường hợp người sử dụng phải cung cấp hai dữ liệu, một cho biến a và một cho biến b và được ngăn cách bởi một dấu trống hợp lệ: một dấu cách, dấu tab hay kí tự xuống dòng.
  58. 3.1.2. OUTPUT - Dòng cout được sử dụng với toán tử đã quá tải << (overloaded - bạn sẽ hiểu rõ hơn về thuật ngữ này trong phần lập trình hướng đối tượng) cout << "Output sentence"; // Hiển thị Output sentence lên màn hình cout << 120; // Hiển thị số 120 lên màn hình cout << x; // Hiển thị nội dung biến x lên màn hình - Toán tử << được gọi là toán tử chèn vì nó chèn dữ liệu đi sau nó vào dòng dữ liệu đứng trước.
  59. Chú ý rằng ở dòng đầu tiên chúng ta sử dụng dấu ngoặc kép vì đó là một chuỗi kí tự. Khi chúng ta muốn sử dụng các hằng xâu kí tự ta phải đặt chúng trong cặp dấu ngoặc kép để chúng có thể được phân biệt với các biến. Ví dụ: hai lệnh sau đây là hoàn toàn khác nhau: cout << "Hello"; // Hiển thị Hello lên màn hình cout << Hello; // Hiển thị nội dung của biến Hello lên màn hình
  60. - Toán tử chèn (<<) có thể được sử dụng nhiều lần trong một câu lệnh: cout << "Hello, " << "I am " << "a C++ sentence"; - Câu lệnh trên sẽ in thông báo: Hello, I am a C++ sentence lên màn hình. - Sự tiện lợi của việc sử dụng lặp lại toán tử chèn (<<) thể hiện rõ khi chúng ta muốn hiển thị nhiều biến và hằng hơn là chỉ một biến: cout << "Hello, I am " << age << " years old and my email address is " << email_add;
  61. - Cần phải nhấn mạnh rằng cout không nhảy xuống dòng sau khi xuất dữ liệu, vì vậy hai câu lệnh sau : cout << "This is a sentence."; cout << "This is another sentence."; sẽ được hiển thị trên màn hình: This is a sentence.This is another sentence. - Bởi vậy khi muốn xuống dòng chúng ta phải sử dụng kí tự xuống dòng, trong C++ là \n: cout << "First sentence.\n "; cout << "Second sentence.\nThird sentence."; sẽ viết ra màn hình như sau:
  62. First sentence. Second sentence. Third sentence. Thêm vào đó, để xuống dòng bạn có thể sử dụng tham số endl. Ví dụ: cout << "First sentence." << endl; cout << "Second sentence." << endl; sẽ in ra màn hình: First sentence. Second sentence.
  63. - Tham số endl có một tác dụng đặc biệt khi nó được dùng với các dòng dữ liệu sử dụng bộ đệm: các bộ đệm sẽ được flushed ( chuyển toàn bộ thông tin từ bộ đệm ra dòng dữ liệu). Tuy nhiên, theo mặc định cout không sử dụng bộ đệm.
  64. Chương 4. Cấu trúc điều khiển 4.1. Câu lệnh điều kiện IF • Dạng 1 (dạng khuyết) Cú pháp: IF BtLogic LệnhP ; Trong đó: Biểu thức logic cho kết qủa TRUE hay FALSE. LệnhP có thể là một lệnh đơn hoặc một lệnh có cấu trúc. Nếu LệnhP là một lệnh ghép, tức là gồm nhiều lệnh, thì các lệnh này phải được đặt trong cặp dấu {}.
  65. Nguyên tắc hoạt động: Đầu tiên điều kiện sẽ được kiểm tra. Nếu điều kiện là TRUE, sẽ thực hiện câu lệnh. Nếu điều kiện FALSE không thực hiện câu lệnh mà tiếp tục thực hiện lệnh tiếp sau cấu trúc điều kiện.
  66. Ví dụ 4.1: Viết chương trình nhập hai số nguyên a, b từ bàn phím. In lên mà hình số lớn nhất của hai số đó. #include #include #include main() { int a,b,Max; cout >a; cout >b; Max=a; if (Max<b) Max=b; cout<<"So lon nhat Max = "<<Max; getch() ; }
  67. ◼ Dạng 2 (dạng đầy đủ) Cú pháp if Btlogic Lệnh P else Lệnh Q ; Ý nghĩa ◼ Tùy theo BtLogic là đúng hay sai mà quyết định làm một trong hai lệnh: LệnhP hoặc LệnhQ . ◼ Nếu BtLogic là đúng thì làm LệnhP, không làm LệnhQ, mà chuyển ngay sang thực hiện lệnh kế tiếp ở sau LệnhQ. ◼ Ngược lại, nếu BtLogic là sai thì không làm LệnhP mà làm LệnhQ rồi chuyển sang lệnh kế tiếp ở sau LệnhQ.
  68. Ví dụ 4.2: Viết chương trình giải phương trình bậc nhất một ẩn ax + b = 0 #include #include #include main() { float a, b, x; cout >a; cout >b; if (a == 0.0) if (b == 0.0) cout<<"Phuong trinh vo dinh" ; else cout<<"Phuong trinh vo nghiem"; else { x = -b/a; cout<<"Nghiem cua pt: x ="<<x; } getch(); }
  69. 4.2. Câu lệnh IF lồng nhau Trong câu lệnh IF, nếu LệnhP hoặc LệnhQ, hoặc cả hai, lại là câu lệnh IF thì ta có cấu trúc IF lồng nhau. 4.3. Câu lệnh lựa chọn SWITCH Cú pháp switch (biểu thức) { case hằng1: LệnhP1; break; case hằng2: LệnhP2; break; default: Lệnh Pk; }
  70. Ý nghĩa ◼ Tùy theo giá trị của biểuthức bằng hằng nào trong các hằng1, hằng2, , hằngk mà quyết định thực hiện lệnh nào trong các lệnhP1, lệnhP2, , LệnhPk. Nguyên tắc hoạt động ◼ Bước 1: Tính toán giá trị của biểuthức ◼ Bước 2: So sánh và lựa chọn:
  71. ◼ Nếu giá trị của biểuthức = hằng1 thì thực hiện LệnhP1, cho đến khi tìm thấy từ khoá break, sau đó nhảy đến phần cuối của cấu trúc lựa chọn switch. ◼ Nếu giá trị của biểuthức = hằng2 thì thực hiện LệnhP2, cho đến khi tìm thấy từ khoá break, sau đó nhảy đến phần cuối của cấu trúc lựa chọn switch. ◼ Cuối cùng, nếu giá trị biểu thức không bằng bất kì hằng nào được chỉ định ở trên, chương trình sẽ thực hiện các lệnh Pk trong phần default: nếu nó tồn tại vì phần này không bắt buộc phải có.
  72. Ví dụ 4.3: Viết chương trình nhập vào một tháng của năm (tính theo dương lịch), tính xem tháng đó có bao nhiêu ngày rồi in kết quả lên màn hình. #include #include #include main() { int t, n; cout >t; cout >n; switch (t) { case 1: cout<<"Thang "<<t<<" nam "<<n<<" co 31 ngay"; break; case 3: cout<<"Thang "<<t<<" nam "<<n<<" co 31 ngay"; break; case 5: cout<<"Thang "<<t<<" nam "<<n<<" co 31 ngay"; break; case 7: cout<<"Thang "<<t<<" nam "<<n<<" co 31 ngay"; break;
  73. case 8: cout<<"Thang "<<t<<" nam "<<n<<" co 31 ngay"; break; case 10: cout<<"Thang "<<t<<" nam "<<n<<" co 31 ngay"; break; case 12: cout<<"Thang "<<t<<" nam "<<n<<" co 31 ngay"; break; case 4: cout<<"Thang "<<t<<" nam "<<n<<" co 30 ngay"; break; case 6: cout<<"Thang "<<t<<" nam "<<n<<" co 30 ngay"; break; case 9: cout<<"Thang "<<t<<" nam "<<n<<" co 30 ngay"; break; case 11 : cout<<"Thang "<<t<<" nam "<<n<<" co 30 ngay"; break; case 2:if (n % 4 == 0) cout<<"Thang 2 nam "<<n<<" co 29 ngay"; else cout<<"Thang 2 nam co 28 ngay"; break; } getch(); }
  74. Cấu trúc FOR Cú pháp: for (biến đk; biểu thức; tăng giá trị biến đk) lệnhP; Nguyên tắc hoạt động: Bước 1. Gán giá trị ban đầu cho biến điều khiển. Bước 2: Thực hiện Lệnh P. Bước 3. Tăng giá trị của biến điều khiển, kiểm tra điều kiện của biểu thức, nếu điều kiện còn thỏa mãn, chuyển sang bước 2, ngược lại chuyển bước 4. Bước 4. Kết thúc vòng lặp
  75. Ví dụ Tính tổng: S= 12 + 22+ 32+ + n2 (n nguyên dương) #include #include #include main() { int i, n; double s=0; cout >n; for (i=1;i<=n;i++) s=s+i*i; cout<<"Tong S = "<<s; getch(); }
  76. Câu lệnh FOR lồng nhau ◼ Trong cấu trúc FOR, khi LệnhP cũng là một lệnh FOR thì ta có cấu trúc FOR lồng nhau: Ví dụ 4.5: Viết chương trình in hình chữ nhật đặc như dưới đây:
  77. #include #include #include main() { int m,n,i,j; cout >m; cout >n; for (i=1;i<=n;i++) { for (j=1;j<=m;j++) cout<<"A"; cout<<"\n"; } }
  78. Cấu trúc while Cú pháp: while (Btlogic) LệnhP ; Ý nghĩa ◼ Chừng nào BtLogic còn đúng thì còn làm LệnhP, cho đến khi BtLogic sai thì không làm LệnhP nữa mà chuyển sang thực hiện lệnh kế tiếp theo. Cách thức hoạt động ◼ Nếu BtLogic sai thì chuyển ngay sang lệnh kế tiếp sau LệnhP, ngược lại, nếu BtLogic đúng thì làm LệnhP, rồi quay trở lại.
  79. Ví dụ 4.6 : Nhập số tự nhiên n. Tính S = n! #include #include #include main() { int n,i,j; double s=1; cout >n; i=1; while(i<=n) { s=s*i; i=i+1; } cout<<"S = "<<n<<"! = "<<s; getch(); }
  80. Cấu trúc do while Cú pháp: do Lệnh P while (Btlogic); ◼ Chức năng của nó là hoàn toàn giống vòng lặp while chỉ trừ có một điều là điều kiện điều khiển vòng lặp được tính toán sau khi Lệnh P được thực hiện, vì vậy Lệnh P sẽ được thực hiện ít nhất một lần ngay cả khi Btlogic không bao giờ được thoả mãn.
  81. Ví dụ 4.7: Chương trình dưới đây sẽ viết ra bất kì số nào mà bạn nhập vào cho đến khi bạn nhập số 0. #include int main() { unsigned long n; do { cout > n; cout << "You entered: " << n << "\n"; } while (n != 0); return 0; }
  82. Câu lệnh break ◼ Sử dụng break chúng ta có thể thoát khỏi vòng lặp ngay cả khi điều kiện để nó kết thúc chưa được thoả mãn. Lệnh này có thể được dùng để kết thúc một vòng lặp không xác định hay buộc nó phải kết thúc giữa chừng thay vì kết thúc một cách bình thường.
  83. Ví dụ 4.8 //break loop example #include int main() { int n; for (n=10; n>0; n ) { cout << n << ", "; if (n==3) { cout << "countdown aborted!"; break; } } return 0; }
  84. Câu lệnh continue ◼ Lệnh continue làm cho chương trình bỏ qua phần còn lại của vòng lặp và nhảy sang lần lặp tiếp theo. Ví dụ 4.9 #include int main() { for (int n=10; n>0; n ) { if (n==5) continue; cout << n << ", "; } cout << "FIRE!"; return 0; }
  85. ươ Ệ 5.1. HàmCh trongng 5: C++HÀM TRONG C++ VÀ L NH GỘP MACRO ◼ Hàm là một khối lệnh được thực hiện khi nó được gọi từ một điểm khác của chương trình, hàm( nói chung) nhận các thông số đầu vào và trả lại kết quả thông qua tên hàm. Dạng thức của nó như sau: Type name ( argument1, argument2, ) { // phần khai báo các biến cục bộ nếu có statement ; [Return [bieuthuc]]; }
  86. ươ Ệ TrongCh đó:ng 5: HÀM TRONG C++ VÀ L NH GỘP MACRO - type là kiểu dữ liệu được trả về của hàm - name là tên gọi của hàm. - arguments là các tham số hình thức, Một tham số bao gồm tên kiểu dữ liệu sau đó là tên của tham số giống như khi khai báo biến (ví dụ int x) và đóng vai trò bên trong hàm như bất kì biến nào khác. Chúng dùng để truyền tham số cho hàm khi nó được gọi. Các tham số khác kiểu nhau được ngăn cách bởi các dấu phẩy.
  87. Chương 5: HÀM TRONG C++ VÀ LỆNH ➢ Khai báo nguyên mẫu hàm: GỘP MACRO Dạng thức type name ( argument1, argument2, ) statement Trong đó: - type là kiểu dữ liệu được trả về của hàm - name là tên của hàm. - arguments là các tham số ,
  88. ChúCh ýương 5: HÀM TRONG C++ VÀ LỆNH GỘP MACRO ✓ Nguyên mẫu hàm( nếu có) phải được khai báo ở đầu chương trình , sau hàm main() ✓ Nguyên mẫu hàm không bắt buộc phải có ✓ Đây chỉ là một dòng khai báo hàm gồm tên hàm, tham số và kiểu của tham số. Chưa có phần định nghĩa cụ thể bên trong hàm là gì , ta đing nghĩa ở phần dưới hàm main. ✓ Nếu trường hợp mà không khai báo nguyên mẫu hàm thì phần định nghĩa cụ thể của hàm được đặt trước hàm main().
  89. Chương 5: HÀM TRONG C++ VÀ LỆNH Ví dụ: GỘP MACRO #include int addition (int a, int b) { int r; r=a+b; return (r);} int main () { int z; z = addition (5,3); cout << "The result is " << z; Return 0; }
  90. Chương 5: HÀM TRONG C++ VÀ LỆNH ❖ Cách truyền thamGỘP s ốMACROvà quy tắc hoạt động của hàm: Trong C++ chỉ có một cách truyền tham số duy nhất cho hàm đó là truyền tham số gái trị.Nghĩa là giá trị của tham số thực đc truyền vào sau khi gọi hàm là không thay đổi. Cụ thể tường bước như sau.
  91. Chương 5: HÀM TRONG C++ VÀ LỆNH GỘP MACRO ❖ Cách truyền tham số và quy tắc hoạt động của hàm: Khi gặp lời gọi hàm B1: Cấp phát bộ nhớ cho các đối số tương ứng và các biến cục bộ. B2: Gán giá tri của các tham số thực cho các đối số tương ứng. B3: Thực hiện các lệnh, tính toán trong thân hàm B4: Khi gặp lệnh return hoặc } cuối cùng của thân hàm thì máy sẽ xóa các đối, biến cục bọ và thoát khỏi hàm Quay trỏ lại lời gọi hàm và xuát kết quả bằng lệnh ở trong main
  92. Chương 5: HÀM TRONG C++ VÀ LỆNH 5.3. Đệ quy GỘP MACRO Một hàm gọi là có tính đệ quy nếu như từ một điểm trong thân của hàm gọi tới chính nó. - Khi một hàm gọi đệ quy tới chính nó thì mỗi lần gọi, máy sẽ tạo ra một tập các biến cục bộ mới hoàn toàn độc lập với các biến đã tạo ra trong các lần gọi trước.
  93. Chương 5: HÀM TRONG C++ VÀ LỆNH Ví dụ: So sánh haiG cáchỘP MACRO tính giai thừa của một số nguyên N không bằng đệ quy và bằng đệ quy sau. Long int Gt(int n) { long int s=1; int i; long int Gt( int n) for (i-1;i 1) S*=i; return (n * factorial (n-1)); return s; else return (1); } }
  94. Chương 5: HÀM TRONG C++ VÀ LỆNH Ví dụ lời gọi hàmGỘ sPử MACROdụng đệ quy f( 3 ) return f( 2 ) + f( 1 ) return f( 1 ) + f( 0 ) return 1 return 1 return 0
  95. Chương 6: Các kiểu dữ liệu có cấu ❖ Các kiểu dữ liêu nàytrúc tuân theo một cấu trúc nhất định nào đó. ❖ Các kiểu có cấu trúc điển hình như: - Kiểu mảng - Kiểu Structure - Kiểu Union
  96. ◼ 6.1.1. Khái niệm ki6.1ểu m Kiảngể u mảng ✓ Mảng dữ liêu bao gồm một số hữu hạn các phần tử có cùng một kiểu nằm liên tục trong bộ nhớ được gọi là kiểu cơ bản. ✓ Số phần tử của mảng phải được xác định ngay khi định nghĩa mảng. ✓ Mỗi phần tử của mảng được truy nhập trực tiếp thông qua tên của mảng cùng với chỉ dẫn (chỉ số) truy nhập được đặt trong [ ] ✓ Số chỉ số phải bằng số chiều của mảng
  97. Một mảng dữ liệu 6.1đượ Kic cểấuu thànhmảng bởi các yếu tố: - Kiểu _phần tử ( kiểu dữ liệu chung của các phần tử mảng), có bao nhiêu kiểu biến thì có bấy nhiêu kiểu mảng. - Tên mảng - Số chiều và kích thước mỗi chiều Giải thích các thành phần trên thông qua VD sau:
  98. Int a[10], float b[2][3];6.1 Kiểu mảng Khai báo 2 mảng: - mảng tên là a, số chiều 1, kích thước là 10. Mảng bao gồm 10 phần tử được đánh số thứ tự từ 0 9 là a[0], a[1], a[9]. Mỗi phần tử a[i] chứa một gtrị kiểu int - Mảng tên là b , kiểu float, có số chiều là 2, kích thước của các chiều là 2 và 3. mảng có 6 phần tử được đánh số như sau: a[0][0], a[0][1] ,a[0][2] a[1][0],a[1][1], a[1][2]
  99. 6.1.1. Mảng một chiều 6.1 Kiểu mảng a) Khai báo mảng một chiều [số_phần tử _của _mảng] Trong đó: ◼ Kiểu_PT là kiểu dữ liệu chung của các phần tử trong mảng ◼ số_phần tử _của _mảng cho biết kích thước của mảng ◼ Tên_mảng là tên do người lập trình tự đặt các phần tử của mảng được ngầm định đánh số thứ tự từ 0 số_phần tử_của_mảng – 1.
  100. Vi dụ: Có khai báo sau:6.1 Kiint ểa[20];u m floatảng x[10] - Khai báo mảng a gồm 20 phần tử, mỗi phần tử chứa giá trị kiểu nguyên được sắp xếp như sau: a[0] a[1] a[2 . . . a[18] a[19] - Khai báo mảng] x gồm 10 phần tử, mỗi phần tử chứa giá trị kiểu thực được sắp xếp như sau: x[0] x[1] x[2] x[8] a[9]
  101. b) Truy nhập đến6.1 các Ki phểầun mtửảmngảng một chiều - Các phần tử trong mảng được truy nhập thông qua tên và chỉ số phần tử được đặt trong [ ]. - Để truy nhập đến phần tử thứ i trong mảng ta viết theo cách thức sau: Tên_mảng[ i ]
  102. Ví dụ: float x[10] , m6.1ảng Ki x ểgồum m 10 ảphngần tử, mỗi phần tử x[ i ] chứa các giá tri thực tương ứng như biểu diễn sau: 3.0 4.5 6.8 12.5 25.5 x[0] x[1] x[2] x[8] a[9]
  103. 6.1. Kiểu mảng c) Khởi tạo giá trị cho mảng một chiều C/C++ cho phép ta vừa khai báo mảng vừa khởi tạo giá trị cho mảng theo mẫu sau: Kieu_phan_tu Ten_mang[Kich_thuoc]={ dsách_giá tri } VD:float a[ 4 ]= { 3.0,4.5,6.8, 5.5 } , nghĩa là ngay khi 3.0 4.5 6.8 5.5 khai báo ta đã gán giá trị cho mảng x[0] x[1] x[2] x[3]
  104. c) Khởi tạo giá trị cho6.1. m Kiảngể muộ mt chiảngều Chú ý: Số lượng các hằng trong danh sách khới tạo phải nhỏ hơn hoặc bằng kích thước của mảng, trong trường hợp nhỏ hơn thì các phàn tử còn lại của mảng tự động khởi tạo gái trị 0. float x[ 10 ]= { 3.0,4.5,6.8, 5.5 } 3.0 4.5 6.8 5.5 0 0 x[0] x[1] x[2] x[3] x[8] a[9]
  105. 6.1.2. Mảng hai chiều 6.1. Kiểu mảng Mảng hai hay nhiều chiều có thể được coi như mảng của mảng, ví dụ, một mảng hai chiều có thể được tưởng tược như là một bảng hai chiều gồm các phần tử có kiểu dữ liệu cụ thể và giống nhau. a) Khai báo mảng hai chiều Kieu_phan_tu Ten_mảng[So_hang] [so_cot]; ◼ Ví dụ : Khai báo mảng 2 chiều int ia[5][10]; với int là kiểu mảng, ia là tên mảng, số phần tử mảng là 5 x 10. ◼ Ý nghĩa: Khai báo một mảng 2 chiều số nguyên gồm 50 phần tử, mỗi phần tử có kiểu int.
  106. 6.1.2. Mảng hai chiề6.1.u Kiểu mảng Mùa xuân Mùa hè Mùa thu Mùa đông Sydney 26 34 22 17 Melbourne2 24 32 19 13 int seasonTemp[3][4]; Brisbane 28 38 25 20 26 34 22 17 24 32 19 13 28 38 25 20 Firsthàng row đầu Secondhàng hairow Thirdhàng rowba Cách tổ chức trong bộ nhớ
  107. ➢ Truy6.1.xuất đến Kitừngểuphần mtửảmảngng 2(chiềuMảcongkhai haibáo chiInt a[ề5u] [)10] Sau khi được khai báo, mỗi phần tử trong mảng 2 chiều đều có 2 chỉ số để tham chiếu, chỉ số hàng và chỉ số cột. Chỉ số hàng bắt đầu từ 0 đến số hàng – 1 và chỉ số cột bắt đầu từ 0 đến số cột – 1. Tham chiếu đến một phần tử trong mảng 2 chiều ia: ia[chỉ số hàng][chỉ số cột] 0 1 2 3 4 5 6 7 8 9 a 0 1 2 3 4 a[3][2] a[1][5] a[4][8] a[3][2] là phần tử tại hàng 3 cột 2 trong mảng 2 chiều xem như là một biến kiểu int.
  108. Nhậ6.1.p dữ liKiệu ểchou mmảngả ng2 chi ề(uM khaiảng báo haiInt a[5]chi [10]ều) for (i = 0; i > a[i][j]; }
  109. 6.1. Kiểu mảng(Mảng hai chiều) ➢ Khởi tạo giá trị cho mảng hai chiều int a[5][5] = {{1, 0, 0, 0, 1} {1, 0, 0, 0, 1}, {1, 1, 1, 1, 1} {1, 0, 0, 0, 1}, {1, 0, 0, 0, 1}};
  110. 6.1.3. Các bài toán6.1. thườ Kingể guặp mtrênả ngmảng Các bài toán tính toán trên mảng ( Tính tổng các phần tử mảng, tổng các phần tử âm,dương , Trung bình cộng các phần tử ) Bài toán sắp xếp trên mảng( Sắp xếp tăng, giảm theo tiêu chí nào đó, . Bài toán tìm kiếm trên mảng( tìm kiếm tuyến tính, tìm kiếm nhị phân, ) .
  111. 6.1.3.1. Sắp xếp mảng6.1. Kiểu mảng - Sắp xếp nói chung và sắp xếp mảng nói riêng được hiểu tổng quát là quá trình lựa chọn, sắp đặt các đối tượng dữ liệu theo một trật tự nào đó. - Ý nghĩa của việc sx là giúp đơn giản hoá việc tìm kiếm các phần tử trong khối dữ liệu đã được sx ✓ Sắp xếp chọn ✓ Bubble Sort - Sắp xếp nỗi bọt ✓ Insertion Sort - Sắp xếp kiểu chèn ✓
  112. Bài toán và sắp xếp chọn : Giả sử có một dãy(mảng) gồm n phần tử X[1], X[2], X[n] 6.1. Kiểu mảng Yêu cầu thực hiện việc sắp xếp để được một dãy tăng Đầu tiên chọn phần tử nhỏ nhất trong n phần tử từ dãy X[1] X[n] và hoán vị nó với phần tử X[1]. Chọn phần tử có khóa nhỏ nhất trong n-1 phần tử từ dãy X[2] X[n] và hoán vị nó với X[2]. Tổng quát ở bước thứ i, chọn phần tử có khoá nhỏ nhất trong n-i+1 phần tử từ dãy X(i) X(n) và hoán vị nó với X(i). Sau n-1 bước này thì mảng đã được sắp xếp theo thư tự tăng . Phương pháp này được gọi là phương pháp chọn bởi vì nó lặp lại quá trình chọn phần tử nhỏ nhất trong số các phần tử chưa được sắp.
  113. Ví dụ cho mảng gồm6.1. 6 phần Ki ểtửu sau mảng Int a[6] = 40 8 9 3 5 27 B1 3 8 9 40 5 27 B2 3 5 9 40 8 27 B3 3 5 8 40 9 27 B4 3 5 8 9 40 27 B5 3 5 8 9 27 40
  114. Bài toán và sắp xếp nổi bọt : Giả sử có một dãy(mảng) gồm n phần tử X[1], X[2], X[n] 6.1. Kiểu mảng Duyệt mảng vài lần So sánh cặp phần tử liên tiếp ✓ Nếu thứ tự tăng (hoặc bằng nhau), không thay đổi gì ✓ Nếu thứ tự giảm, tráo đổi hai phần tử Như vậy sau lượt thứ nhất thì phần tử nhỏ nhất sẽ dần dần chuyển lên đỉnh Lặp lại các bước trên cho mọi phần tử
  115. Ví dụ 6.1. Kiểu mảng ( Duyệt mảng từ trái qua phải và hoán đổi khi cần thiết) Int a[6] = 3 4 2 7 6 B1 3 2 4 6 7 B2 2 3 4 6 7 B3 2 3 4 6 7 B4 2 3 4 6 7 B5 2 3 4 6 7
  116. 6.1. Kiểu mảng (Sắp xếp kiểu nổi bọt) int main() { const int N = 10; // size of array a int a[ N ] = { 3, 4, 2,7,6}; int Tam; Duyệt 1 lần cho mỗi phần tử của mảng. for ( int i = 0; i a[ j + 1 ] ) Nếu phần tử bên trái (chỉ số j) { lớn hơn phần tử bên phải (chỉ số Tam = a[ j ]; j + 1), thì ta tráo đổi chúng. a[ j ] = a[ j + 1 ]; Nh ờ sử dụng biến tạm. a[ j + 1 ] = Tam; } // end if
  117. 6.1.3.2. Tìm kiếm trên6.1. mảng Ki(ểTìmu mộtmả giáng trị khoá (key value) trên mảng) Tìm kiếm tuyến tính So sánh từng phần tử của mảng với key ◼ Bắt đầu từ một đầu, đi đến đầu kia của mảng Hữu dụng cho mảng nhỏ và chưa sắp xếp ◼ Không hiệu quả ◼ Nếu giá trị cần tìm không có trong mảng thì phải kiểm tra tất cả các phần tử
  118. 6.1. Kiểu mảng (Tìm kiếm trên mảng) Tìm kiếm nhị phân Chỉ sử dụng cho mảng đã sắp xếp Không mất tính tổng quát, giả xử dãy đang xét là một dãy số tăng dần Phương pháp ◼ So sánh phần tử ở giữa (middle) với key Nếu bằng, tìm thấy Nếu key middle ◼ Lặp lại ở nửa cuối của mảng
  119. # include include 6.1. Kiểu mảng int linearSearch( const int [ ], int, int ); // prototype int main() { const int arraySize = 100; // size of array a int a[ arraySize ]; // create array a int searchKey; // value to locate in a for ( int i = 0; i > searchKey; // attempt to locate searchKey in array a int element = linearSearch( a, searchKey, arraySize ); if ( element != -1 ) cout << "Found value in element " << element << endl; else cout << "Value not found" << endl; return 0; }
  120. int linearSearch(6.1. const Ki intểarray[],u m ảintngkey, int sizeOfArray ) { for ( int j = 0; j < sizeOfArray; j++ ) if ( array[ j ] == key ) // if found, return j; // return location of key return -1; // key not found } // end function linearSearch
  121. Xâu ký tự và các hàm xử lý xâu Xâu kí tự là một dãy các kí tự bất kỳ (kể cả dấu cách) do vậy nó có thể được lưu bằng mảng kí tự. Tuy nhiên để máy có thể nhận biết được mảng kí tự này là một xâu, cần thiết phải có kí tự kết thúc xâu, theo qui ước là kí tự có mã 0 (tức '\0') tại vị trí nào đó trong mảng. Khi đó xâu là dãy kí tự bắt đầu từ phần tử đầu tiên (thứ 0) đến kí tự kết thúc xâu đầu tiên (không kể các kí tự còn lại trong mảng). VD: 0 1 2 3 4 5 6 7 H E L L O \0 H E L \0 L O \0 \0 H E L L O \0
  122. Khai báo char [độ dài]; char [độ dài] = xâu kí tự; char [] = xâu kí tự; ◼ Độ dài mảng là số kí tự tối đa có thể có trong xâu. Độ dài thực sự của xâu chỉ tính từ đầu mảng đến dấu kết thúc xâu (không kể dấu kết thúc xâu ‘\0’). ◼ Do một xâu phải có dấu kết thúc xâu nên trong khai báo độ dài của mảng cần phải khai báo thừa ra một phần tử. Thực chất độ dài tối đa của xâu = độ dài mảng - 1. ◼ Ví dụ nếu muốn khai báo mảng s chứa được xâu có độ dài tối đa 80 kí tự, ta cần phải khai báo char s[81].
  123. Ví dụ char hoten[26]; //xâu họ tên chứa tối đa 25 kí tự char monhoc[31] = "NNLT C++"; ◼ Xâu môn học chứa tối đa 30 kí tự, được khởi tạo với nội dung "NNLT C++" với độ dài thực sự là 10 kí tự (chiếm 11 ô đầu tiên trong mảng monhoc[31]). ◼ Cách khai báo thứ 3 tự chương trình sẽ quyết định độ dài của mảng bởi xâu khởi tạo (bằng độ dài xâu + 1). char thang[] = "Mười hai"; //độ dài mảng = 9
  124. Truy cập một kí tự trong xâu: cú pháp giống như mảng. Ví dụ 6.8 char s[50] = "I\'m a student"; //Chú ý kí tự ' phải được viết là \' cout << s[0]; //in kí tự đầu tiên, tức kí tự 'I' s[1] = 'a'; //đặt lại kí tự thứ 2 là 'a' Không được thực hiện các phép toán trực tiếp trên xâu như: char s[20] = "Hello", t[20]; //khai báo hai xâu s và t t = "Hello"; //sai, chỉ gán được khi khai báo t = s; //sai, không gán được toàn bộ mảng if (s < t) //sai, không so sánh được hai mảng
  125. Phương thức nhập xâu Phương thức: cin.getline(s,n). ◼ s là xâu cần nhập ◼ n-1 là số kí tự tối đa của xâu. ◼ Khi gặp hàm cin.getline(s,n) chương trình sẽ nhìn vào bộ đệm bàn phím lấy ra n-1 kí tự (nếu đủ hoặc lấy tất cả kí tự còn lại, trừ kí tự enter) và gán cho s. Nếu tại thời điểm đó bộ đệm đang rỗng, chương trình sẽ tạm dừng chờ NSD nhập dữ liệu vào từ bàn phím. Hiển nhiên, sau khi gán các kí tự cho s, chương trình sẽ tự động đặt kí tự kết thúc xâu vào ô tiếp theo của xâu s.
  126. Ví dụ: char s[10]; cin.getline(s, 10); cout << s << endl; cin.getline(s, 10); cout << s << endl; ◼ Giả sử ta nhập dòng kí tự: 1234567890abcd ↵. Khi đó lệnh cin.getline(s,10) đầu tiên sẽ gán xâu "123456789" (9 kí tự) cho s, phần còn lại vẫn lưu trong bộ đệm bàn phím. Tiếp theo s được in ra màn hình. Đến lệnh cin.getline(s,10) thứ hai NSD không phải nhập thêm dữ liệu, chương trình tự động lấy nốt số dữ liệu còn lại (vì chưa đủ 9 kí tự) "0abcd" để gán cho s. Sau đó in ra màn hình. Như vậy trên màn hình sẽ xuất hiện hai dòng: 123456789 0abcd
  127. Một số hàm xử lí xâu (#include ) Hàm strcpy(s, t) ◼ Gán nội dung của xâu t cho xâu s. Hàm sẽ sao chép toàn bộ nội dung của xâu t (kể cả kí tự kết thúc xâu) vào cho xâu s. Để sử dụng hàm này cần đảm bảo độ dài của mảng s ít nhất cũng bằng độ dài của mảng t. Trong trường hợp ngược lại kí tự kết thúc xâu sẽ không được ghi vào s và điều này có thể gây treo máy khi chạy chương trình
  128. Ví dụ char s[10], t[10]; t = "Face"; //không được dùng s = t; //không được dùng strcpy(t,"Face");//được,gán"Face" cho t strcpy(s,t); //được, sao chép t sang s cout << s << " to " << t; //in ra: Face to Face
  129. Sao chép n kí tự củHàma t vào s. Hàmstrncpy(s,này chỉ làm nhi t,ệ mn)vụ sao chép, không tự động gắn kí tự kết thúc xâu cho s. Do vậy NSD phải thêm câu lệnh đặt kí tự '\0' vào cuối xâu s sau khi sao chép xong. Ví dụ char s[10], t[10] = "Steven"; strncpy(s, t, 5); //copy 5 kí tự "Steve" vào s s[5] = '\0'; //đặt dấu kết thúc xâu //in câu: Steve is young brother of Steven cout << s << " is young brother of " << t;
  130. Nối (+) một bản saoHàmcủa t vàostrcat(s,sau s. Hàm st)ẽ loại bỏ kí tự kết thúc xâu s trước khi nối thêm t (lấy cả kí tự kết thúc của xâu t vào cho s (nếu s đủ chỗ). Vì vậy không cần thêm kí tự này vào cuối xâu. Tuy nhiên, hàm không kiểm tra xem liệu độ dài của s có đủ chỗ để nối thêm nội dung, việc kiểm tra này phải do NSD đảm nhiệm. Ví dụ: char a[100] = “Man”, b[4] = "tôi"; strcat(a, “ và ”); strcat(a, b); cout << a //Man va toi char s[100], t[100] = "Steve"; strncpy(s, t, 3); s[3] = '\0'; //s = "Ste" strcat(s, "p"); //s = "Step" cout << t << " goes " << s << " by " << s //Steve goes Step by Step
  131. Hàm strncat(s, t, n) Nối bản sao n kí tự đầu tiên của xâu t vào sau xâu s. Hàm tự động đặt thêm dấu kết thúc xâu vào s sau khi nối xong. Cũng giống strcat hàm đòi hỏi độ dài của s phải đủ chứa kết quả. Tương tự, có thể sử dụng cách viết strncat(s, t+k, n) để nối n kí tự từ vị trí thứ k của xâu t cho s. Ví dụ: char s[20] = "Nha "; char t[] = "vua chua" strncat(s, t, 3); //s = “Nha vua” hoặc: strncat(s, t+4, 4); //s = “Nha
  132. Hàm strcmp(s, t) ◼ Hàm so sánh 2 xâu s và t (thay cho các phép toán so sánh). Giá trị trả lại là hiệu 2 kí tự khác nhau đầu tiên của s và t. Từ đó, nếu s1 s2. Trong trường hợp chỉ quan tâm đến so sánh bằng, nếu hàm trả lại giá trị 0 là 2 xâu bằng nhau và nếu giá trị trả lại khác 0 là 2 xâu khác nhau. Ví dụ: if (strcmp(s,t)) cout << "s khác t";
  133. Hàm strncmp(s, t) Giống hàm strcmp(s, t) nhưng chỉ so sánh tối đa n kí tự đầu tiên của hai xâu. Ví dụ: char s[] = “Ha Noi”, t[] = “Ha noi”; cout << strcmp(s,t); //-32 (vì 'N' = 78, 'n' = 110) cout << strncmp(s, t, 3); // 0 (vì 3 kí tự đầu của s và t là như nhau)
  134. Hàm strcmpi(s, t) Như strcmp(s, t) nhưng không phân biệt chữ hoa, thường. Ví dụ: char s[] = “Ha Noi”, t[] = “Ha noi”; cout << strcmpi(s, t); //0 (vì s = t)
  135. Hàm strupr(s) Hàm đổi xâu s thành in hoa, và cũng trả lại xâu in hoa đó. Ví dụ: char s[10] = "Ha noi"; cout << strupr(s); //HA NOI cout << s; //HA NOI (s cũng thành in hoa)
  136. Hàm strlwr(s) Hàm đổi xâu s thành in thuờng, kết quả trả lại là xâu s. Ví dụ: char s[10] = "Ha Noi"; cout << strlwr(s); //ha noi cout << s; //ha noi (s cũng thành in thường)
  137. Hàm strlen(s) Hàm trả giá trị là độ dài của xâu s. Ví dụ: char s[10] = "Ha Noi"; cout << strlen(s); //5 Sau đây là một số ví dụ sử dụng tổng hợp các hàm trên.
  138. VD Thống kê số chữ 'a' xuất hiện trong xâu s. main() { Const int MAX=100; char s[MAX+1]; int sokitu = 0; cin.getline(s, MAX+1); for (int i=0; i < strlen(s); i++) if (s[i] = 'a ') sokitu++; cout << "Số kí tự = " << sokitu << endl; }
  139. ◼ Sao chép xâu s sang xâu t (tương đương với hàm strcpy(t,s)) void main() { char s[100], t[100]; cin.getline(s, 100); //nhập xâu s int i=0; while ((t[i] = s[i]) != '\0') i++; //copy cả dấu kết thúc xâu '\0' cout << t << endl;
  140. Cấu trúc động của dữ liệu Cấu trúc tự trỏ: ◼ Một cấu trúc có chứa ít nhất một thành phần con trỏ có kiểu của chính cấu trúc đang định nghĩa được gọi là cấu trúc tự trỏ. Khai báo: Cách 1: typedef struct ; //định nghĩa tên cấu trúc struct { các thành phần chứa thông tin ; *con trỏ;
  141. Ví dụ: typedef struct Sv Sinhvien; //lưu ý phải có từ khoá struct struct Sv { char hoten[30]; //Thành phần chứa thông tin float diem; //Thành phần chứa thông tin Sinhvien *tiep; //Con trỏ chứa địa chỉ tiếp theo };
  142. Cách 2: struct { các thành phần chứa thông tin ; *con trỏ; }; //định nghĩa tên cấu trúc tự trỏ typedef ;
  143. Ví dụ struct Sv { char hoten[30]; //thành phần chứa thông tin float diem; //thành phần chứa thông tin Sv *tiep; //thành phần con trỏ chứa địa chỉ tiếp theo }; typedef Sv Sinhvien;
  144. Cách 3: typedef struct //định nghĩa tên cấu trúc tự trỏ { các thành phần chứa thông tin ; *con trỏ; };
  145. typedef struct Sinhvien { char hoten[30]; //thành phần chứa thông tin float diem; //thành phần chứa thông tin Sinhvien *tiep; //con trỏ chứa địa chỉ thành phần tiếp theo };
  146. Khái niệm danh sách liên kết ◼ Danh sách liên kết là một cấu trúc dữ liệu cho phép thể hiện và quản lý danh sách bằng các cấu trúc liên kết với nhau thông qua các con trỏ trong cấu trúc. Có nhiều dạng danh sách liên kết phụ thuộc vào các kết nối Ví dụ: ◼ Danh sách liên kết đơn chứa một con trỏ trỏ đến cấu trúc tiếp theo (trước đó). Cấu trúc đầu được đánh dấu bằng con trỏ head và cấu trúc cuối chưa con trỏ NULL. ◼ Danh sách liên kết kép gồm 2 con trỏ, một trỏ đến cấu trúc trước và một trỏ đến cấu trúc sau, 2 đầu của danh sách được đánh dấu bởi các con trỏ head, last. ◼ Danh sách liên kết vòng gồm 1 con trỏ trỏ về sau (trước), hai đầu của danh sách được nối với nhau tạo thành vòng tròn. Chỉ cần một con trỏ head đánh dấu đầu danh sách.
  147. Các phép toán trên danh sách liên Tạo phần tử mới kết Để tạo phần tử mới thông thường chúng ta thực hiện theo các bước sau đây: Dùng toán tử new xin cấp phát một vùng nhớ đủ chứa một phần tử của danh sách. Nhập thông tin cần lưu trữ vào phần tử mới. Con trỏ tiep được đặt bằng NULL. Gắn phần tử vừa tạo được vào danh sách.
  148. Chèn phần tử mới vào giữa ◼ Cho con trỏ p chạy đến phần tử thứ i(vị trí cần chèn) ◼ Cho con trỏ tiep của phần tử mới trỏ vào phần tử thứ i+1 (tuc p->tiep). ◼ Cho con trỏ tiep của phần tử thứ i (hiện được trỏ bởi p) thay vì trỏ vào phần tử thứ i+1 bây giờ sẽ trỏ vào phần tử mới.
  149. Xoá phần tử thứ i khỏi danh sách ◼ Cho con trỏ p chạy đến phần tử thứ i-1. ◼ Đặt phần tử thứ i vào biến x. ◼ Cho con trỏ tiep của phần tử thứ i-1 trỏ vào phần tử thứ i+1 bằng cách đặt tiep =x.tiep. ◼ Giải phóng bộ nhớ được trỏ bởi x bằng câu lệnh delete x.
  150. Chương 7: ĐỌC/GHI TỆP, ĐỌC/GHI CỔNG Khái niệm về tệp tin Tệp tin hay tệp dữ liệu là một tập hợp các dữ liệu có liên quan với nhau và có cùng một kiểu được nhóm lại với nhau thành một dãy. Chúng thường được chứa trong một thiết bị nhớ ngoài của máy tính (đĩa mềm, đĩa cứng ) dưới một cái tên nào đó. ◼ Có hai kiểu nhập xuất dữ liệu lên tệp: Nhập xuất nhị phân và nhập xuất văn bản.
  151. Nhập xuất nhị phân ◼ Dữ liệu ghi lên tệp theo các byte nhị phân như bộ nhớ, trong quá trình nhập xuất, dữ liệu không bị biến đổi. ◼ Khi đọc tệp, nếu gặp cuối tệp thì ta nhận được mã kết thúc tệp EOF (được định nghĩa trong stdio.h bằng -1) và hàm feof cho giá trị khác 0.
  152. Nhập xuất văn bản ◼ Kiểu nhập xuất văn bản chỉ khác kiểu nhị phân khi xử lý ký tự chuyển dòng (mã 10) và ký tự mã 26. Đối với các ký tự khác, hai kiểu đều đọc ghi như nhau. ◼ Khi ghi, một ký tự LF (mã 10) được chuyển thành 2 ký tự CR (mã 13) và LF ◼ Khi đọc, 2 ký tự liên tiếp CR và LF trên tệp chỉ cho ta một ký tự LF Mã kết thúc tệp ◼ Trong khi đọc, nếu gặp ký tự có mã 26 hoặc cuối tệp thì ta nhận được mã kết thúc tệp EOF và hàm feof(fp) cho giá trị khác 0.
  153. Khai báo sử dụng tệp Để khai báo sử dụng tệp, ta dùng lệnh sau: FILE biến_con_trỏ_tệp; ◼ Trong đó biến_con_trỏ_tệp có thể là biến đơn hay một danh sách các biến phân cách nhau bởi dấu phảy (dấu,). Ví dụ FILE *vb, *np; /* Khai báo hai biến con trỏ tệp */
  154. Mở tệp - hàm fopen Cú pháp FILE *fopen(const char *tên_tệp, const char *kiểu); ◼ Nguyên hàm trong: stdio.h, trong đó đối thứ nhất là tên tệp, đối thứ hai là kiểu truy nhập. Công dụng ◼ Hàm dùng để mở tệp. Nếu thành công hàm cho con trỏ kiểu FILE ứng với tệp vừa mở. Các hàm cấp hai sẽ làm việc với tệp thông qua con trỏ này. Nếu có lỗi hàm sẽ trả về giá trị NULL.
  155. Chú ý: ◼ Trong các kiểu đọc ghi, ta nên làm sạch vùng đệm trước khi chuyển từ đọc sang ghi hoặc ngược lại. Ta sẽ đề cập đến các hàm với tính năng xoá sau này. Ví dụ f=fopen("TEPNP","wb");
  156. Đóng tệp - hàm fclose Cú pháp: int fclose(FILE *fp); ◼ Nguyên hàm trong: stdio.h, trong đó fp là con trỏ ứng với tệp cần đóng. Công dụng: ◼ Hàm dùng để đóng tệp khi kết thúc các thao tác trên nó. Khi đóng tệp, máy thực hiện các công việc sau: ◼ Khi đang ghi dữ liệu thì máy sẽ đẩy dữ liệu còn trong vùng đệm lên đĩa
  157. ◼ Khi đang đọc dữ liệu thì máy sẽ xoá vùng đệm ◼ Giải phóng biến trỏ tệp. ◼ Nếu lệnh thành công, hàm sẽ cho giá trị 0, trái lại nó cho hàm EOF. Ví dụ fclose(f);
  158. Đóng tất cả các tệp đang mở- hàm fcloseall Cú pháp: int fcloseall(void); Nguyên hàm trong: stdio.h. Công dụng: ◼ Hàm dùng để đóng tất cả các tệp đang mở. Nếu lệnh thành công, hàm sẽ cho giá trị bằng số là số tệp được đóng, trái lại nó cho hàm EOF. Ví dụ: fcloseall();
  159. Làm sạch vùng đệm - hàm fflush Cú pháp: int fflush(FILE *fp); ◼ Nguyên hàm trong: stdio.h. Công dụng: ◼ Dùng làm sạch vùng đệm của tệp fp. Nếu lệnh thành công, hàm sẽ cho giá trị 0, trái lại nó cho hàm EOF. Ví dụ fflush(f);
  160. Làm sạch vùng đệm của các tệp đang mở - hàm fflushall Cú pháp: int fflushall(void); Nguyên hàm trong: stdio.h. Công dụng: ◼ Dùng làm sạch vùng đệm của tất cả các tệp đang mở. Nếu lệnh thành công, hàm sẽ cho giá trị bằng số các tệp đang mở, trái lại nó cho hàm EOF. Ví dụ : fflushall();
  161. Kiểm tra lỗi file - hàm ferror Cú pháp: int ferror(FILE *fp); ◼ Nguyên hàm trong: stdio.h. Trong đó fp là con trỏ tệp. Công dụng: ◼ Hàm dùng để kiểm tra lỗi khi thao tác trên tệp fp. Hàm cho giá trị 0 nếu không có lỗi, trái lại hàm cho giá trị khác 0.
  162. Kiểmtra cuối tệp - hàm feof Cú pháp: int feof(FILE *fp); ◼ Nguyên hàm trong: stdio.h. Trong đó fp là con trỏ tệp. Công dụng: ◼ Hàm dùng để kiểm tra cuối tệp. Hàm cho giá trị khác 0 nếu gặp cuối tệp khi đọc, trái lại hàm cho giá trị 0.
  163. Truy nhập ngẫu nhiên - các hàm di chuyên con trỏ chỉ vị a)Chuyển con trỏ chỉ vị về đầu tệp - Hàm rewind Cú pháp: void rewind(FILE *fp); ◼ Nguyên hàm trong: stdio.h. Trong đó fp là con trỏ tệp. Công dụng: ◼ Chuyển con trỏ chỉ vị của tệp fp về đầu tệp. Khi đó việc nhập xuất trên tệp fp được thực hiện từ đầu. ◼ Ví dụ: rewind(f);
  164. Chuyển con trỏ chỉ vị trí cần thiết - Hàm fseek Cú pháp: int fseek(FILE *fp, long sb, int xp); Nguyên hàm trong: stdio.h. Trong đó fp là con trỏ tệp. sb là số byte cần di chuyển. xp cho biết vị trí xuất phát mà việc dịch chuyển được bắt đầu từ đó. xp có thể nhận các giá trị sau:
  165. + xp=SEEK_SET hay 0: Xuất phát từ đầu tệp. + xp=SEEK_CUR hay 1: Xuất phát từ vị trí hiện tại của con trỏ chỉ vị. + xp=SEEK_END hay 2: Xuất phát từ cuối tệp. Công dụng: ◼ Chuyển con trỏ chỉ vị của tệp fp về vị trí xác định bởi xp qua một số byte xác định bằng giá trị tuyệt đối của sb. Chiều di chuyển là về cuối tệp nếu sb dương, trái lại nó sẽ di chuyển về đầu tệp. Khi thành công, hàm trả về giá trị 0. Khi có lỗi hàm trả về giá trị khác không.
  166. Chú ý: ◼ Không nên dùng fseek trên tệp tin văn bản, do sự chuyển đổi ký tự sẽ làm cho việc định vị thiếu chính xác. ◼ Ví dụ: fseek(stream, SEEK_SET, 0);
  167. Vị trí hiện tại của con trỏ chỉ vị - Hàm ftell Cú pháp: int ftell(FILE *fp); Nguyên hàm trong: stdio.h. Trong đó fp là con trỏ tệp. Công dụng: ◼ Hàm cho biết vị trí hiện tại của con trỏ chỉ vị (byte thứ mấy trên tệp fp) khi thành công. Số thứ tự tính từ 0. Trái lại hàm cho giá trị -1L. Sau lệnh fseek(fp,0,seek_end); ftell(fp) cho giá trị 3. Sau lệnh fseek(fp,-1,seek_end); ftell(fp) cho giá trị 2.
  168. Ghi các mẫu tin lên tệp - hàm fwrite Cú pháp: int fwrite(void *ptr, int size, int n, FILE *fp); Nguyên hàm trong: stdio.h. Trong đó: ◼ ptr là con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi. ◼ size là kích thước của mẫu tin theo byte ◼ n là số mẫu tin cần ghi ◼ fp là con trỏ tệp Công dụng: ◼ Hàm ghi n mẫu tin kích thước size byte từ vùng nhớ ptr lên tệp fp. ◼ Hàm sẽ trả về một giá trị bằng số mẫu tin thực sự ghi được.
  169. Đọc các mẫu tin từ tệp - hàm fread Cú pháp: int fread(void *ptr, int size, int n, FILE *fp); Nguyên hàm trong: stdio.h. Trong đó: ◼ ptr là con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi. ◼ size là kích thước của mẫu tin theo byte ◼ n là số mẫu tin cần ghi ◼ fp là con trỏ tệp Công dụng: ◼ Hàm đọc n mẫu tin kích thước size byte từ tệp fp lên lên vùng nhớ ptr. ◼ Hàm sẽ trả về một giá trị bằng số mẫu tin thực sự đọc được.
  170. Nhập xuất ký tự a)Các hàm putc và fputc Cú pháp: int putc(int ch, FILE *fp); int fputc(int ch, FILE *fp); ◼ Nguyên hàm trong: stdio.h, trong đó ch là một giá trị nguyên, fp là một con trỏ tệp. Công dụng: ◼ Hàm ghi lên tệp fp một ký tự có mã bằng m=ch % 256. ◼ ch được xem là một giá trị nguyên không dấu. Nếu thành công hàm cho mã ký tự được ghi, trái lại cho EOF.
  171. Các hàm getc và fgetc Cú pháp: int getc(FILE *fp); int fgetc(FILE *fp); ◼ Nguyên hàm trong: stdio.h, Trong đó fp là một con trỏ tệp. Công dụng: ◼ Hàm đọc một ký tự từ tệp fp. Nếu thành công hàm sẽ cho mã đọc được (có giá trị từ 0 đến 255). Nếu gặp cuối tệp hay có lỗi hàm sẽ trả về EOF. ◼ Trong kiểu văn bản, hàm đọc một lượt cả hai mã 13, 10 và trả về giá trị 10. Khi gặp mã 26 hàm sẽ trả về EOF.
  172. Xoá tệp - hàm unlink Cú pháp: int unlink(const char *tên_tệp) ◼ Nguyên hàm trong: dos.h, io.h, stdio.h, trong đó tên_tệp là tên của tệp cần xoá. Công dụng: ◼ Dùng để xoá một tệp trên đĩa ◼ Nếu thành công, hàm cho giá trị 0, trái lại hàm cho giá trị EOF.
  173. Các hàm truy nhập trực tiếp cổng inp, inpw, outp, outpw Một số hàm truy nhập trực tiếp cổng: ◼ inp: Đọc một byte từ cổng ◼ inpw: Đọc một từ (word - 2 byte) từ cổng ◼ outp: Ghi một byte ra cổng ◼ outpw: Ghi một từ (word – 2 byte) ra cổng Cú pháp: int inp(unsigned portid); unsigned inpw(unsigned portid); int outp(unsigned portid, int value); unsigned outpw(unsigned portid, unsigned value);
  174. Chú ý: ◼ Cả inp và inpw đều là các macro để đọc cổng được chỉ định vởi portid. ◼ Cả outp và outpw đều là các macro để ghi dữ liệu ra cổng được chỉ định vởi portid. ◼ inp đọc một byte. ◼ inpw đọc một từ 16-bit (Byte thấp của word đọc từ địa chỉ portid, byte cao đọc từ địa chỉ portid+1). ◼ outp ghi một byte ra cổng portid.
  175. Chú ý: ◼ outpw ghi byte thấp ra portid, và byte cao ra portid + 1, sử dụng một lệnh đơn OUT 16-bit. ◼ Khi gọi một trong các lệnh trên bắt buộc phải khai báo sử dụng thư viện conio.h Giá trị trả về ◼ inp và inpw trả về giá trị đọc được (1 byte) ◼ outp và outpw trả về giá trị ghi ra