Môn học lập trình C căn bản

Tham số được khai báo nhưkhai báo biếnmảng. -Cóthểkhông cầnxácđịnh sốphầntửcủamảng -Mảngđược chuyển tham chiếu Vd:Hàm xuấtnội dung mộtmảng các sốnguyên: void xuatMang(int a[], int N); Vd:Hàm nhậpnội dung mộtmảng các sốnguyên: void nhapMang(int a[], int &N);

pdf162 trang | Chia sẻ: tlsuongmuoi | Lượt xem: 2134 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Môn học lập trình C căn bản, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
iệc ngoài đời. • Mỗi công việc nhỏ hơn cũng có thể được chia nhỏ hơn nữa nếu nó còn phức tạp,... • Vấn đề mấu chốt của việc dùng máy tính giải quyết công việc ngoài đời là lập trình. 2. Thuật toán Thuật toán ) Là cách biểu diễn lời giải "bài toán“ rõ ràng, chi tiết để có thể thực thi được trên máy tính. ) Là một dãy hữu hạn các bước nhằm xác định các thao tác mà máy tính có thể thực hiện được sao cho sau khoảng thời gian hữu hạn thì cho ra kết quả. Â Bài toán giải phương trình bậc 1- 1 ẩn. (??) 9Các đặc trưng của thuật toán (1) - Tính hữu hạn: có hữu hạn bước và phải dừng. - Tính xác định: các bước rõ ràng, thực thi được. - Tính đúng: quá trình thực thi theo các bước đã chỉ ra phải đi đến kết quả như ý. - Tính hiệu quả: khối lượng, không gian, thời gian tính toán không quá “lớn”. - Tính tổng quát: áp dụng được cho mọi trường hợp của bài toán. Các đặc trưng của thuật toán (2) 10 Phương pháp biểu diễn thuật toán • Thuật toán thường được biểu diễn bằng các ngôn ngữ sau: – Dùng ngôn ngữ tự nhiên (NNTN) – Dùng mã giả (NNTN + NN LT) – Dùng lưu đồ - sơ đồ khối Biểu diễn bằng NNTN • Dùng ngôn ngữ thường ngày để liệt kê các bước của thuật toán. • Không thể hiện rõ cấu trúc của thuật toán • Dài dòng, có thể gây hiểu lầm hoặc khó hiểu • Không yêu cầu người viết hay đọc nắm quy tắc. − Không có một quy tắc cố định • Tính dễ đọc: − viết các bước con lùi vào bên phải − đánh số bước theo quy tắc phân cấp như 1, 1.1, ... 11 Biểu diễn bằng mã giả (1) • Vay mượn các cú pháp của một ngôn ngữ lập trình – dùng một phần ngôn ngữ tự nhiên – bị phụ thuộc vào ngôn ngữ lập trình. • Mọi ngôn ngữ lập trình đều có những thao tác cơ bản – xử lý, rẽ nhánh và lặp – tận dụng được các khái niệm trong ngôn ngữ lập trình, • Dễ dàng nắm bắt nội dung thuật toán Biểu diễn bằng mã giả (2) Một đoạn mã giả của thuật toán giải pt bậc hai if Delta > 0 then begin x1=(-b-sqrt(delta))/(2*a) x2=(-b+sqrt(delta))/(2*a) xuất kết quả : phương trình có hai nghiệm là x1 và x2 end else if delta = 0 then xuất kết quả : phương trình có nghiệm kép là -b/(2*a) else {trường hợp delta < 0 } xuất kết quả : phương trình vô nghiệm 12 Biểu diễn bằng lưu đồ (1) Đường đi Terminator Module – CT con Quyết định Xuất Xử lý Nhập Ý nghĩaBiểu tượng Biểu diễn bằng lưu đồ (2) • Công cụ trực quan diễn đạt thuật toán. – Biểu diễn bằng mô hình – hình vẽ • Theo dõi được: – sự phân cấp các trường hợp – quá trình xử lý của thuật toán • Phân biệt hai loại thao tác: – Chọn lựa theo một điều kiện nào đó – Xử lý, hành động 13 Biểu diễn bằng lưu đồ (3) • Chọn lựa theo một điều kiện nào đó: – Biểu diễn bằng một hình thoi, bên trong chứa biểu thức điều kiện. – Ví dụ: thao tác "nếu a = b thì thực hiện thao tác B2, ngược lại thực hiện B4" là thao tác chọn lựa a = b Δ = 0 Biểu diễn bằng lưu đồ (4) • Thao tác chọn lựa: có thể có hai hướng đi – một hướng ứng với điều kiện thỏa – một hướng ứng với điều kiện không thỏa. – 2 cung có nhãn • Đ/Đúng,Y/Yes • S/Sai,N/No 14 Biểu diễn bằng lưu đồ (5) • Xử lý, hành động: – Biểu diễn bằng một hình chữ nhật, bên trong chứa nội dung xử lý. – Ví dụ: "Chọn một môn học và in ra." là một thao tác thuộc loại hành động. tăng i lên 1 chọn 1 hộp bất kỳ Biểu diễn bằng lưu đồ (6) • Quá trình thực hiện các thao tác: – Đường đi – route – Biểu diễn bằng cung có hướng • nối giữa 2 thao tác: thực hiện lần lượt 15 Biểu diễn bằng lưu đồ (7) • Ðiểm cuối (terminator) – Biểu diễn bằng hình ovan – Điểm khởi đầu • chỉ có cung đi ra • bên trong ovan ghi chữ: bắt đầu/start/begin – Điểm kết thúc • Chỉ có cung đi vào • bên trong ovan ghi chữ: kết thúc/end • Mỗi lưu đồ chỉ có 1 điểm bắt đầu và 1 điểm kết thúc. Phương trình thuật toán giải pt bậc 2. Đường chấm ứng với trường hợp nghiệm kép, ví dụ: a=1,b=2,c=1 16 Biểu diễn bằng lưu đồ (8) • Điểm nối (connector) – Nối các phần khác nhau của một lưu đồ – Nối sang trang – Sử dụng với lưu đồ phức tạp • Giảm độ rắc rối • Đặt ký hiệu liên hệ giữa các điểm nối 3. Giải bài toán trên máy tính (1) Các bước giải quyết vấn đề, bài toán bằng máy tính điện tử (MTĐT): 1) Xác định vấn đề, bài toán: xác định rõ yêu cầu của bài toán, bài toán cho gì (Input) và yêu cầu tìm gì (Output). 2) Lựa chọn phương pháp giải: Có thể có nhiều cách khác nhau để giải bài toán. Các phương pháp có thể khác nhau về thời gian thực hiện, chi phí lưu trữ dữ liệu, độ chính xác, … => tùy theo nhu cầu cụ thể mà chọn phương pháp giải thích hợp. 17 3. Giải bài toán trên máy tính (2) 3) Xây dựng thuật toán: xây dựng mô hình chặt chẽ, chính xác hơn và chi tiết hơn cho phương pháp giải đã chọn. Xác định rõ ràng dữ liệu vào, ra cho các bước thực hiện cơ bản và trật tự thực hiện các bước đó. Nên áp dụng phương pháp thiết kế có cấu trúc, từ thiết kế tổng thể tiến hành làm mịn dần từng bước. 4) Cài đặt chương trình: mô tả thuật giải bằng chương trình. Dựa vào thuật giải đã được xây dựng, căn cứ quy tắc của một ngôn ngữ lập trình để soạn thảo ra chương trình thể hiện giải thuật thiết lập ở bước 3. 3. Giải bài toán trên máy tính (3) 5) Hiệu chỉnh chương trình: Cho chương trình chạy thử để phát hiện và điều chỉnh sai sót nếu tìm thấy. Có hai loại lỗi: lỗi cú pháp và lỗi ngữ nghĩa. 6) Thực hiện chương trình: Cho MTĐT thực hiện chương trình. Tiến hành phân tích kết quả thu được. Việc phân tích kết quả nhằm khẳng định kết quả đó có phù hợp hay không. Nếu không, cần kiểm tra lại toàn bộ các bước một lần nữa. 18 Bài tập Một công ty, mỗi giờ làm việc của một công nhân được trả 10,000 đồng/giờ trong 8 giờ đầu làm việc theo qui định. Nếu làm tăng ca (phải làm nhiều hơn 8 giờ qui định), thì mỗi giờ vượt qui định được trả thêm 30%. Tính tiền công cho một công nhân tùy theo giờ làm việc của họ. CHƯƠNG 2 CÁC KHÁI NIỆM CƠ BẢN Th.S Dương Thị Thùy Vân Khoa CNTT & TƯD 19 Nội dung 1. Ngôn ngữ lập trình 2. Chương trình dịch 3. Soạn thảo mã nguồn-Biên dịch-Liên kết và thực thi 4. Ví dụ chương trình C 5. Các thành phần của chương trình C đơn giản 1. Ngôn ngữ lập trình (1) • Con người liên lạc với nhau dùng: – ngôn ngữ tự nhiên: các mẫu từ ngữ và âm thanh • Con người “nói chuyện” với máy tính dùng: – Ngôn ngữ lập trình: tập từ ngữ và ký hiệu • Tuân theo các luật được gọi là cú pháp (syntax) • Có rất nhiều ngôn ngữ lập trình đang được sử dụng. 20 1. Ngôn ngữ lập trình (2) • Dựa vào mức độ chi tiết hóa việc mô tả các thao tác, người ta chia ngôn ngữ lập trình thành các lớp: – Ngôn ngữ máy, – Hợp ngữ, – Ngôn ngữ cấp cao. • Các ngôn ngữ cấp cao gần với ngôn ngữ tự nhiên nên rất tiện lợi cho việc mô tả các thao tác và dễ học, dễ nhớ. 1. Ngôn ngữ lập trình (3) Ngôn ngữ máy Hợp ngữ Ngôn ngữ cấp cao +1300042774 +1400593419 +1200274027 LOAD A ADD B STORE C C=A+B 21 Ngôn ngữmáy (1) • Là ngôn ngữ nền tảng của bộ vi xử lý, còn được gọi là mã máy. • Tập lệnh của ngôn ngữ máy phụ thuộc vào loại vi xử lý nên ngôn ngữ máy sẽ khác nhau trên những máy tính có sử dụng bộ vi xử lý khác nhau. • Các chương trình được viết bằng các loại ngôn ngữ khác cuối cùng đều được chuyển thành ngôn ngữ máy trước khi chương trình đó được thi hành. Ngôn ngữmáy (2) • Ưu điểm viết chương trình bằng ngôn ngữ máy: – điều khiển máy tính trực tiếp • đạt được chính xác điều mình muốn làm. • hiệu quả về tốc độ thi hành, kích thước chương trình nhỏ => ngôn ngữ máy cho phép khai thác triệt để khả năng của máy tính. • Bất lợi của chương trình ngôn ngữ máy – Tốn rất nhiều thời gian để viết, – Rất khó đọc, khó theo dõi để tìm lỗi – Chỉ chạy được trên những máy tính có cùng bộ vi xử lý. => ngôn ngữ máy được gọi là ngôn ngữ cấp thấp. 22 Hợp ngữ • Tương tự như ngôn ngữ máy nhưng sử dụng các ký hiệu gợi nhớ để biểu diễn cho mã lệnh của máy. • Cho phép định địa chỉ hình thức (dùng tên hoặc ký hiệu để tham chiếu tới một vị trí bộ nhớ) thay vì phải sử dụng địa chỉ thực sự (bằng con số nhị phân) như ngôn ngữ máy. • Được phát triển nhằm giúp lập trình viên dễ nhớ các lệnh của chương trình. • Các chương trình hợp ngữ được chuyển sang mã máy thông qua trình hợp dịch (assembler). Ngôn ngữ cấp cao • Hợp ngữ vẫn còn rất gần với từng thiết kế của máy tính. • Cần có những ngôn ngữ lập trình gần với ngôn ngữ tự nhiên hơn, được gọi là ngôn ngữ cấp cao. • Ngôn ngữ cấp cao bao gồm: danh từ, động từ, ký hiệu toán học, liên hệ và thao tác luận lý. Các yếu tố này có thể được liên kết với nhau tạo thành câu lệnh. • Ưu điểm viết chương trình bằng ngôn ngữ cấp cao: – Dễ đọc và dễ học – Không phụ thuộc vào máy tính 23 VD01 // Chuong trinh tinh bieu thuc y= 3e^cos(t+1) #include #include void main() { double t, y; cout<<”Moi ban nhap 1 so thuc t: ”; cin>>t; y= 3*exp(cos(t+1)); cout<<”Gia tri cua bieu thuc can tinh la: ”<< y; } Các thành phần của ngôn ngữ lập trình • Mỗi ngôn ngữ lập trình thường có ba thành phần cơ bản: – Bảng chữ cái: là tập hợp các kí tự được dùng khi viết chương trình, ngoài các kí tự này không được phép dùng bất kì kí tự nào khác. – Cú pháp: là bộ quy tắc để viết chương trình. Dựa vào chúng, người lập trình và chương trình dịch biết được tổ hợp nào của các kí tự trong bảng chữ cái là hợp lệ và tổ hợp nào là không hợp lệ. Nhờ đó, có thể mô tả chính xác thuật toán để máy thực hiện. – Ngữ nghĩa: xác định ý nghĩa thao tác cần phải thực hiện, ứng với mỗi tổ hợp kí tự và dựa vào ngữ cảnh của nó. 24 Ví dụ • Hầu như các ngôn ngữ lập trình đều có kí tự + chỉ phép cộng. Xét các biểu thức: A + B (1) I + J (2) • Giả thiết A, B là các biến thực và I, J là các biến nguỵên. • Khi đó dấu trong biểu thức (1) sẽ được hiểu là cộng hai số nguyên, dấu + trong biểu thức (2) sẽ được hiểu là cộng hai số thực. • Như vậy, cú pháp cho biết cách viết một chương trình hợp lệ, • Còn ngữ nghĩa xác định tính chất, thuộc tính của các tổ hợp kí tự trong chương trình. 2. Chương trình dịch • Chuyển đổi chương trình từ NN cấp cao (hợp ngữ) thành NN máy. • Có hai kỹ thuật chính: – Trình biên dịch (compiler), – Trình thông dịch (interpreter). 25 Trình biên dịch • Chuyển đổi toàn bộ chương trình sang ngôn ngữ máy và lưu kết quả vào đĩa để có thể thi hành về sau. – Chương trình nguồn (source program) là chương trình ngôn ngữ cấp cao được chuyển đổi. – Chương trình đối tượng (object program) là chương trình ngôn ngữ máy được tạo ra. • Thực hiện – Duyệt, kiểm tra cú pháp chương trình, – Kiểm tra logic và đảm bảo các dữ liệu sử dụng được định nghĩa hợp lý, – Phát hiện và tạo ra một danh sách lỗi cú pháp của các mệnh đề (statement). • Phương pháp dịch này thuận tiện cho các chương trình ổn định và cần thực hiện nhiều lần. Trình thông dịch • Lần lượt dịch và thực hiện từng câu lệnh một. • Mỗi lần chạy chương trình là mỗi lần chương trình nguồn được thông dịch sang ngôn ngữ máy. • Ưu điểm – Có thể chạy một chương trình vẫn còn lỗi cú pháp. • Nhược điểm – Chậm hơn các chương trình được biên dịch. • Phương pháp dịch này thích hợp cho môi trường đối thoại giữa người và hệ thống. • Đa số các ngôn ngữ cấp cao đều dùng trình biên dịch. 26 3. Soạn thảo mã nguồn – Biên dịch – Liên kết và thực thi (1) • Mỗi ngôn ngữ lập trình có một vài môi trường lập trình tương ứng. • Ví dụ ngôn ngữ C có các môi trường lập trình Turbo C, Borland C, Microsoft Visual C++, … • Môi trường lập trình cung cấp các dịch vụ như: – Soạn thảo mã nguồn, – Lưu trữ, tìm kiếm, – Xác định loại lỗi nếu có, chỉ rõ lỗi ở câu lệnh nào, – Cho xem các kết quả trung gian, – … 3. Soạn thảo mã nguồn – Biên dịch – Liên kết và thực thi (2) • Các môi trường lập trình khác biệt nhau ở các loại dịch vụ mà nó có thể cung cấp. • Đặc biệt là các dịch vụ mở rộng, nâng cấp, tăng cường các khả năng mới cho ngôn ngữ lập trình. • Khi biên dịch chương trình nguồn, người lập trình sẽ phát hiện được các lỗi cú pháp. • Khi liên kết và thực thi chương trình trên dữ liệu cụ thể thì mới phát hiện được các lỗi ngữ nghĩa. 27 3. Soạn thảo mã nguồn – Biên dịch – Liên kết và thực thi (3) hello.ocompile hellohello.c C libaray Link Source File (High-Level Languages) Object File (Machine Languages) Executable Edit Trình biên dịch 4. Ví dụ chương trình C /* Chương trình tính tổng các số tự nhiên từ 1 đến N */ #include int sum(int n); //khai bao ham void main() { int S, n; //biến lưu tổng và số n được cho ban đầu cout<<”Moi nhap vap so n: ”; cin>>n; S = sum(n); //gọi hàm tính tổng cout<<”Tong cac so tu nhien nho hon ”<<n << “ la: ”<< S; } int sum(int n) //Dinh nghia ham sum { int i, S =0; for (i=0; i<=n; i++) S = S+i; return S; } 28 Một số qui tắc khi viết chương trình C • Mỗi câu lệnh có thể viết trên một hay nhiều dòng nhưng phải được kết thúc bằng dấu “;”. • Chú thích có thể được viết trên một dòng, nhiều dòng hoặc trên phần còn lại của câu lệnh. • Khi sử dụng một hàm thư viện cần khai báo hàm ở đầu chương trình bằng cách toán tử #include, ví dụ: #include • Một chương trình chỉ có một hàm chính (main), có thể có thêm vài hàm khác (gọi là hàm con). 5. Các thành phần của chương trình C/C++ đơn giản (1) (1) #include yêu cầu trình biên dịch đọc tập tin chứa các khai báo như khai báo hàm thư viện mà chương trình dùng. VD: iostream.h → cout, cin, ... stdio.h → printf, scanf, ... math.h → sqrt, sin, log, pow, ... conio.h → getch, clrscr, ... 29 5. Các thành phần của chương trình C/C++ đơn giản (2) (2) Hàm chính, là thành phần buộc phải có trong mọi chương trình C. Dạng đơn giản: void main(){ } int main() { return 0; } main() { return 0; } (3) Định nghĩa dữ liệu và các phát biểu. - Các phát biểu là phần thực thi của chương trình. (đọc từ bàn phím, xuất ra màn hình, thực hiện tính toán, gọi hàm,...) - Các phát biểu được đặt giữa cặp ngoặc { và } của hàm (main), tạo nên “thân hàm”. - Mỗi phát biểu đơn (câu lệnh) được kết thúc bởi ‘;’ - Các phát biểu cùng được đặt giữa { và } tạo thành phát biểu ghép (còn gọi khối lệnh). 5. Các thành phần của chương trình C/C++ đơn giản (3) 30 (4) Khai báo hàm và định nghĩa hàm. Khai báo hàm là đưa ra một “mẫu hàm”, gồm tên và các tham số của hàm (kết thúc bởi ;). int sum(int n); Định nghĩa hàm gồm tên hàm, các tham số và thân hàm (chứa các phát biểu chương trình), thực thi một việc cụ thể. 5. Các thành phần của chương trình C/C++ đơn giản (4) (5) Các chú thích, được trình biên dịch “bỏ qua”, không ảnh hưởng đến việc thực thi của chương trình. Có hai loại chú thích: • Chú thích khối, chú thích là phần văn bản đặt giữa /* và */ • Chú thích dòng, chú thích là phần văn bản đặt ngay sau cặp kí tự: // 5. Các thành phần của chương trình C/C++ đơn giản (5) 31 Xuất dữ liệu (1) • cout là đối tượng xuất chuẩn, xuất dữ liệu ra màn hình. • Một phát biểu xuất kết quả ra màn hình, bao gồm: cout, phép toán xuất <<, đối tượng được xuất, và ‘;’. Một đối tượng được xuất có thể là: ─ Số nguyên (số thực) hay biến nguyên (biến thực). ─ Kí tự (một hằng kí tự được đặt giữa cặp dấu ‘ ’) hoặc biến kiểu kí tự. ─ Thông điệp gồm nhiều kí tự (chuỗi kí tự) được đặt giữa cặp dấu “ ”. Xuất dữ liệu (2) 32 Định dạng xuất, như: cho phép có bao nhiêu số ở phần thập phân, canh lề phải dữ liệu xuất... 33 • Nhiều phát biểu xuất có thể được nối lại thành một phát biểu xuất, khi đó cần lưu ý là trước mỗi đối tượng được xuất là một phép toán xuất và ngược lại. • Các đối tượng được xuất ra sẽ liên tiếp nhau trên cùng một dòng. • Nếu muốn một đối tượng được xuất ra trên một dòng mới thì gọi endl hay “\n” trong phát biểu xuất. Xuất dữ liệu (3) Nhập dữ liệu • cin là dòng nhập chuẩn, đọc dữ liệu được gõ từ bàn phím. • Dạng tổng quát: cin>> var; var là một biến nào đó • Phát biểu nhập có nhiều đối tượng: cin>>var1>>var2…>>varN 34 CHƯƠNG 3 BIẾN VÀ HẰNG ThS. Dương Thị Thùy Vân Khoa CNTT & TƯD Nội dung 1. Danh hiệu 2. Từ khóa 3. Kiểu dữ liệu 4. Khái niệm biến, vùng nhớ cho biến 5. Các kiểu cơ bản của biến 6. Định nghĩa kiểu với typedef 7. Định nghĩa biến và gán trị cho biến 8. Hằng 35 1. Danh hiệu (1) • Danh hiệu: được dùng để xác định các đại lượng khác nhau trong một chương trình như biến, hằng, hàm,… Là dãy kí tự liền nhau, gồm: - kí tự chữ - kí tự số - kí tự ‘_’ (underscore character). • Qui tắc (đặt tên): - Chỉ có thể bắt đầu với một kí tự chữ hoặc kí tự ‘_’ - Không trùng “từ khóa”. - Phân biệt chữ in, chữ thường. 1. Danh hiệu (2) Xét các ví dụ sau: DiemMon1 Dong$ 1HK _diemTB 123$ int diem HK 36 2. Từ khóa (key words) • Là những “tên” đã được định nghĩa bởi ngôn ngữ, dùng cho những mục đích khác nhau: static register goto struct continue return sizeof enum typedef unsigned if else switch case default char int long float double void do for while break 3. Kiểu dữ liệu • Xét tập N, Z, Q, R, C ?! • Kiểu dữ liệu (KDL) được xác định bởi: – tập giá trị, và – tập các phép toán tác động lên các phần tử thuộc tập giá trị ấy. • Đơn vị lưu trữ là byte. Mỗi giá trị thuộc một KDL được biểu diễn bởi một số byte nhất định. => Các giá trị biểu diễn được là hữu hạn. 37 • Là nơi lưu trữ dữ liệu trong bộ nhớ máy tính, được đặt bởi một tên. int a; • Mỗi biến chỉ có thể lưu một loại giá trị nhất định, tùy thuộc kiểu biến (KDL). 4. Khái niệm biến, vùng nhớ cho biến (1) 38 4. Khái niệm biến, vùng nhớ cho biến (2) • Giá trị của biến có thể thay đổi, nhưng tại mỗi thời điểm một biến chỉ lưu một giá trị. 4. Khái niệm biến, vùng nhớ cho biến (3) 39 5. Các kiểu dữ liệu cơ bản • Kiểu số nguyên (int) • Kiểu số thực – Số dấu phẩy động độ chính xác đơn (float) – Số dấu phẩy động độ chính xác kép (double) • Kiểu ký tự (char) Kiểu số nguyên (1) char unsigned char int unsigned int long unsigned long Biểu diễn hằng giá trị: 1234 (kiểu int) 1234U (kiểu unsigned int) 1234L (kiểu long) 1234UL (kiểu unsigned long) 40 Kết quả 41 Các phép toán trên số nguyên: + – * / % 9/4 → 2 1/2 → 0 9%5 → 4 Kiểu số nguyên (2) 42 Kết quả Các tiếp đầu ngữ: long, short, signed, unsigned với kiểu nguyên: short int → short signed int ≡ int unsigned int → unsigned long int →long Kiểu số nguyên (3) 43 Kiểu số thực (1) float double Hai cách biểu diễn số thực: - Dạng thập phân: phần nguyên & phần phân. 12.345 -0.02468 - Dạng chấm động: phần định trị & phần mũ. 1.2345e+01 -2.468e-02 Biểu diễn hằng giá trị: 12.34 (kiểu double) 1.234e+01 12.34F (kiểu float) 1.234e+01F • Các phép toán trên số thực: + – * / • Độ chính xác: float: 7 chữ số thập phân double: 15 chữ số thập phân ⇒ Kiểu double được lưu ý sử dụng: - Tính toán với số lớn. - Cần độ chính xác cao. Kiểu số thực (2) 44 Kết quả 45 Kiểu kí tự (1) Biểu diễn hằng kí tự: ‘a’, ‘4’, ‘@’,... Tập giá trị (1 byte, mã hoá được 256 kí tự): Kí tự chữ (‘a’, ‘S’,...) Kí tự số (‘0’,..,‘9’) Dấu (‘@’,‘?’,..) Kí tự điều khiển (‘\n’, ‘\t’,...) Kí tự đặc biệt. \r carriage return\v vertical tab \" double quote\t horizontal tab \' single quote \n newline \? question mark\b backspace \\ backslash Một vài kí tự điều khiển: \a alert (bell) Kiểu kí tự (2) 46 • Mỗi kí tự được lưu với một số nguyên, và theo một thứ tự nhất định gọi là bộ mã. • Bộ mã được dùng phổ biến là bộ mã ASCII: ‘a’ = 97 ‘A’ = 65 ‘0’ = 48 ‘@’ = 64 ... Kiểu kí tự (3) Bảng mã ASCII 47 Kết quả 48 Các phép toán như đối với trên số nguyên: + – * / % ) Thực hiện trên mã ASCII của kí tự tương ứng: char c= ‘A’; //c= 65 cout<<c+1; → 66 c= c+1; cout<<c; → ‘B’ c= c/2; cout<<c; → ‘!’ cout<<‘a’ – ‘A’; → 32 cout<<‘8’ – ‘3’; → 5 Kiểu kí tự (4) 6. Định nghĩa kiểu với typedef - Một khai báo có thêm tiền tố typedef sẽ định nghĩa một tên mới cho KDL (đã có). typedef KDL tenMoi; - Một tên được định nghĩa theo cách này được gọi là “định nghĩa kiểu”. 49 typedef long SoNg32; typedef short int SoNg16; typedef char KITU; Ví dụ 50 7. Định nghĩa biến và gán trị • Định nghĩa biến (khai báo biến) là đặt tên và xác định kiểu biến. • Mọi biến cần phải được khai báo trong chương trình trước khi sử dụng. • Để định nghĩa một biến, dạng khai báo: KDL tenBien; • Định nghĩa nhiều biến cùng kiểu: KDL bien1, bien2, bienN; • Phép gán “=“ để thay đổi giá trị biến. tenBien = giatri; 51 Kết quả 52 Gán trị cho biến (1) • Gán liên tiếp là gán cho nhiều biến cùng lúc sau khi đã khai báo các biến. Ví dụ: int a, b; a = b = 6; b = (a= 3)+2; • Khởi gán là gán trị cho biến ngay khi khai báo biến đó. Ví dụ: double x = 1.1234; Gán trị cho biến (2) • Gán kép và khởi gán: int a = b = 6; • Chú ý phân biệt: double x= 1.0, y= 2.0, z= 1.5; int a, b; a = b = 6; int a = b = 6; int m = 3, n = 3; 53 8. Hằng •Là đại lượng không đổi trong suốt quá trình thực thi của chương trình •Phân biệt: •Hằng biến •Hằng thực sự •Hằng ký hiệu •Định nghĩa hằng dùng từ khóa: •const, define, enum Định nghĩa hằng dùng từ khóa const const KDL TenHang = giaTriHang; Ví dụ: const float PI= 3.1459; const int DVHT_m1 = 10; 54 55 Khi không định kiểu hằng, hằng có kiểu mặc định là kiểu int 56 Kết quả #define TenHang giaTriHang Chú ý: Không dùng ‘;’ Không dùng phép gán = Một định nghĩa chỉ một hằng Ví dụ: #define PI 3.1459 #define DVHT_m1 10 #define DVHT_m2 8 Định nghĩa hằng ký hiệu, dùng từ khóa define 57 Kết quả 58 Hằng liệt kê, dùng từ khóa enum (1) • Dùng khi có muốn định nghĩa nhiều hằng nguyên. • Mặc định các giá trị hằng liên tiếp nhau, bắt đầu là 0. enum { false, true }; enum { auto, remote, hand }; enum { hang1, hang2,…, hangN } 59 Kết quả - Định trị bắt đầu của danh sách hằng: enum { auto= -1, remote, hand }; enum { Mon= 2, Tue, Wed, Thu, Fri, Sat, Sun }; Hằng liệt kê, dùng từ khóa enum (2) 60 Kết quả 61 - Định trị cho từng tên hằng: enum { auto=-1, remote= 2, hand= 5 }; enum { start= ‘A’, mid=‘M’, end= ‘Z’ }; Hằng liệt kê, dùng từ khóa enum (3) 62 Kết quả Tham chiếu (1) • Mẫu khai báo: KDL & ref = var; Ví dụ: int n = 3; int &r = n; 3 n r • Là một tên gọi khác để truy cập đến cùng địa chỉ (vùng nhớ) với biến đã có. 63 Được sử dụng chính: - Đối với tham số của hàm. - Trong kiểu trả về của hàm. - Cho các phép toán “nạp chồng”. Tham chiếu (2) 64 Kết quả 65 Kết quả 66 Kết quả • Không tham chiếu đến biến khác kiểu. double x; int &n = x; //??? • Không tham chiếu đến hằng. const int a = 5; int &r = a; //??? int &t = 7; //??? Tham chiếu (2) 67 Tham chiếu đến biến khác Kết quả 68 Bài tập 1 xx 2vars var-2 ban_kinh x^2 BANKINH dong_$ chieu dai chieu rong DienTich Bài tập 2 int a, b, dienTich, chuVi; const double Pi = 3.14159 const long rate = 16019L; float chieu dai, chieu rong; char t= ‘a’; char ho= ‘nguyen’; int a= b= 2, S, C; 69 Bài tập 3 #define PI= 3.14159 double R= 2, dT, cV; double diem_m_1, diem-mon-2, dTB; const dvht 1= 3, dvht 2= 4; char ten= “nam”; long tien = 100000 LẬP TRÌNH C CĂN BẢN Th.S: Dương Thị Thùy Vân Khoa CNTT & TƯD 70 CHƯƠNG 4 PHÉP TOÁN VÀ BIỂU THỨC Nội dung 1. Khái niệm biểu thức 2. Phép toán 3. Phép toán số học 4. Phép toán quan hệ 5. Phép toán luận lý 6. Chuyển kiểu 7. Tăng và giảm 8. Phép gán và biểu thức gán 9. Thứ tự thực hiện phép toán 71 1. Khái niệm biểu thức • Là sự kết hợp hợp lệ giữa các toán hạng và toán tử để diễn đạt một công thức toán học nào đó, cho một kết quả duy nhất sau cùng. Ví dụ: delta= b*b – 4*a*c; pi= 4*atan(1.0); • Biểu thức với toán tử là phép toán số học → biểu thức số học • Với phép toán quan hệ & luận lí → biểu thức quan hệ & luận lí. • Trong C, các phép toán có thể phân ra thành 3 loại chính: phép toán số học, phép thao tác bit, phép toán quan hệ và luận lý. • Phép toán 1 ngôi, còn gọi là phép toán 1 toán hạng. • Phép toán 2 ngôi, còn gọi là phép toán 2 toán hạng. • Độ ưu tiên của phép toán qui định trình tự tính toán trong biểu thức. Ví dụ: a = - 9/2*2 - 2 – 7%5; 2. Phép toán 72 3. Phép toán số học • Các phép toán số học 1 ngôi: + - • Các phép toán số học 2 ngôi: * / % + - • Phép chia nguyên và chia không nguyên: / Ví dụ: 11/2 = 5 11/2.0 = 5.5 • Phép toán % cho phần dư của phép chia nguyên. • Phép toán % không áp dụng được cho các giá trị kiểu float và double. 4. Phép toán quan hệ • Phép toán quan hệ: > = == != • Phép toán quan hệ cho ta hoặc giá trị đúng (1) hoặc giá trị sai (0). Ví dụ: if (a>b) cout<<a<<” la so lon hon !”; if (b!=0) cout<<a/b; • Các phép toán quan hệ có độ ưu tiên thấp hơn so với các phép toán số học. 73 5. Phép toán luận lí • Phép toán luận lí: && || ! and or not • Phép toán luận lý cho ta hoặc giá trị đúng (1) hoặc giá trị sai (0). Ví dụ: 3 && 7 có giá trị 1 • Các phép toán quan hệ và luận lí được dùng để thiết lập điều kiện rẽ nhánh trong toán tử if và điều kiện kết thúc chu trình trong các toán tử for, while và do-while. • Trong một biểu thức, các toán hạng khác kiểu sẽ phải chuyển sang cùng kiểu để tính toán. • Chuyển kiểu tự động và chuyển kiểu tường minh. − (1) Việc tự động chuyển kiểu được thực hiện từ toán hạng có kiểu “hẹp” sang kiểu “rộng” hơn. Ví dụ: x = - 9.0/4*2/2 - 2 – 7%5; y = - 9.0/4*2%2 - 2 – 7%5; //?? 6. Chuyển kiểu (1) 74 6. Chuyển kiểu (2) • Với phép gán, kết quả của biểu thức bên phải sẽ được chuyển thành kiểu của biến bên trái. Ví dụ: float x; x = 3/4.0 + 2; int y; y = 3/4.0 + 2; 75 Kết quả (2) Chuyển kiểu tường minh: Buộc kiểu của biểu thức chuyển sang kiểu khác. (KDL)BTh KDL(BTh) Ví dụ: long a= 300000 + (long)400000; double x= double(3)/4*4.0f; double y= double(1/2)*100; //?? long s= s + long(n)*17000; 6. Chuyển kiểu (3) 76 ??? Kết quả 77 Kết quả 78 Kiểu bool (1) • Kiểu bool được dùng để biểu diễn kết quả của biểu thức luận lí, cho kết quả là đúng (true) hoặc sai (false). • Ngôn ngữ C không định nghĩa tường minh kiểu bool, được dùng thông qua kiểu số nguyên. − Kết quả biểu thức là true ⇒ giá trị là 1 − Kết quả biểu thức là false ⇒ giá trị là 0 int a, b, c; cin>>a>>b; c= a>b; //c= 0 or 1 - Giá trị biểu thức là ≠ 0 ⇒ KQ ứng là true - Giá trị biểu thức là = 0 ⇒ KQ ứng là false if (b) cout<<a/b; Kiểu bool (2) 79 Kiểm tra một năm y có phải là năm nhuận ? Biết năm là nhuận nếu là năm chia hết cho 400 hoặc chia hết cho 4 nhưng không chia hết cho 100. int y; cout<<“Ban hay nhap mot nam: “; cin>>y; if ((y%4==0 && y%100!=0)||y%400 == 0) cout<<y<<“ la nam nhuan !”; else cout<<y<<“ khong la nam nhuan !”; Ví dụ 1 Kiểm tra a, b, c có thể là 3 cạnh của một tam giác ? Tổng chiều dài của hai cạnh bất kì luôn lớn hơn chiều dài cạnh còn lại. int a, b, c; cout<<“Ban hay nhap 3 so nguyen: “; cin>>a>>b>>c; if ( a+b>c && a+c>b && c+b>a ) cout<<“Thoa 3 canh mot tam giac!”; else cout<<“Khong thoa ... ”; ⇒ Làm lại cách khác dùng mệnh đề và phép phủ định !! Ví dụ 2 80 Tính tổng S = 1+3+5+...n ? (n ≥ 0) int n, S = 0; cout<<“Ban hay nhap so nguyen duong: “; cin>>n; for (int i= 1; i<n; i=i+2) S = S+i; cout<<“Tong so le nho hon n: S =”<<S; Ví dụ 3 Toán tử sizeof • Cho biết kích thước (theo byte) của kiểu dữ kiệu cơ sở (hoặc của một đối tượng cụ thể). Ví dụ: int n= sizeof(long); //n= 4 1= sizeof(char) ≤ sizeof(short) ≤ <= sizeof(int) ≤ sizeof(long) 81 7. Phép tăng và giảm (1) • Nếu phép tăng (ký hiệu ++) đặt ngay trước tên biến, là phép toán “tăng trước”. • Tương tự, phép giảm (ký hiệu --) đặt ngay trước tên biến, là phép toán “giảm trước”. • Giá trị của biến được tăng (giảm) 1 đơn vị, sau đó giá trị mới này được dùng trong biểu thức mà biến xuất hiện. int a= 5, b= 6, c; c= ++a + b; c= a * --b; • Nếu phép tăng đặt ngay sau tên biến, là phép toán “tăng sau”. • Nếu phép giảm đặt ngay sau tên biến, là phép toán “giảm sau”. • Giá trị hiện tại của biến được dùng trong biểu thức mà nó xuất hiện, sau đó giá trị của biến mới được tăng (giảm) 1 đơn vị. int a= 5, b= 6, c; c= a++ + b; c= a * b--; 7. Phép tăng và giảm (2) 82 8. Phép gán và biểu thức gán (1) • Phép gán “=“ để thay đổi giá trị biến: tenBien = giatri; • Chú ý phân biệt toán tử gán với khái niệm đẳng thức trong toán học. • Biểu thức gán là biểu thức có dạng: v = e • Trong đó v là một biến, e là một biểu thức.Giá trị của biểu thức gán là giá trị của e, kiểu của nó là kiểu của v. 83 8. Phép gán và biểu thức gán (2) • Nếu đặt dấu ; vào sau biểu thức gán thì ta được toán tử gán: v = e; • Biểu thức gán có thể sử dụng trong các phép toán và các câu lệnh như các biểu thức khác. Ví dụ 1: a = b = 5; thì điều đó có nghĩa là gán giá trị của biểu thức: b = 5 cho biến a. Kết quả là b = 5 và a = 5. • Ví dụ 2: Sau khi thực hiện câu lệnh z = (y = 2)*(x = 6); thì y có giá trị 2, x có giá trị 6 và z có giá trị 12. 8. Phép gán và biểu thức gán (3) • Phép toán kết hợp là phép gán cùng với phép toán, tác động lên chính biến được gán. += -= *= /= %= &= |= ^= >= Ví dụ: i += 2; //⇔ i = i + 2; a *= b+1 //⇔ a = a*(b + 1); a <<= 1 //⇔ a = a<<1; 84 85 9. Thứ tự thực hiện phép toán • Khi thực hiện tính toán trong một biểu thức, phép toán có độ ưu tiên cao hơn sẽ thực hiện trước. b= (a= 3)+2; b= a= 3 + 2; n= 18/4*4; • Bảng sau cho biết độ ưu tiên phép toán (thứ tự giảm dần). • Trừ phép gán và phép 1 toán hạng, các phép cùng cấp sẽ ưu tiên trái hơn. = += -= *= /= %= &= |= ^= >= Phép gán (←) && ||& | ^Phép toán luận lí == != >=Phép toán quan hệ >> <<+ –Cùng cấp phép cộng * / %Cùng cấp phép nhân ! ~ ++ -- + - (type) sizeof Phép một toán hạng (←) ( )Ngoặc đơn Ưu tiên giảm dần 86 Ví dụ (3.0/4 < 4.0/5) && (‘a’ < ‘b’) (3/4 < 4/5) && (‘a’ < ‘b’) !(48.5+2 4/2) !(48.5+2 4/2) n&1==0 Bài tập • Giá trị của x là 10, x và a là bao nhiêu sau khi thực thi: a = x++; • Giá trị của x là 10, x và a là bao nhiêu sau khi thực thi: a = ++x; 87 CHƯƠNG 5 CÁC CẤU TRÚC ĐIỀU KHIỂN CHƯƠNG TRÌNH Nội dung 1. Phát biểu 2. Phát biểu if 3. Phát biểu switch 4. Phát biểu while 5. Phát biểu for 6. Phát biểu do-while 7. Phát biểu break 8. Phát biểu continue 88 • Cấu trúc điều khiển xác định thứ tự các phát biểu được thực thi. • Cấu trúc “chọn” (if, switch) biểu diễn các “quyết định” • Cấu trúc “lặp” (for, while) cho phép lặp lại nhiều lần việc thực thi các phát biểu Cấu trúc điều khiển 1. Phát biểu • Một biểu thức trở thành một phát biểu khi nó được kết thúc bởi dấu “;”, được gọi là phát biểu đơn. • Các dấu { và } dùng để nhóm các khai báo và phát biểu đơn → phát biểu ghép hay phát biểu khối. • Về mặt cú pháp, phát biểu khối tương đương một phát biểu đơn. • Phát biểu khối được dùng trong định nghĩa hàm, dùng với các phát biểu if, else, while, for,... 89 2. Phát biểu if (1) expr statement1statement2 ... other statements S Đ Dạng của phát biểu if: if (expr) statement; Chỉ khi kết quả của expr là TRUE (giá trị của expr ≠ 0), thì statement được thực thi. 2. Phát biểu if (2) 90 91 92 • Phát biểu if có thể có phần else: if (expr) statement_1a; else statement_1b • Nếu phát biểu ứng với phần if được thực thi, phần else của if đó sẽ không được xét đến. expr stat1stat2... other stats S Đ stat1bstat2b... 2. Phát biểu if (3) 93 94 95 96 97 Toán tử điều kiện ? : expr stat1 S Đ stat1b ( expr ? stat1 : stat2 ) • Kết quả biểu thức là stat1 nếu expr có giá trị ≠0 (TRUE), kết quả là stat2 nếu ngược lại. Tìm max{a, b} ? m = a>b ? a : b; Tìm |a| ? m = a>0 ? a : -a; Toán tử điều kiện ? : 98 Xét mối tương quan giữa a và b: coutb ? "a la so lon hon !" : "b la so lon hon !"); a>b ? cout<<a<<" la so lon hon !" : cout<<b<<" la so lon hon !"; Toán tử điều kiện ? : 3. Phát biểu switch (1) expr == val_1 S Đ stats(1) ... stats(N+1) expr == val_2 expr == val_N stats(2) stats(N) Đ Đ S S 99 switch (expr) { case val_1: stats(1); break; case val_2: stats(2); break; //... case val_N: stats(N); break; default: stats(N+1); } Các hằng nguyên không trùng nhau 3. Phát biểu switch (2) Ví dụ 100 • switch → chương trình chọn lựa một trong nhiều phương án khác nhau tùy thuộc kết quả của biểu thức so sánh bằng. - Mỗi val_1,..., val_N là một hằng nguyên. - Các giá trị val_i không trùng nhau. - Mỗi stats(i) gồm một hay nhiều phát biểu. - break: kết thúc thực thi và thoát khỏi switch. 3. Phát biểu switch (3) Ví dụ 101 102 103 Ví dụ Ví dụ 104 Bài tập 1 • Hãy cho biết, khi nào thì phần else trong đoạn chương trình sau được thực hiện ? if (n > 0) for (i = 0; i < n; i++) if (a[i] > 0) { cout<<" !!! "; return i; } else cout<<”n phai duong !"; Bài tập 2 • Hãy cho cho biết, có lỗi nào trong chương trình sau ? #include void main() { int x; cin>>x; if( x > 0) cout<<" x duong !"; else (x < 0) cout<<" x am !"; else cout<<” x khong am khong duong !”; } 105 Bài tập 3 • Hãy sửa đoạn chương trình sau đây (sửa ít nhất có thể) sao cho kết quả nhận được là hợp lí ? #include void main() { int x= 1: if( x = 1); cout<<" x bang 1"; otherwise cout<<" x khac 1"; } 4. Phát biểu while (1) expr statement1 statement2 ... other statements S Đ 106 Dạng của phát biểu while: while (expr) { //statements; } 4. Phát biểu while (2) 107 • Khi while thực thi : B1. Tính toán biểu thức expr. B2. Nếu kết quả của expr là TRUE (≠0), thì sang B3. Nếu kết quả của expr là FALSE (=0), thì sang B4. B3. Thực thi statement1, statement2,… thân của while. Quay trở về B1. B4. Kết thúc while. (các phát biểu sau while tiếp tục thực thi). 4. Phát biểu while (3) 108 109 • Cần xác định các yếu tố: - Điều kiện lặp = điều kiện “làm” ≠ điều kiện “dừng”. - Làm những gì ? - Yếu tố làm expr thay đổi ? 4. Phát biểu while (4) Tính tổng: n S 1... 3 1 2 11 ++++= Lặp không dừng !! 110 S = 1 (?!!) 111 Có bao nhiêu số dương < N chia hết cho 3 ? Hãy cho biết số nguyên N có bao nhiêu chữ số ? n = 7023 n = 702 n = 70 n = 7 n = 0 (1) (2) (3) (4) /10 /10 /10 /10 112 ??? 113 dem = (n==0); 114 ??? 115 BThuc CacPhatBieu PhatBieuKhac S Đ dem = gtbd dem += gtbn 5. Phát biểu for (1) • Dạng của phát biểu for: for ( i = gtbd; BieuThuc; i += gtbn) { //Cac phat bieu } 5. Phát biểu for (2) 116 Tính tổng: S= 1 + +2 + ... + n Tính tổng: n S 1... 3 1 2 11 ++++= 117 Cấu trúc lặp for dựa trên biến đếm với giá trị khởi đầu, thay đổi biến đếm và biểu thức. Dạng: for ( gán trị đầu cho biến đếm ; biểu thức ; thay đổi giá trị biến đếm theo bước nhảy ) { //Cac phat bieu } 5. Phát biểu for (3) • Khi phát biểu for thực thi: B1. Gán trị ban đầu: dem = gtbd B2. Tính toán biểu thức BThuc. B3. Nếu BThuc là TRUE (≠0), thì sang B4. Nếu BThuc là FALSE (=0), thì sang B6. B4. Các phát biểu (CacPhatBieu) thân của for thực thi. B5. Thay đổi giá trị biến đếm (dem += gtbn). Quay trở về B2. B6. Kết thúc for, PhatBieuKhac sau for tiếp tục thực thi 5. Phát biểu for (2) 118 (1) (2) (3) (4) (i>n) 119 Có bao nhiêu số dương < N chia hết cho 3 ? (1) (2) (3) (4) (i≤n) 120 Hãy cho biết số nguyên N có bao nhiêu chữ số ? 121 Không nên !! 122 expr statement1 statement2 ... other statements S Đ 6. Phát biểu do-while (1) 123 Phát biểu do-while tính biểu thức sau thực thi các phát biểu trong phần thân. Dạng: do { //statements } while ( expr ); 6. Phát biểu do-while (2) 124 • Khi phát biểu do-while thực thi: B1. Các phát biểu (statements) thân của do-while thực thi. B2. Tính toán biểu thức expr. B3. Nếu expr là TRUE (≠0), quay trở về B1. Nếu expr là FALSE (=0), kết thúc do-while. (Các phát biểu khác sau while tiếp tục thực thi) ⇒ Như vậy, thân của do-while thực hiện ít nhất 1 lần. 6. Phát biểu do-while (3) 125 Nhập đến đâu cộng đến đó !?!! 126 • Phát biểu break kết thúc cấu trúc lặp gần nhất mà nó xuất hiện trong đó, không cần biết kết quả của expr • Được dùng trong trường hợp thoát khỏi vòng lặp mà không dùng đến điều kiện dừng. • Phát biểu break thường xuất hiện cùng với phát biểu if. • break còn được dùng để thoát khỏi switch, nếu các nhóm lệnh (case i) không được kết thúc bằng break thì máy có thể đi từ case i sang case i+1. 7. Phát biểu break 127 128 • Phát biểu continue dùng để bắt đầu một lần lặp mới của cấu trúc lặp gần nhất mà nó xuất hiện trong đó. Cụ thể: – Khi gặp continue bên trong phát biểu for, máy sẽ chuyển tới bước 5 trong “sự hoạt động của for” (slide 63). – Khi gặp continue bên trong phát biểu while hoặc do-while, máy sẽ chuyển tới bước tính toán biểu thức (bước 1 trong while, bước 2 trong do-while). • Phát biểu continue thường xuất hiện cùng với phát biểu if. 8. Phát biểu continue 129 CHƯƠNG 6 HÀM 130 Nội dung 1. Chương trình con 2. Khai báo hàm và định nghĩa hàm 3. Gọi hàm 4. Truyền tham số 5. Giá trị trả về 6. Phạm vi của biến 7. Biến mảng 8. Biến mảng là tham số của hàm 1. Chương trình con (1) • Chương trình con: là một phần mã trong một chương trình lớn hơn, phần mã này thực hiện một tác vụ cụ thể và tương đối độc lập với phần mã còn lại. • Một chương trình con thường được viết mã sao cho nó có thể được gọi nhiều lần từ nhiều nơi trong thời gian chạy của một chương trình (có thể được gọi bởi chính nó). • Các chương trình con thường được tập trung thành các thư viện, là một cơ chế quan trọng cho việc chia sẻ và tái sử dụng mã. 131 • Chương trình con có 2 loại: Thủ tục (Procedure) và hàm (Function): – Thủ tục (PROCEDURE): Dùng để thực hiện một hay nhiều nhiệm vụ nào đó. – Hàm (FUNCTION): Trả về một giá trị nào đó (có kiểu vô hướng, kiểu string hoặc kiểu con trỏ). Hàm có thể sử dụng trong các biểu thức. 1. Chương trình con (2) 1. Chương trình con (3) • Khi nào thì nên dùng thủ tục/hàm: – Dùng hàm: • Kết quả của bài toán trả về 1 giá trị duy nhất (kiểu vô hướng, kiểu string hoặc kiểu con trỏ). • Phát biểu gọi CHƯƠNG TRÌNH CON cần nằm trong các biểu thức tính toán. – Dùng thủ tục: • Kết quả của bài toán không trả về giá trị nào hoặc trả về nhiều giá trị hoặc trả về kiểu dữ liệu có cấu trúc (Array, Record, File). • Phát biểu gọi CHƯƠNG TRÌNH CON không nằm trong các biểu thức tính toán. 132 1. Chương trình con (4) • Chương trình con được dùng khi xây dựng các chương trình lớn nhằm: – giảm đáng kể kích thước và chi phí của một chương trình – làm cho chương trình dễ theo dõi, – dễ sửa chữa, – nâng cao độ tin cậy của chương trình. • Một đặc điểm nổi bật của chương trình con là nó có tính đệ quy nhờ thế mà nhiều bài toán được giải quyết dễ dàng. • Chương trình con trong ngôn ngữ C là hàm. 2. Khai báo hàm, định nghĩa hàm (1) • Định nghĩa hàm gồm tên hàm, các tham số và thân hàm (chứa các phát biểu chương trình), thực thi một việc cụ thể. • Dạng định nghĩa hàm: 133 2. Khai báo hàm, định nghĩa hàm (2) trong đó: – Kiểu trả về (return_type, còn gọi là kiểu hàm) tương ứng với kiểu của giá trị mà hàm trả về thông qua phát biểu return. – Tên hàm (func_name) được đặt theo nguyên tắc đặt tên, nhưng nên đặt tên sao cho dễ hiểu. – ParameterList là danh sách tham số, mỗi tham số được xác định bởi kiểu dữ liệu và tên. Các tham số phân cách nhau bởi dấu phẩy. Có thể là danh sách rỗng. – Phần thân hàm nằm giữa cặp ngoặc { và }. 2. Khai báo hàm, định nghĩa hàm (3) • Nếu không xác định return_type, mặc định sẽ là kiểu int. • Nếu hàm không trả về giá trị, dùng void (thay cho return_type). • Không được phép đặt định nghĩa hàm này trong một hàm khác. • Các hàm được định nghĩa không phải theo một thứ tự nào. • Nếu có phát biểu gọi hàm trước khi hàm được định nghĩa thì cần có một khai báo hàm trước lời gọi hàm đó. 134 135 2. Khai báo hàm và định nghĩa hàm • Khai báo hàm là đưa ra một “mẫu hàm”, mô tả tên hàm, kiểu trả về và danh sách tham số. • Kết thúc khai báo hàm với dấu chấm phẩy “;”. • Dạng khai báo hàm: return_type func_name (ParameterList) • Xét các ví dụ sau: void f1(int i, int j, float k); void f2(int a, b, float c); //?? f3(); 3. Gọi hàm • Chỉ với định nghĩa hàm, hàm đó chưa thực thi. Hàm chỉ thực thi khi nó được gọi. • Để “yêu cầu” một hàm thực thi, ta “gọi” tên hàm cùng với các tham số thực sự: func( arg1, arg2,…); //Lưu ý: không có kiểu dữ liệu 136 Tham số trong chương trình con • Chương trình con có thể không cần tham số mà chỉ có các biến riêng (biến cục bộ). • Trường hợp cần chuyển các giá trị cho hàm khi gọi hàm thì cần định nghĩa danh sách tham số của hàm, còn gọi là các tham số hình thức. • Mỗi giá trị thực chuyển cho hàm khi gọi hàm được gọi là đối số (hay tham số thực). • Mỗi khi gọi hàm, có thể chuyển các đối số khác nhau. 4. Truyền tham số (1) • Để một hàm thực thi, cần gọi hàm với tên và chuyển các đối số tương ứng với danh sách tham số hình thức cả về kiểu và thứ tự. • Truyền bằng tham trị: – Là khi giá trị của đối số được sao chép vào cho tham số hình thức. Như vậy, các thay đổi cho tham số hình thức (trong hàm) không làm thay đổi đối với tham số thực. – Mặc định, với cách khai báo danh sách tham số với kiểu và tên, ta có cách chuyển tham trị. 137 4. Truyền tham số (2) • Truyền bằng tham chiếu: – Khi muốn tham số hình thức và tham số thực cùng địa chỉ (bản chất là cùng ô nhớ nhưng khác tên), ta dùng cách chuyển tham chiếu cho hàm. – Khai báo tham số của hàm với kí tự ‘&’ ngay trước tên (giữa KDL và tên). – Như vậy, mọi thay đổi đối với tham số hình thức cũng làm thay đổi tham số thực. – Có thể dùng chuyển tham chiếu để trả về giá trị cho nơi gọi hàm. Ví dụ • So sánh 2 hàm hoán vị sau đây, dùng chuyển tham chiếu và tham trị: void main() { int x= 3, y= 4; cout<<x<<’ ‘<<y<<endl; hoanVi_1(x, y); cout<<x<<’ ‘<<y<<endl; hoanVi_2(x, y); cout<<x<<’ ‘<<y<<endl; } //Nhận xét các giá trị được in ra void hoanVi_1(int a, int b) { int t= a; a= b, b= t; } void hoanVi_2(int &a, int &b) { int t= a; a= b, b= t; } 138 5. Giá trị trả về • Một hàm không trả về giá trị khi hàm được khai báo có kiểu là void. • Ngược lại, hàm phải trả về giá trị có kiểu cùng với kiểu trả về đã khai báo. • Phát biểu return nhằm dừng thực thi hàm, trở về nơi gọi nó; và còn được dùng để trả giá trị (tính toán được) về cho nơi gọi hàm. • Trong một hàm, có thể có nhiều phát biểu return, nhưng chỉ 1 phát biểu return được thực thi. • Trong một phát biểu return chỉ có 1 giá trị được trả về. Ví dụ: • Trong các định nghĩa hàm sau đây, có những định nghĩa hàm không hợp lệ. void f4() { return;} int f5() { return 0;} int f6(){ return 0.5;} //? int f1() {} //? void f2() { return 0;} //? int f3() { return ; } //? void main() { int n; cout<<”Hay nhap 1 so nguyen:”; cin>>n; if (IsPrime(n) == 1) cout<<n<<”la so nguyen to”; else cout<<n<<”KHONG la so nguyen to”; } int IsPrime(int n) { if (n <= 1) return 0; for (int i= 2; i<n; i++) if (n%i == 0) return 0; return 1; } 139 6. Phạm vi của biến • Có 3 nơi cơ bản mà biến được khai báo: – trong một hàm, – trong định nghĩa danh sách tham số của hàm, – ngoài tất cả các hàm. • Tương ứng với vị trí xuất hiện của biến, có: – Biến địa phương – Tham số hình thức – Biến toàn cục Biến địa phương • Các biến (hằng) được khai báo trong một hàm được gọi là các biến địa phương. • Biến có thể được khai báo bất kì đâu trong hàm, chỉ các phát biểu trong cùng khối mới có thể truy xuất. • Biến địa phương chỉ tồn tại (thời gian sống) trong khi khối lệnh có chứa khai báo biến đó thực thi. • Khối lệnh hoặc hàm khác không thể truy xuất chúng. 140 Tham số hình thức • Dùng tham số hình thức để chuyển các giá trị cho hàm. • Các tham số hình thức được dùng như biến địa phương.Nghĩa là: – biến chỉ được sinh ra khi hàm được gọi thực thi và bị hủy khi hàm thực thi xong. – Chỉ được truy xuất bởi các phát biểu trong hàm đó. Biến toàn cục • Để tạo biến (hằng) toàn cục, khai báo biến (hằng) ngoài tất cả các hàm. • Biến toàn cục có thể được truy xuất bởi các phát biểu ở bất kì đâu trong chương trình kể từ sau khi nó được định nghĩa (khai báo). • Thời gian sống của biến toàn cục là suốt quá trình chương trình thực thi. 141 Ví dụ void main() { cout<<f1(); cout<<f2(); cout<<r; } #include double a = 3.0, r = 0.0; double f1(){ r = 2*a; return r; } double f2(){ return (a*a); } Trường hợp trùng tên biến • Không thể định nghĩa hai biến trùng tên trong cùng khối. • Nếu có biến địa phương trong hàm trùng tên với biến toàn cục, thì trong hàm đó, mặc định sẽ truy xuất đến biến địa phương. • Để truy xuất đến biến toàn cục, ta dùng phép toán phân định phạm vi, là dấu hai chấm kép [::] ngay trước tên biến. 142 Ví dụ //Chú ý trường hợp: int f3(int a) { int b = a; if (a<0) int b = -a; return b; } //Chạy chương trình bằng “tay” xem thử ! #include double a = 3.0, r = 0.0; double f1(double a) { double r = 2*a; return r; } double f2(double r) { ::r = r*r; return ::r; } void main() { cout<<f1(a); cout<<f2(a); cout<<r; } 7. Biến mảng • Mảng là một nhóm các biến có cùng tên, cùng kiểu dữ liệu. • Mảng có thể là một hoặc nhiều chiều. • Mỗi phần tử (mỗi biến) của mảng được truy xuất thông qua chỉ số • Mảng một chiều a có 8 phần tử, hiện có 4 phần tử đã được gán giá trị. 582-3a n=4 143 Ví dụ: a ) Mảng 2 chiều a có 4×5=20 phần tử, hiện có 2×3=6 phần tử đã được gán giá trị. 6-87 4-23 Mẫu khai báo: TenBien[MAX] ; • TenBien: theo nguyên tắc đặt tên, • MAX: phải là hằng (hằng khai báo, hằng giá trị,…) Ví dụ: #define MAX 20 int a[10]; int b[MAX] double m[MAX] Định nghĩa mảng một chiều (1-D) 144 Với khai báo trên: • Là ta đã định nghĩa một mảng có MAX phần tử (= đã định nghĩa MAX biến) • Tất cả phần tử (biến) này có cùng kiểu dữ liệu. • Mỗi phần tử của mảng có chỉ số từ [0]→[MAX–1]. Định nghĩa mảng một chiều (2) Ví dụ: char s[50]; ⇒ định nghĩa 50 biến kiểu char gồm: s[0], s[1], s[2],… s[49]. s[0] = ‘H’, s[1]=‘e’, s[2]=‘l’; …‘l’‘e’‘H’ s[0] s[1] s[2] s[3] s[48] s[49] Định nghĩa mảng một chiều (3) 145 Ví dụ: int F[7]; ⇒ định nghĩa 7 biến kiểu int gồm: F[0], F[1],f[2],… F[6]. F[0]=-2, F[1]=5, F[2]=1; 15-2 F[0] F[1] F[2] F[3] F[4] F[5] F[6] Định nghĩa mảng một chiều (3) Ví dụ: double x[12];⇒định nghĩa 12 biến kiểu double gồm: x[0], x[1], x[2],… x[11]. x[0]=1.2, x[1]=3.1; …3.11.2 x[0] x[1] x[2] x[10] x[11] Định nghĩa mảng một chiều (4) 146 Ví dụ: - Để khai báo mảng số nguyên có 25 phần tử với tên là mg, = Khai báo 25 biến có tên chung là mg: int mg[25]; hay: #define MAX 25 int mg[MAX]; Định nghĩa mảng một chiều (5) Khi mảng được định nghĩa, - Vùng nhớ cho các phần tử của mảng được cấp phát là các ô nhớ liền nhau. - Mỗi phần tử chiếm số bytes tùy thuộc kiểu dữ liệu. - sizeof(); → cho biết tổng số bytes của mảng. Lưu trữ 147 Ví dụ: double x[25]; ⇒ sizeof(x) ≡ 200 ⇒ sizeof(x[0]) ≡ sizeof(x[1]) ≡ …≡ 8 long a[20]; ⇒ sizeof(a) ≡ 80 ⇒ sizeof(a[0]) ≡ sizeof(a[1]) ≡ …≡ 4 Lưu trữ Không thể dùng biến mảng như thông thường. int a[6]; a = -2; //err cout<<a; //err Mà phải dùng từng phần tử trong chúng. Mỗi phần tử được dùng như một biến đơn. int a[6]; a[1] = -2; cin>>a[0]; cout<<a[0]*a[1]; Lưu ý (1) 148 - Ta thường dùng phát biểu lặp để truy xuất các phần tử của mảng. - Đồng thời dùng thêm một biến kiểu nguyên, cho biết số phần tử của mảng thực sự đang được dùng. Lưu ý (2) Vd01 149 Một số cách mà ngôn ngữ C cho phép khởi tạo giá trị của mảng: (1) Số phần tử = số giá trị double x[3]= {1.0, 2.71828, 3.14159}; ⇔ x[0]= 1.0, x[1]= 2.71828,... ⇒ Cấp phát 3 ô nhớ kiểu double, gán 3 giá trị cho chúng. Khởi tạo (2) Số phần tử > số giá trị char s[10]= {‘c’,’h’,’a’,’o’,’e’,’m’}; ⇔ s[0]= ‘c’, s[1]= ‘h’,…,s[5]=‘m’; ⇒ Cấp phát 10 ô nhớ kiểu char, lần lượt gán 6 giá trị cho 6 ô nhớ đầu Khởi tạo 150 (3) Không định số phần tử int SoNgay[]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ⇔ Cấp phát số phần tử = số giá trị được gán. ⇒ Cấp phát 12 ô nhớ kiểu int, lần lượt gán 12 giá trị cho chúng. Khởi tạo Vd02 151 - Tham số được khai báo như khai báo biến mảng. - Có thể không cần xác định số phần tử của mảng - Mảng được chuyển tham chiếu Vd: Hàm xuất nội dung một mảng các số nguyên: void xuatMang(int a[], int N); Vd: Hàm nhập nội dung một mảng các số nguyên: void nhapMang(int a[], int &N); // lưu ý khi nhập N trong hàm 8. Biến mảng là tham số của hàm Vd03 152 - Tham số được khai báo như khai báo biến mảng. - Có thể không cần xác định số phần tử của mảng - Mảng được chuyển tham chiếu Vd: Hàm tính tổng các phần tử của mảng nguyên (vd: a = [3 7 4 9] → S= 23) int tinhTong(int a[], int N); 153 Vd04 Vd1: Đảo ngược nội dung của mảng. Ví dụ: a= [3 7 4 9] → a = [9 4 7 3] void daoMang(int a[], int N) { for (int i= 0; i<N/2; i++) HoanVi(a[i], a[n-i-1]); } 8. Biến mảng là tham số của hàm 154 8129673 n=7 a= i=0 a0 ai a6 an-1 a5 an-i-1 a4 an-i-1 a3 i=1 a1 ai i=2 a2 ai Vd05 155 Vd2: Hàm sắp xếp tăng các phần tử của mảng. Ví dụ: a= [3 7 4 9] → a = [3 4 7 9] Vd06 156 Vd3: Tìm xem một giá trị x có trong mảng ? Ví dụ: a= [3 7 4 9], x= 4 → x nằm ở vị trí 2 trong mảng a 8292376 n=7 a= x= 3 xa ?? 0 = xa ?? 1 = xa ??2 = k=2 157 8292376 n=7 a= x= 4 xa ?? 0 = xa ?? 1 = xa ?? 2 = xa ?? 3 = xa ?? 4 = xa ?? 5 = xa ?? 6 = k=-1 (khong co x trong mang) Vd07 158 Vd07b Vd4: Xóa phần tử x khỏi mảng (nếu có). Ví dụ: a= [6 7 3 2 9 2 8],n=7 x= 3 → a= [6 7 2 9 2 8], n= 6 x= 2 → a= [6 7 9 8], n= 4 159 8292376 n=7 a= x= 3 n=6xa ?? 0 = xa ?? 1 = xa ?? 2 = k=2 160 Xóa phần tử x khỏi mảng (nếu có). Vd08a 161 Xóa tất cả phần tử x khỏi mảng (nếu có). Vd08b

Các file đính kèm theo tài liệu này:

  • pdfMôn học lập trình C căn bản.pdf
Tài liệu liên quan