Giáo trình Lập trình C - Nghề: Quản trị mạng - Trình độ: Cao đẳng - Trường CĐCN Hải Phòng

pdf 98 trang Gia Huy 17/05/2022 1750
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình C - Nghề: Quản trị mạng - Trình độ: Cao đẳng - Trường CĐCN Hải Phòng", để 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:

  • pdfgiao_trinh_lap_trinh_c_nghe_quan_tri_mang_trinh_do_cao_dang.pdf

Nội dung text: Giáo trình Lập trình C - Nghề: Quản trị mạng - Trình độ: Cao đẳng - Trường CĐCN Hải Phòng

  1. UỶ BAN NHÂN DÂN TỈNH HẢI PHÒNG TRƯỜNG CĐCN HẢI PHÒNG GIÁO TRÌNH Tên môn học: Lập trình C NGHỀ: QUẢN TRỊ MẠNG TRÌNH ĐỘ CAO ĐẲNG HẢI PHÒNG Trang 1
  2. TUYÊN BỐ BẢN QUYỀN Tài liệu này thuộc loại sách giáo trình nên các nguồn thông tin có thể được phép dùng nguyên bản hoặc trích dùng cho các mục đích về đào tạo và tham khảo. Mọi mục đích khác mang tính lệch lạc hoặc sử dụng với mục đích kinh doanh thiếu lành mạnh sẽ bị nghiêm cấm. LỜI GIỚI THIỆU ”Lập trình cơ bản” là môn học bắt buộc trong các trường nghề. Tuỳ thuộc vào đối tượng người học và cấp bậc học mà trang bị cho học sinh, sinh viên những kiến thức cơ bản nhất. Để thống nhất chương trình và nội dung giảng dạy trong các nhà trường chúng tôi biên soạn cuốn giáo trình: Lập trình cơ bản. Giáo trình được biên soạn phù hợp với các nghề trong các trường đào tạo nghề phục vụ theo yêu cầu của thực tế xã hội hiện nay. Tài liệu tham khảo để biên soạn gồm: [1]. Phạm Văn Ất. Kỹ thuật lập trình C cơ sở và nâng cao. Nhà xuất bản Giao thông vận tải,2006 [2]. Ngô Trung Việt. Ngôn ngữ lập trình C và C++. Nhà xuất bản Thống kê, Kết hợp với kiến thức mới có liên quan môn học và những vấn đề thực tế thường gặp trong sản xuất, đời sống để giáo trình có tính thực tế cao, giúp cho người học dễ hiểu, dễ dàng lĩnh hội được kiến thức môn học. Trong quá trình biên soạn giáo trình kinh nghiệm còn hạn chế, chúng tôi rất mong nhận được ý kiến đóng góp của bạn đọc để lần hiệu đính sau được hoàn chỉnh hơn. Tổ bộ môn ứng dụng tin học Trang 2
  3. MỤC LỤC LỜI GIỚI THIỆU 2 CHƯƠNG 1: TỔNG QUAN VỀ NGÔN NGỮ LẬP TRÌNH C 5 1.1. Giới thiệu sơ lược về ngôn ngữ lập trình C 6 1.1.1. Lịch sử phát triển ngôn ngữ C 6 1.1.2. Các bước cơ bản khi viết chương trình trên C 7 1.2. Các phần tử cơ bản của C 8 1.2.1. Tập ký tự cơ bản 8 1.2.3. Định danh (Tên) - Identifier 9 1.2.4. Kiểu dữ liệu 9 1.2.5. Hằng 11 1.2.6. Biến 12 1.2.7. Hàm 12 1.2.8. Biểu thức 12 1.2.9. Câu lệnh 13 1.2.10. Chú thích 13 1.3. Cấu trúc cơ bản của chương trình C 14 1.4. Cài đặt và sử dụng môi trường turbo C 15 1.4.1. Cài đặt 15 1.4.2. Sử dụng môi trường Turbo 15 CHƯƠNG 2: KHỞI ĐẦU VỚI LẬP TRÌNH C 17 2.1. Một số khai báo cơ bản 17 2.1.1. Khai báo tệp tiêu đề 17 2.1.2. Khai báo hằng 17 2.2. Các phép toán trong C 19 2.3. Các lệnh vào ra dữ liệu 25 2.3.2. Lệnh nhập dữ liệu 28 2.3.3. Lệnh gán 30 2.3.4. Các lệnh nhập xuất khác 30 TH bài 1: CÀI ĐẶT, SỬ DỤNG MÔI TRƯỜNG LẬP TRÌNH C 32 CHƯƠNG 3: CÁC LỆNH CẤU TRÚC 35 3.1. Lệnh khối 35 3.2. Lệnh lựa chọn 36 3.2.1. Lệnh lựa chọn theo điều kiện if 36 3.2.2. Lệnh switch 39 3.3. Lệnh lặp 42 3.3.1. Lệnh for 42 3.3.2. Lệnh while 44 3.3.3. Lệnh do while 46 TH BÀI 2: LẬP TRÌNH VỚI LỆNH KHỐI VÀ LỆNH LỰA CHỌN 50 TH BÀI 3: LẬP TRÌNH VỚI LỆNH LẶP 53 TH BÀI 3: LẬP TRÌNH VỚI LỆNH LẶP (tiếp) 55 CHƯƠNG 4: HÀM TRONG C 57 4.1. Khái niệm về hàm và thư viện 57 4.1.1. Chương trình con (Subprogram) 57 Trang 3
  4. 4.1.2. Một số đặc tính của hàm trong C 58 4.1.3. Thư viện hàm chuẩn 58 4.2. Quy trình xây dựng hàm 59 4.2.1. Khai báo hàm 59 4.2.2. Sử dụng hàm 61 4.2.3. Quy tắc hoạt động của hàm 63 4.2.4. Tính tổng thể và cục bộ của biến 63 CHƯƠNG 5: DỮ LIỆU KIỂU MẢNG 67 5.1. Khái niệm và khai báo mảng 67 5.1.1. Khái niệm về mảng 67 5.1.2. Khai báo và sử dụng mảng 67 5.2. Một số bài toán với mảng 1 chiều 69 5.2.1. Nhập dữ liệu cho mảng 69 5.2.2. Hiện mảng dữ liệu 70 5.2.3. Tìm giá trị lớn nhất/nhỏ nhất (Max/Min) 71 5.2.4. Sắp xếp mảng 72 5.2.5. Tìm kiếm trong mảng 74 5.3. Một số bài toán với mảng 2 chiều 76 5.3.1. Nhập dữ liệu cho mảng 2 chiều 76 5.3.2. Hiện dữ liệu từ mảng 2 chiều 76 5.3.3. Các bài toán về ma trận 76 TH BÀI 4: XÂY DỰNG HÀM VÀ XỬ LÝ MẢNG 1 CHIỀU 79 CÁC HÀM ĐƠN GIẢN 79 TH BÀI 5: XÂY DỰNG HÀM VÀ XỬ LÝ MẢNG 2 CHIỀU 82 CÁC HÀM ĐƠN GIẢN 82 CHƯƠNG 6: XÂU KÝ TỰ (STRING) 85 6.1. Khái niệm và khai báo xâu 85 6.1.1. Khái niệm về xâu ký tự 85 6.1.2. Khai báo và sử dụng biến xâu 85 6.2. Một số hàm xử lý ký tự và xâu 86 6.2.1. Hàm xử lý ký tự 86 6.2.2. Hàm xử lý xâu 88 6.3. Một số chương trình xử lý dữ liệu kiểu xâu 90 TH BÀI 6: MẢNG VÀ XỬ LÝ XÂU KÝ TỰ 92 BÀI TẬP TỔNG HỢP 96 Trang 4
  5. LẬP TRÌNH CƠ BẢN I. Vị trí, tính chất của môn học: - Vị trí: Là môn học được bố trí sau khi sinh viên học xong các môn chung, các môn học cơ sở chuyên ngành đào tạo chuyên môn nghề; - Tính chất: Là môn học kỹ thuật cơ sở chương trình đào tạo nghề công nghệ thông tin (ƯDPM). II. Mục tiêu môn học: Kiến thức: Trình bày được các khái niệm cơ bản về lập trình, một số cấu trúc, câu lệnh trong lập trình C. Kỹ năng: Sử dụng được môi trường lập trình C để soạn thảo, biên dịch và hiệu chỉnh chương trình; Hình thành kỹ thuật lập trình từ việc áp dụng các khái niệm cơ bản để giải quyết các bài toán. Về năng lực tự chủ và trách nhiệm: Rèn luyện tư duy lập trình đối với sinh viên hệ cao đẳng. III. NỘI DUNG Chương 1: Tổng quan về ngôn ngữ lập trình c 1.1. Giới thiệu sơ lược về ngôn ngữ lập trình C 1.2. Các phần tử cơ bản của C 1.3. Cấu trúc cơ bản của chương trình C 1.4. Cài đặt và sử dụng phần mềm Chương 2: Khởi đầu với lập trình c 2.1. Một số khai báo cơ bản 2.2. Các phép toán trong C 2.3. Các lệnh vào ra dữ liệu TH bài 1: Cài đặt, sử dụng môi trường lập trình C Chương 3: Các lệnh cấu trúc 3.1. Lệnh khối 3.2. Lệnh lựa chọn 3.3. Lệnh lặp TH Bài 2: Lập trình với lệnh khối và lệnh lựa chọn TH Bài 3: Lập trình với lệnh lặp Chương 4: Hàm và thư viện 4.1. Khái niệm về hàm và thư viện 4.2. Quy trình xây dựng hàm Chương 5: Dữ liệu kiểu mảng 5.1. Khái niệm và khai báo mảng 5.2. Một số bài toán với mảng 1 chiều 5.3. Một số bài toán với mảng 2 chiều TH Bài 4: Xây dựng hàm và xử lý mảng 1 chiều các hàm đơn giản TH Bài 5: Xây dựng hàm và xử lý mảng 2 chiều các hàm đơn giản Chương 6: Xâu ký tự (string) 6.1. Khái niệm và khai báo xâu 6.2. Một số hàm xử lý ký tự và xâu 6.3. Một số chương trình xử lý dữ liệu kiểu xâu TH Bài 6: Mảng và xử lý xâu ký tự Bài tập tổng hợp Trang 5
  6. CHƯƠNG 1: TỔNG QUAN VỀ NGÔN NGỮ LẬP TRÌNH C Kiến thức: Trình bày được lịch sử phát triển của ngôn ngữ C, các phần tử cơ bản trong ngôn ngữ C và cấu trúc cơ bản của một chương trình C. Kĩ năng Thực hiện được cài đặt trình biên dịch và viết được chương trình C cơ bản. Thái độ Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. 1.1. Giới thiệu sơ lược về ngôn ngữ lập trình C 1.1.1. Lịch sử phát triển ngôn ngữ C Ngôn ngữ C ra đời tại phòng thí nghiệm BELL của tập đoàn AT&T (Hoa Kỳ) do Brian W. Kernighan và Dennis Ritchie phát triển vào đầu những năm 1970 và hoàn thành vào năm 1972. C được phát triển dựa trên nền các ngôn ngữ BCPL (Basic Combined Programming Language) và ngôn ngữ B. Cũng vì được phát triển dựa trên nền ngôn ngữ B nên ngôn ngữ mới được Brian W. Kernighan và Dennis Ritchie đặt tên là ngôn ngữ C như là sự tiếp nối ngôn ngữ B. C có các đặc điểm là một ngôn ngữ lập trình hệ thống mạnh, khả chuyển, có tính linh hoạt cao và có thế mạnh trong xử lí các dạng dữ liệu số, văn bản, cơ sở dữ liệu. Vì vậy C thường được dùng để viết các chương trình hệ thống như hệ điều hành (ví dụ hệ điều hành Unix có 90% mã nguồn được viết bằng C, 10% còn lại viết bằng hợp ngữ) và các chương trình ứng dụng chuyên nghiệp có can thiệp tới dữ liệu ở mức thấp như xử lí văn bản, cơ sở dữ liệu, xử lí ảnh W. Kernighan và Dennis Ritchie công bố ngôn ngữ C trong lần xuất bản đầu của cuốn sách "The C programming language" (1978). Sau đó người ta đã bổ sung thêm những yếu tố và khả năng mới vào trong ngôn ngữ C (ví dụ như đưa thêm kiểu liệt kê enum, cho phép kiểu dữ liệu trả về bởi hàm là kiểu void, struct hoặc union và đặc biệt là sự bổ sung các thư viện cho ngôn ngữ. Lúc đó đồng thời tồn tại nhiều phiên bản khác nhau của ngôn ngữ C nhưng không tương thích với nhau. Điều này gây khó khăn cho việc trao đổi mã nguồn chương trình C viết trên các phiên bản ngôn ngữ C khác nhau (bạn sẽ rất khó đọc và hiểu chương trình của người khác, và khi bạn muốn sửa nó thành chương trình của mình dịch trên bộ dịch của mình thì sẽ tốn rất nhiều công sức) và dẫn đến nhu cầu chuẩn hóa ngôn ngữ C. Hiện nay cũng có nhiều phiên bản của ngôn ngữ C khác nhau và mỗi phiên bản này gắn liền với một bộ chương trình dịch cụ thể của ngôn ngữ C. Các bộ chương trình dịch phổ biến của ngôn ngữ C có thể kể tên như: Turbo C++ và Borland C++ của Borland Inc. MSC và VC của Microsoft Corp. GCC của GNU project. Free C Trang 6
  7. 1.1.2. Các bước cơ bản khi viết chương trình trên C Để giải bài toán bằng chương trình thực hiện theo các bước sau: 1. Xác định đối tượng của chương trình 2. Xác định phương pháp và thuật giải 3. Viết chương trình (lập trình) 4. Chạy chương trình và kiểm tra kết quả. Như vậy ta thấy chu trình phát triển một chương trình như sau: 1. Soạn thảo chương trình nguồn Chúng ta có thể sử dụng một trình soạn thảo văn bản chuẩn (ASCII) nào đó để soạn thảo chương trình, sau đó ghi vào file chương trình nguồn (ngầm định với phần mở rộng là .C). Do C cũng như hầu hết các ngôn ngữ lập trình phổ biến đều sử dụng bảng chữ cái ASCII nên bạn có thể sử dụng bất kỳ một hệ soạn thảo văn bản chuẩn để viết chương trình, tuy nhiên hầu hết các trình biên dịch của C trên môi trường MS-DOS hoặc WINDOWS đều có tích hợp trình soạn thảo và bạn nên sử dụng trình soạn thảo tích hợp này sẽ thuận lợi hơn. 2. Biên dịch chương trình nguồn Hiện nay có rất nhiều chương trình dịch cho C như: Turbo C, BC, Microsoft C, mục đích của bước này là chuyển chương trình nguồn thành chương trình mã đối tượng (object). Sau bước này (nếu thành công) chúng ta thu được file chương trình đối tượng (có phần mở rộng là .OBJ) 3. Liên kết chương trình Sau bước biên dịch hoàn thành ta có chương trình đối tượng, đây chưa phải là chương trình có thể chạy được trên máy tính, bước này chúng ta phải sử dụng một trình liên kết để liên kết các hàm thư viện với chương trình đối tượng để tạo ra chương trình đích. Bạn có thể sử dụng trình liên kết độc lập nào đó, nhưng với các trình biên dịch của C trên môi trường DOS hay WINDOWS đều có sẵn trình liên kết. 4. Chạy và kiểm tra kết quả chương trình Khi đã có chương trình đích, chúng ta cần phải kiểm tra tính đúng đắn của nó.Bạn chạy chương trình với các bộ dữ liệu mẫu và kiểm tra kết quả có như dự kiến hay không, nếu có sai sót thì phải xác định nguyên nhân gây lỗi và quay lại bước 1 để hiệu chỉnh. Và chúng ta lặp lại quá trình này cho tới khi được chương trình giải đúng bài toán mong đợi. Trang 7
  8. Các bước phát triển chương trình Hiện nay có rất nhiều chương trình dịch cho C và hầu hết (trên nền DOS hoặc Windows) trong đó được tích hợp cả trình soạn thảo, biên dịch, liên kết - gọi là môi trường tích hợp. Trong giáo trình này chúng ta sử dụng BC (Borland C) hoặc turbo C làm môi trường lập trình. 1.2. Các phần tử cơ bản của C 1.2.1. Tập ký tự cơ bản Tập kí tự sử dụng trong ngôn ngữ lập trình C gồm có: 1.2.2. Từ khóa (Keyword) 26 chữ cái hoa: A B C X Y Z 26 chữ cái thường: a b c x y z. 10 chữ số: 0 1 2 3 4 5 6 7 8 9. Các kí hiệu toán + - * / = <> Cáchọc: dấu ngăn cách: . ; , : space tab Các dấu ngoặc: ( ) [ ] { } Các kí hiệu đặc _ ? $ & # ^ \ ! ‘ “ ~ .v.v. biệt: Từ khóa (Keyword) là những từ có sẵn của ngôn ngữ và được sử dụng dành riêng cho những mục đích xác định. Một số từ khóa hay dùng trong Turbo C Trang 8
  9. break case char const continue default do double else enum float for goto if int interrupt long return short signed sizeof static struct switch typedef union unsigned void while Chú ý: Tất cả các từ khóa trong C đều viết bằng chữ thường. Các từ khóa trong C được sử dụng để - Đặt tên cho các kiểu dữ liệu: int, float, double, char, struct, union - Mô tả các lệnh, các cấu trúc điều khiển: for, do, while, switch, case, if, else, break, continue 1.2.3. Định danh (Tên) - Identifier Định danh (Identifier – hoặc còn gọi là Tên) là một dãy các kí tự dùng để gọi tên các đối tượng trong chương trình. Các đối tượng trong chương trình gồm có biến, hằng, hàm, kiểu dữ liệu ta sẽ làm quen ở những mục tiếp theo. Khi đặt tên cho định danh trong C, người lập trình cần tuân thủ các quy tắc sau : 1. Các kí tự được sử dụng trong các định danh của ngôn ngữ C chỉ được gồm có: chữ cái, chữ số và dấu gạch dưới “_” (underscore). 2. Bắt đầu của định danh phải là chữ cái hoặc dấu gạch dưới, không được bắt đầu định danh bằng chữ số. 3. Định danh do người lập trình đặt không được trùng với từ khóa. 4. Turbo C++ không giới hạn độ dài của định danh, nhưng chỉ 32 kí tự đầu của định danh được chương trình biên dịch sử dụng (khi định danh có độ dài lớn hơn 32 kí tự thì Turbo C++ sẽ tự động cắt bỏ, không xem xét các kí tự cuối bắt đầu từ kí tự thứ 33). Một số ví dụ về định danh: i, x, y, a, b, _function, _MY_CONSTANT, PI, gia_tri_1 Ví dụ về định danh không hợp lệ 1_a, 3d, 55x bắt đầu bằng chữ số so luong, ti le có kí tự không hợp lệ (dấu cách – space) trong tên int, char trùng với từ khóa của ngôn ngữ C 1.2.4. Kiểu dữ liệu Dữ liệu là đối tượng được lưu trữ và xử lý trong máy tính. Dữ liệu trong máy tính lại không phải tất cả đều giống nhau. Có dữ liệu là chữ viết, có dữ liệu là con số, lại có dữ liệu khác là hình ảnh, âm thanh Ta nói rằng các dữ liệu đó thuộc các kiểu dữ liệu khác nhau. Kiểu dữ liệu trong C có thể phân loại thành 3 nhóm: - Kiểu đơn giản (cơ bản/cơ sở) gồm kiểu số nguyên,số thực,ký tự - Kiểu dữ liệu có cấu trúc gồm kiểu mảng, xâu (chuỗi), struct (bản ghi),tệp. - Kiểu con trỏ Một cách hình thức, kiểu dữ liệu có thể được định nghĩa gồm 2 điểm như sau: Trang 9
  10. Một kiểu dữ liệu là một tập hợp các giá trị mà một dữ liệu thuộc kiểu dữ liệu đó có thể nhận được (dải giá trị/miền giá trị). Trên một kiểu dữ liệu ta xác định một số phép toán đối với các dữ liệu thuộc kiểu dữ liệu đó (tập thao tác/ phép toán trên tập giá trị). Bảng sau liệt kê các kiểu dữ liệu đơn giản trong C Ví dụ: Trong ngôn ngữ C có kiểu dữ liệu int. Một dữ liệu thuộc kiểu dữ liệu int thì nó sẽ là một số nguyên (integer) và nó có thể nhận giá trị từ - 32,768 (- 215) đến 32,767 (215 - 1). Trên kiểu dữ liệu int ngôn ngữ C định nghĩa các phép toán số học đối với số nguyên như Tên phép toán Kí hiệu Đảo dấu - Cộng + Trừ - Nhân * Chia lấy phần / nguyên Chia lấy phần dư % So sánh bằng = = So sánh lớn hơn > So sánh nhỏ hơn < Trong máy tính, việc phân biệt kiểu dữ liệu là cần thiết vì qua kiểu dữ liệu máy tính biết được đối tượng mà nó đang xử lí thuộc dạng nào, có cấu trúc ra sao, có thể thực hiện các phép xử lí nào đối với đối tượng đó, hay là cần phải lưu trữ đối tượng đó như thế nào Trang 10
  11. 1.2.5. Hằng Hằng (constant) là đại lượng có giá trị xác định và không thay đổi trong chương trình. Để giúp chương trình dịch nhận biết hằng ta cần nắm được cách biểu diễn hằng trong một chương trình C. Biểu diễn hằng số nguyên Trong ngôn ngữ C, một hằng số nguyên có thể được biểu diễn dưới những dạng sau - Dạng thập phân: đó chính là cách viết giá trị số đó dưới hệ đếm cơ số 10 thông thường. - Dạng thập lục phân: ta viết giá trị số đó dưới dạng hệ đếm cơ số 16 và thêm tiền tố 0x ở đầu. - Dạng bát phân: ta viết giá trị số đó dưới dạng hệ đếm cơ số 8 và thêm tiền tố 0 ở đầu. Ví dụ Giá trị thập phân Giá trị hệ bát phân Giá trị hệ thập lục phân 2007 03727 0x7D7 396 0614 0x18C Biểu diễn hằng số thực Có 2 cách biểu diễn hằng số thực: - Dưới dạng số thực dấu phẩy tĩnh. - Dưới dạng số thực dấu phẩy động. Ví dụ: Số thực dấu phẩy tĩnh Số thực dấu phẩy động 3.14159 31.4159 E-1 123.456 12.3456 E+1 hoặc 1.23456 E+2 Biểu diễn hằng kí tự Có 2 cách biểu diễn hằng kí tự: - Bằng kí hiệu của kí tự đó đặt giữa 2 dấu nháy đơn. - Bằng số thứ tự của kí tự đó trong bảng mã ASCII (và lưu ý số thứ tự của một kí tự trong bảng mã ASCII là một số nguyên nên có một số cách biểu diễn). Ví dụ Kí tự cần biểu diễn Cách 1 Cách 2 Chữ cái A ‘A’ 65 hoặc 0101 hoặc 0x41 Dấu nháy đơn ‘ ‘\’’ 39 hoặc 047 hoặc 0x27 Dấu nháy kép “ ‘\”’ 34 hoặc 042 hoặc 0x22 Dấu gạch chéo ngược \ ‘\\’ 92 hoặc 0134 hoặc 0x5c Kí tự xuống dòng ‘\n’ Kí tự NUL ‘\0’ 0 hoặc 00 hoặc 0x0 Kí tự Tab ‘\t’ 9 hoặc 09 hoặc 0x9 Biểu diễn hằng xâu kí tự Trang 11
  12. Hằng xâu kí tự được biểu diễn bởi dãy các kí tự thành phần có trong xâu đó và được đặt trong cặp dấu nháy kép. Ví dụ: “ngon ngu lap trinh C”, “tin hoc dai cuong” Để sử dụng, hằng phải được đặt tên. Tên hằng đặt theo quy tắc định danh 1.2.6. Biến Biến (variable) là đặc trưng cho một đại lượng được xử lý trong bài toán, đại lượng này có giá trị có thể thay đổi trong chương trình. Tại một thời điểm xác định, giá trị của biến là một hằng. Trong chương trình, hằng và biến được sử dụng để lưu trữ dữ liệu, và dữ liệu lưu trữ trong biến, hằng phải thuộc một kiểu dữ liệu nào đó. Biến và hằng đều phải được đặt tên để khi cần thì có thể gọi đến. Tên biến và hằng được đặt theo quy tắc đặt tên cho định danh. 1.2.7. Hàm Trong lập trình chúng ta rất hay phải tính toán giá trị của một số đại lượng thường gặp như sin(x), cos(x), căn bậc hai, lũy thừa, logarithm Ngôn ngữ C cung cấp cho người lập trình một công cụ dùng để tính toán giá trị các đại lượng đó mỗi khi cần trong chương trình, đó là các hàm. Một số hàm toán học hay được sử dụng trong C Kí hiệu Hàm Ý nghĩa Ví dụ toán học sqrt(x) Căn bậc 2 của x x sqrt(16.0) bằng 4.0 pow(x,y) x mũ y xy pow(2,3) bằng 8 exp(x) e mũ x ex exp(1.0) bằng 2.718282 log(x) logarithm tự nhiên (cơ số e) lnx log(2.718282) bằng 1.0 của x log10(x) logarithm cơ số 10 của x logx log10(100) bằng 2 sin(x) sin của x sinx sin(0.0) bằng 0.0 cos(x) cosin của x cosx cos(0.0) bằng 1.0 tan(x) tang của x tgx tan(0.0) bằng 0.0 ceil(x) phần nguyên già của x, tức là x ceil(2.5) bằng 3 số nguyên nhỏ nhất không ceil(-2.5) bằng –2 nhỏ hơn x floor(x) phần nguyên non của x, tức x floor(2.5) bằng 2 là số nguyên lớn nhất không floor(-2.5) bằng –3 lớn hơn x 1.2.8. Biểu thức Biểu thức là sự ghép nối các toán tử (operator) và các toán hạng (operand) theo một quy tắc xác định. Trang 12
  13. Các toán hạng trong biểu thức có thể là biến, hằng, hàm hoặc một biểu thức khác. Bản thân một biến, hằng, hàm đứng độc lập cũng được coi là một biểu thức. Các toán tử trong biểu thức rất đa dạng như cộng, trừ, nhân, chia, so sánh Biểu thức thường là sự thể hiện công thức tính toán giá trị một đại lượng nào đó. Ví dụ về biểu thức: chieu_dai * chieu_rong * chieu_cao Trong biểu thức trên chieu_dai, chieu_rong, chieu_cao là các biến hoặc hằng, * là kí hiệu của toán tử nhân. Nếu chieu_dai, chieu_rong, chieu_cao là các biến (hoặc hằng) lưu trữ giá trị chiều dài, chiều rộng và chiều cao của một khối hộp chữ nhật thì biểu thức trên sẽ tính giá trị thể tích của khối hộp chữ nhật đó. 1.2.9. Câu lệnh Câu lệnh (statement) diễn tả một hoặc một nhóm các thao tác trong giải thuật. Chương trình được tạo thành từ dãy các câu lệnh. Cuối mỗi câu lệnh đều có dấu chấm phẩy ‘;’ để đánh dấu kết thúc câu lệnh cũng như để phân tách các câu lệnh với nhau. Câu lệnh được chia thành 2 nhóm chính: Nhóm các câu lệnh đơn: là những câu lệnh không chứa câu lệnh khác. Ví dụ: phép gán, phép cộng, phép trừ Nhóm các câu lệnh phức: là những câu lệnh chứa câu lệnh khác trong nó. Ví dụ: lệnh khối, các cấu trúc lệnh rẽ nhánh, cấu trúc lệnh lặp Lệnh khối là một số các lệnh đơn được nhóm lại với nhau và đặt trong cặp dấu ngoặc nhọn { } để phân tách với các lệnh khác trong chương trình. 1.2.10. Chú thích Để giúp việc đọc và hiểu chương trình viết ra được dễ dàng hơn, chúng ta cần đưa vào các lời chú thích (comment). Lời chú thích là lời mô tả, giải thích vắn tắt cho một câu lệnh, một đoạn chương trình hoặc cả chương trình, nhờ đó người đọc có thể hiểu được ý đồ của người lập trình và công việc mà chương trình đang thực hiện. Khi gặp kí hiệu lời chú thích trong chương trình, trình biên dịch sẽ tự động bỏ qua không dịch phần nội dung nằm trong phạm vi của vùng chú thích đó. Trong C, có 2 cách để viết lời chú thích Dùng 2 dấu sổ chéo liên tiếp // để kí hiệu toàn bộ vùng bắt đầu từ 2 dấu sổ chéo liên tiếp đó đến cuối dòng là vùng chú thích. Ví dụ: // khai bao 2 bien nguyen int a, b; a = 5; b = 3; // khoi tao gia tri cho cac bien nay Cách này thường dùng nếu đoạn chú thích ngắn, có thể viết đủ trên một dòng. Dùng 2 cặp kí hiệu /* và */ để kí hiệu rằng toàn bộ vùng bắt đầu từ cặp kí hiệu /* kéo dài đến cặp kí hiệu */ là vùng chú thích. Ví dụ: /* doan chuong trinh sau khai bao 2 bien nguyen va khoi tao gia tri cho 2 bien nguyen nay */ int a, b; a = 5; b = 3; Trang 13
  14. Cách này thường dùng khi đoạn chú thích dài, phải viết trên nhiều dòng. 1.3. Cấu trúc cơ bản của chương trình C Về cơ bản, mọi chương trình viết bằng ngôn ngữ C sẽ có cấu trúc gồm các phần có thứ tự như sau: Phần 1: Khai báo tệp tiêu đề #include Phần 2: Định nghĩa hằng #define hay const Phần 3: Định nghĩa kiểu dữ liệu typedef Phần 4: Khai báo các nguyên mẫu hàm Phần 5: Khai báo các biến toàn cục Phần 6: Định nghĩa các hàm Phần 7: Định nghĩa hàm main() main() { } Phần 8: Định nghĩa các hàm đã khai báo nguyên mẫu Phần 1: Phần khai báo các tệp tiêu đề. Phần này có chức năng thông báo cho chương trình dịch biết là chương trình có sử dụng những thư viện nào (mỗi tệp tiêu đề tương ứng với một thư viện). Phần 2: Định nghĩa các hằng mới dùng cho cả chương trình. Phần 3: Định nghĩa các kiểu dữ liệu mới dùng cho cả chương trình Phần 4: Phần khai báo các hàm nguyên mẫu. Phần này giúp cho chương trình dịch biết được những thông tin cơ bản (gồm tên hàm, dach sách các tham số và kiểu dữ liệu trả về) của các hàm sử dụng trong chương trình. Phần 5: Phần khai báo các biến toàn cục. Phần 6: Định nghĩa các hàm. Phần 7: Phần định nghĩa hàm main( ). Hàm main( ) là một hàm đặc biệt trong C. Khi thực hiện, chương trình sẽ gọi hàm main( ), hay nói cách khác chương trình sẽ bắt đầu bằng việc thực hiện các lệnh trong hàm main( ). Trong hàm main( ) ta mới gọi tới các hàm khác. Phần 8: Phần định nghĩa các hàm đã khai báo nguyên mẫu. Ở phần 3 ta đã khai báo nguyên mẫu (prototype) của các hàm, trong đó chỉ giới thiệu các thông tin cơ bản về hàm như tên hàm, danh sách các tham số và kiểu dữ liệu trả về. Nguyên mẫu hàm không cho ta biết cách thức cài đặt và hoạt động của các hàm. Ta sẽ làm việc đó ở phần định nghĩa các hàm. Trang 14
  15. Trong các phần trên, thì phần 7 định nghĩa hàm main( ) bắt buộc phải có trong mọi chương trình C. Các phần khác có thể có hoặc không. 1.4. Cài đặt và sử dụng môi trường turbo C 1.4.1. Cài đặt Để sử dụng Turbo C++ 3.0 ta cần phải cài đặt nó lên máy. Quá trình cài đặt thực hiện theo các bước sau: Bước 1: Bạn cần chuẩn bị đĩa chứa bộ cài của Turbo C++ 3.0, kích thước của bộ cài khoảng 4 MB. Hãy copy bộ cài này vào máy của bạn, giả sử vào thư mục C:\TC_Setup. Bước 2: Tìm đến thư mục chứa bộ cài Turbo C++ 3.0 (như giả sử ở trên là C:\TC_Setup) và kích hoạt file INSTALL.EXE để chạy chương trình cài đặt Turbo C++ 3.0. Chương trình cài đặt Turbo C++ 3.0 ban đầu sẽ yêu cầu bạn chỉ ra ổ đĩa trên đó chứa bộ cài Turbo C++ 3.0 Enter the SOURCE drive to use: Hãy nhập vào tên ổ đĩa, chẳng hạn C (ta để bộ cài Turbo C++ 3.0 ở thư mục C:\TC_Setup). Bước 3: Sau đó chương trình yêu cầu bạn nhập vào đường dẫn tới thư mục chứa các file của Turbo C++ 3.0 Enter the SOURCE Path: Thông thường chương trình sẽ tự tìm cho bạn, và bạn chỉ cần ấn Enter để chuyển sang bước tiếp theo. Bước 4: Ở bước 4, bạn cần xác định thư mục cài đặt. Thư mục này sẽ chứa các file của Turbo C++ 3.0 để bạn sử dụng sau này. Directories [C:\TC] Option [IDE CMD LIB CLASS BGI HELP EXMPL] Start Installation Thư mục cài đặt mặc định sẽ là \TC nằm trên thư mục gốc của ổ đĩa chứa bộ cài. Nếu bạn muốn thay đổi thư mục cài đặt thì hãy dùng các phím  và  để di chuyển hộp sáng đến phần Directories, gõ Enter và nhập vào đường dẫn mới, sau đó ấn phím Esc để trở về. Dùng các phím  và  để di chuyển hộp sáng đến phần Start Installation và ấn Enter. 1.4.2. Sử dụng môi trường Turbo Sau khi cài đặt xong, bạn có thể tìm đến thư mục BIN trong thư mục cài đặt và chạy file TC.EXE để khởi động Turbo C++ 3.0. Sau khi khởi động Turbo C++ 3.0 sẽ xuất hiện màn hình làm việc của Turbo C++ 3.0. Bạn dùng chuột di chuyển đến menu File (hoặc ấn Alt-F), sau đó chọn mục New để mở cửa sổ soạn thảo mới. Giờ hãy gõ vào toàn bộ chương trình viết bằng ngôn ngữ C của bạn lên cửa sổ soạn thảo này. Ấn phím F2 để lưu trữ tệp chương trình nguồn trên máy, một cửa sổ cất giữa tệp sẽ hiện ra yêu cầu bạn nhập vào tên mới cho tệp chương trình nguồn (tên mặc Trang 15
  16. định sẽ là NONAME.CPP). Hãy đặt một tên cho tệp rồi chọn OK để lưu tệp chương trình nguồn lại. Cuối cùng là ấn phím F9 để biên dịch chương trình viết ra. Nếu chương trình của bạn có lỗi thì Turbo C++ 3.0 sẽ báo lỗi và bạn phải sửa lại đến khi không còn lỗi. Nếu chương trình bạn không có lỗi thì Turbo C++ 3.0 sẽ thông báo biên dịch thành công và bạn có thể ấn Ctrl-F9 để chạy chương trình đã biên dịch. Trang 16
  17. CHƯƠNG 2: KHỞI ĐẦU VỚI LẬP TRÌNH C MỤC TIÊU CỦA BÀI Kiến thức: - Trình bày được các phép toán trong C; - Trình bày được các lệnh vào ra dữ liệu trong C. Kĩ năng Tạo được một chương trình đơn giản nhập và xuất ra màn hình. Thái độ Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. 2.1. Một số khai báo cơ bản 2.1.1. Khai báo tệp tiêu đề Trong chương trình C (trong hàm main cũng như các hàm khác do người lập trình viết) có thể sử dụng các hàm, hằng, kiểu dữ liệu, (gọi chung là các thành phần) đã được định nghĩa trong thư viện của C. Để sử dụng các thành phần này chúng ta phải chỉ dẫn cho chương trình dịch biết các thông tin về các thành cần sử dụng, các thông tin đó được khai báo trong tệp gọi là tệp tiêu đề (có phần mở rộng là H – viết tắt của header). Cú pháp của một dòng bao hàm tệp: #include hoặc #include “tên_tệp” trong đó tên_tệp là tên có thể có cả đường dẫn của tệp tiêu đề (.H) mà chúng ta cần sử dụng, mỗi lệnh bao hàm tệp trên một dòng. Ví dụ: #include #include #include “phanso.h” 2.1.2. Khai báo hằng Có 2 cách để khai báo hằng trong C là dùng chỉ thị #define hoặc khai báo với từ khóa const. Dùng chỉ thị #define Cú pháp khai báo: # define tên_hằng giá_trị Lưu ý không có dấu chấm phẩy ở cuối dòng chỉ thị. #define MAX_SINH_VIEN 50 // hằng kiểu số nguyên Dùng từ khóa const để khai báo với cú pháp: const kiểu_dữ_liệu tên_hằng = giá_trị; Khai báo này giống với khai báo biến có khởi tạo giá trị đầu, tuy nhiên cần lưu ý: Do có từ khóa const ở đầu cho nên giá trị của đối tượng tên_hằng sẽ không được phép thay đổi trong chương trình. Những lệnh nhằm làm thay đổi giá trị của tên_hằng trong chương trình sẽ dẫn tới lỗi biên dịch. Trang 17
  18. Trong khai báo biến thông thường, người lập trình có thể khởi tạo giá trị cho biến ngay từ khi khai báo hoặc không khởi tạo cũng được. Nhưng trong khai báo hằng, giá trị của tất cả các hằng cần được xác định ngay trong lệnh khai báo. Các khai báo hằng ở ví dụ trước giờ có thể viết lại theo cách khác như sau: const int MAX_SINH_VIEN = 50; 2.1.3. Khai báo biến Một biến trước khi sử dụng phải được khai báo. Cú pháp khai báo: kiểu_dữ_liệu tên_biến; Ví dụ: float x; // biến kiểu thực float y; // biến kiểu thực double z; // biến kiểu thực int i; // biến kiểu nguyên int j; // biến kiểu nguyên Nếu các biến thuộc cùng kiểu dữ liệu thì C cho phép khai báo chúng trên cùng một dòng: kiểu_dữ_liệu danh_sách_tên_biến; Ví dụ: float x, y; double z; int i, j; Sau khi khai báo, biến có thể nhận giá trị thuộc kiểu dữ liệu đã khai báo. Chúng ta có thể khởi tạo giá trị đầu cho biến nếu muốn với cú pháp: kiểu_dữ_liệu tên_biến = giá_trị_đầu; Ví dụ: int a = 3; // sau lenh nay bien a se co gia tri bang 3 2.1.4. Khai báo hàm main() Một chương trình C bao hàm nhiều hàm. Trong đó hàm main() là hàm chính,luôn xuất hiện và chỉ xuất hiện 1 lần. Khái niệm về hàm của C như sau: Hàm main() cũng không có tham số, vì vậy ta có thể gặp cách viết void main() hoặc void main(void). Phần thân của hàm main() gồm: - Các khai báo hằng,biến, - Các chỉ thị thực hiện các thao tác theo nội dung hàm. Ví dụ: Void main (void) { Int in; Printf(“\n Go vao 1 so nguyen la nam sinh cua ban”); Scanf(“%d”,&n)’ Printf(“\n ban sinh nam %d”,n); Getch(); } Trang 18
  19. 2.2. Các phép toán trong C 2.2.1. Các phép toán (operators) Các phép toán trong C được chia thành các nhóm phép toán cơ bản sau: nhóm các phép toán số học,nhóm các phép toán thao tác trên bit,nhóm các phép toán quan hệ,nhóm các phép toán logic. 2.2.1.1. Các phép toán cơ bản Các phép toán số học (Arithmetic operators) gồm có: Toán Ý nghĩa Kiểu dữ liệu của Ví dụ tử toán hạng - Phép đổi dấu Số thực hoặc số int a, b; nguyên -12; -a; -25.6; + Phép toán cộng Số thực hoặc số float x, y; nguyên 5 + 8; a + x; 3.6 + 2.9; - Phép toán trừ Số thực hoặc số 3 – 1.6; a – 5; nguyên * Phép toán nhân Số thực hoặc số a * b; b * y; nguyên 2.6 * 1.7; / Phép toán chia Số thực hoặc số 10.0/3.0; (bằng 3.33 ) nguyên 10/3.0; (bằng 3.33 ) 10.0/3; (bằng 3.33 ) / Phép chia lấy phần Giữa 2 số nguyên 10/3; (bằng 3) nguyên % Phép chia lấy phần Giữa 2 số nguyên 10%3; (bằng 1) dư Các phép toán quan hệ (Comparison operators) gồm có: Toán tử Ý nghĩa Ví dụ So sánh lớn hơn giữa 2 số nguyên hoặc 2 > 3 (có giá trị 0) thực. 6 > 4 (có giá trị 1) a > b So sánh lớn hơn hoặc bằng giữa 2 số 6 4 (có giá trị 1) nguyên hoặc thực. x a So sánh nhỏ hơn giữa 2 số nguyên hoặc 5 3 (có giá trị 0), thực. So sánh nhỏ hơn hoặc bằng giữa 2 số 5 5 (có giá trị 1) nguyên hoặc thực. 2 9 (có giá trị 1) So sánh bằng nhau giữa 2 số nguyên hoặc 3 4 (có giá trị 0) thực. a b  So sánh không bằng (so sánh khác) giữa 2 5  6 (có giá trị 1) số nguyên hoặc thực. 6  6 (có giá trị 0) Trang 19
  20. Các phép toán logic (Logical operators) gồm có Toán Ý nghĩa Kiểu dữ liệu của Ví dụ tử toán hạng && Phép VÀ LOGIC. Hai biểu thức logic 3 b && c 5) (có giá trị 1) ĐỊNH LOGIC có giá trị bằng 1 nếu toán hạng bằng 0 và có giá trị bằng 0 nếu toán hạng bằng 1 Phép toán gán Phép toán gán có dạng tên_biến = biểu_thức; Phép toán gán có chức năng lấy giá trị của biểu_thức gán cho tên_biến. Dấu = là kí hiệu cho toán tử gán. Ví dụ: int a, b, c; a = 3; b = a + 5; c = a * b; Sau đoạn lệnh trên, biến a có giá trị là 3, b có giá trị là 8 và c có giá trị là 24. Trong phép toán gán nếu ta bỏ dấu ; ở cuối đi thì ta sẽ thu được biểu thức gán. Biểu thức gán là biểu thức có dạng tên_biến = biểu_thức; 2.2.1.2. Các phép toán đặc trưng của C Phép toán gán thu gọn Xét lệnh gán sau x = x + y; Lệnh gán này sẽ tăng giá trị của biến x thêm một lượng có giá trị bằng giá trị của y. Trong C ta có thể viết lại lệnh này một cách gọn hơn mà thu được kết quả tương đương Trang 20
  21. x += y; Dạng lệnh gán thu gọn này còn áp dụng được với các phép toán khác nữa. Lệnh gán thông thường Lệnh gán thu gọn x = x + y x + = y x = x - y x - = y x = x * y x * = y x = x / y x / = y x = x % y x % = y x = x >> y x >> = y x = x = + 1; = - 1; Ta cũng có thể tăng (hoặc giảm) giá trị của một biến bằng cách sử dụng hai phép toán đặc biệt của C là phép toán ++ và phép toán . Phép toán ++ sẽ tăng giá trị của biến thêm 1 đơn vị, phép toán sẽ giảm giá trị của biến đi 1 đơn vị. Ví dụ int a = 5; float x = 10; a ++; // lệnh này tương đương với a = a+1 ; x ; // tương đương với x = x – 1; Phép toán tăng, giảm một đơn vị ở ví dụ trên là dạng hậu tố (vì phép toán đứng sau toán hạng). Ngoài ra còn có dạng tiền tố của phép toán tăng, giảm một đơn vị. Trong dạng tiền tố, ta thay đổi giá trị của biến trước khi sử dụng biến đó để tính toán giá trị của biểu thức. Trong dạng hậu tố, ta tính toán giá trị của biểu thức bằng giá trị ban đầu của biến, sau đó mới thay đổi giá trị của biến. Ví dụ int a, b, c; a = 3; // a bằng 3 b = a++; // dạng hậu tố. b bằng 3; a bằng 4 c = ++b; // dạng tiền tố. b bằng 4, c bằng 4; Sau khi thực hiện đoạn chương trình trên, ta có a, b và c đều có giá trị bằng 4; Phép toán lấy địa chỉ biến (&) Địa chỉ của một biến được định nghĩa là địa chỉ của ô nhớ đầu tiên trong vùng nhớ dành cho biến đó. Hình dưới đây minh họa một biến tên là a, kiểu dữ liệu int được lưu trữ trong bộ nhớ tại 2 ô nhớ có địa chỉ lần lượt là 158 và 159. Giá trị của biến a là 2006 Trang 21
  22. = 0x07D6. Khi đó địa chỉ của biến a sẽ là 158 hay 0000:9E (vì địa chỉ được mã hóa bởi 2 byte). 1 . . . . 157 a D6 158 07 159 160 . . . Trong C để xác đinh địa chỉ của một biến ta sử dụng toán tử một ngôi & đặt trước tên biến, cú pháp là & ; Ví dụ &a; // có giá trị là 158 hay 9E Phép toán chuyển đổi kiểu bắt buộc Chuyển đổi kiểu là chuyển kiểu dữ liệu của một biến từ kiểu dữ liệu này sang kiểu dữ liệu khác. Cú pháp của lệnh chuyển kiểu dữ liệu là như sau: ( ) ; Có những sự chuyển đổi được thực hiện hết sức tự nhiên, không có khó khăn gì, thậm chí đôi khi chương trình dịch sẽ tự động chuyển đổi kiểu hộ cho ta, ví dụ chuyển một dữ liệu kiểu số nguyên int sang một số nguyên kiểu long int, hay từ một số long int sang một số thực float Đó là vì một số nguyên kiểu int thực ra cũng là một số nguyên kiểu long int, một số nguyên kiểu long int cũng chính là một số thực kiểu float, một số thực kiểu float cũng là một số thực kiểu double. Tuy nhiên điều ngược lại thì chưa chắc, ví dụ số nguyên long int 50,000 không phải là một số nguyên kiểu int vì phạm vi biểu diễn của kiểu int là từ (-32,768 đến 32,767). Khi đó nếu phải chuyển kiểu dữ liệu thì ta phải cẩn thận nếu không sẽ bị mất dữ liệu. C hỗ trợ chuyển kiểu tự động trong những trường hợp sau char int long int float double long double 2.2.2. Biểu thức 2.2.2.1. Các loại biểu thức Biểu thức số học Biểu thức số học là biểu thức mà giá trị của nó là cái đại lượng số học (số nguyên, số thực). Trong biểu thức số học, các toán tử là các phép toán số học (cộng, trừ, nhân, chia ), các toán hạng là các đại lượng số học. Ví dụ (giả sử a, b, c là các số thực) 3 * 3.7, 8 + 6/3, a + b – c Biểu thức logic Biểu thức logic là biểu thức mà giá trị của nó là các giá trị logic, tức là một trong hai giá trị: Đúng (TRUE) hoặc Sai (FALSE). Ngôn ngữ C coi các giá trị nguyên khác 0 (ví dụ 1, -2, -5) là giá trị logic Đúng (TRUE), giá trị 0 là giá trị logic Sai (FALSE). Trang 22
  23. Các phép toán logic gồm có - AND (VÀ logic, trong ngôn ngữ C được kí hiệu là &&) - OR (HOẶC logic, trong ngôn ngữ C được kí hiệu là ||) - NOT (PHỦ ĐỊNH, trong ngôn ngữ C kí hiệu là !) Biểu thức quan hệ Biểu thức quan hệ là những biểu thức trong đó có sử dụng các toán tử quan hệ so sánh như lớn hơn, nhỏ hơn, bằng nhau, khác nhau Biểu thức quan hệ cũng chỉ có thể nhận giá trị là một trong 2 giá trị Đúng (TRUE) hoặc Sai (FALSE), vì vậy biểu thức quan hệ là một trường hợp riêng của biểu thức logic. Ví dụ về biểu thức quan hệ 5 > 7 // có giá trị logic là sai, FALSE 9 != 10 // có giá trị logic là đúng, TRUE 2 2 // có giá trị logic là đúng, TRUE a > b // giả sử a, b là 2 biến kiểu int a+1 > a // có giá trị đúng, TRUE Ví dụ về biểu thức logic (5 > 7)&&(9!=10) // có giá trị logic là sai, FALSE 0 || 1 // có giá trị logic là đúng, TRUE (5 > 7)||(9!=10) // có giá trị logic là đúng, TRUE 0 // có giá trị logic là sai, FALSE !0 // phủ định của 0, có giá trị logic là đúng, TRUE 3 // có giá trị logic là đúng, TRUE !3 // phủ định của 3, có giá trị logic là sai, FALSE (a > b)&&( a < b) // Có giá trị sai, FALSE. Giả sử a, b là 2 biến kiểu int Biểu thức điều kiện Là biểu thức có dạng biểu_thức_1 ? biểu_thức_2 : biểu_thức_3 Giá trị của biểu thức điều kiện sẽ là giá trị của biểu_thức_2 nếu biểu_thức_1 có giá trị khác 0 (tương ứng với giá trị logic ĐÚNG), và trái lại giá trị của biểu thức điều kiện sẽ là giá trị của biểu_thức_3 nếu biểu_thức_1 có giá trị bằng 0 (tương ứng với giá trị logic SAI). Ví dụ sau sẽ cho ta xác định được giá trị nhỏ nhất của 2 số nhờ sử dụng biểu thức điều kiện float x, y, z; // khai báo biến x = 3.8; y = 2.6; // gán giá trị cho các biến x, y z = (x<y) ? x : y; // z sẽ có giá trị bằng giá trị nhỏ nhất trong 2 số x và y Biểu thức dãy Lệnh dãy là lệnh gồm một dãy các biểu thức phân cách nhau bằng dấu phẩy và kết thúc lệnh là dấu chấm phẩy. Nó có dạng biểu_thức_1, biểu_thức_2, , biểu_thức_n; Trong lệnh dãy các biểu thức được tính toán độc lập với nhau Trang 23
  24. 2.2.2.2. Thứ tự ưu tiên của các phép toán trong biểu thức Trong biểu thức có thể có nhiều toán tử, vậy điều gì giúp cho chương trình dịch thực hiện các toán tử một cách đúng đắn?. Trong các biểu thức nếu có các cặp (), thì nó sẽ quyết định thứ tự thực hiện các phép toán: trong ngoặc trước, ngoài ngoặc sau. Nhưng có những khả năng dấu ngoặc không có hoặc không đủ để quyết định tất cả các trường hợp thì khi đó C thực hiện các toán tử căn cứ vào độ ưu tiên của chúng và sử dụng một số quy tắc về các toán tử (ví dụ như khi chúng cùng độ ưu tiên thì thực hiện từ trái qua phải hay từ phải qua trái). Ví dụ với các phép toán số học +, - có cùng độ ưu tiên, nên nếu trong biểu thức có nhiều phép toán +, - và không có các dấu ngoặc quy định thứ tự thực hiện thì chúng sẽ được thực hiện từ trái qua phải. Nhưng với phép toán ++, hay các phép gán, chẳng hạn như ++++ a; hoặc a=b=c=d trình tự kết hợp lại từ phải qua trái. Sau đây là bảng các toán tử và độ ưu tiên của chúng, các phép toán trên cùng dòng (thứ tự) có cùng độ ưu tiên, các toán tử trên dòng có thứ tự nhỏ hơn sẽ có độ ưu tiên cao hơn, trong bảng này có một số toán tử không được mô tả trong phần các phép toán như [], (), ., -> chúng sẽ được mô tả trong các phần thích hợp. Bảng thứ tự ưu tiên của các phép toán trong C Mức Các toán tử Trật tự kết hợp 1 () [] . -> ++ (hậu tố) hậu tố 2 ! ~ ++ (tiền tố) (tiền tố) - * & sizeof 3 * / % 4 + - 5 > 6 >= 7 == != 8 & 9 ^ 10 | 11 && 12 || 13 ?: 14 = += -= Ghi chú: trật tự kết hợp từ trái qua phải trật tự kết hợp từ phải qua trái. Nguyên tắc xác định trật tự thực hiện các phép toán i. Biểu thức con trong ngoặc được tính toán trước các phép toán khác ii. Phép toán một ngôi đứng bên trái toán hạng được kết hợp với toán hạng đi liền nó. iii. Nếu toán hạng đứng cạnh hai toán tử thì có 2 khả năng là: Trang 24
  25. a. Nếu hai toán tử có độ ưu tiên khác nhau thì toán tử nào có độ ưu tiên cao hơn sẽ kết hợp với toán hạng b. Nếu hai toán tử cùng độ ưu tiên thì dựa vào trật tự kết hợp của các toán tử để xác định toán tử được kết hợp với toán hạng. 2.2.2.3. Sử dụng biểu thức Trong chương trình, biểu thức được sử dụng cho các mục đích sau: - Làm vế phải, của lệnh gán như công thức tính toán một đại lượng nào đó. - Làm toán hạng trong các biểu thức khác. - Làm tham số thực trong lời gọi hàm. - Làm chỉ số trong các cấu trúc lặp for, while, do while. - Làm biểu thức kiểm tra trong các cấu trúc rẽ nhánh if, switch. 2.3. Các lệnh vào ra dữ liệu Các công cụ lập trình nói chung và ngôn ngữ lập trình nói riêng đều cung cấp cho người dùng các chỉ thị tương ứng để thực hiện vào ra dữ liệu. Để vào ra dữ liệu, ngôn ngữ C cung cấp 2 hàm vào ra cơ bản là printf() và sacnf(). Muốn sử dụng 2 hàm printf() và scanf() ta cần khai báo tệp tiêu đề stdio.h #include 2.3.1. Lệnh hiển thị dữ liệu Cú pháp sử dụng hàm printf ( ) printf(xâu_định_dạng, [danh_sách_tham_số]); Hàm printf() được dùng để hiển thị ra màn hình các loại dữ liệu cơ bản như số, kí tự và xâu kí tự cùng một số hiệu ứng hiển thị đặc biệt. xâu_định_dạng là xâu điều khiển cách thức hiển thị dữ liệu trên thiết bị ra chuẩn(màn hình máy tính). Trong xâu_định_dạng có chứa: - Các kí tự thông thường, chúng sẽ được hiển thị ra màn hình bình thường. - Các nhóm kí tự định dạng dùng để xác định quy cách hiển thị các tham số trong phần danh_sách_tham_số. - Các kí tự điều khiển dùng để tạo các hiệu ứng hiển thị đặc biệt như xuống dòng (‘\n’) hay sang trang (‘\f’) Phần danh_sách_tham_số là các giá trị biến, hằng, biểu thức mà ta muốn hiển thị ra màn hình. Nhóm kí tự định dạng thứ k trong xâu_định_dạng dùng để xác định quy cách hiển thị tham số thứ k trong danh_sách_tham_số. Do đó danh_sách_tham_số phải phù hợp về số lượng, thứ tự và kiểu với các nhóm kí tự định dạng trong xâu_định_dạng. Số lượng tham số trong danh_sách_tham_số bằng số lượng nhóm các kí tự định dạng trong xâu_định_dạng. Ví dụ #include #include void main() { int a = 5; float x = 1.234; Trang 25
  26. printf(“Hien thi mot so nguyen %d và mot so thuc %f”,a,x); getch(); } Kết quả: Hien thi mot so nguyen 5 va mot so thuc 1.234000 Trong ví dụ trên “Hien thi mot so nguyen %d và mot so thuc %f” là xâu định dạng, còn a và x là các tham số của hàm printf(). Trong xâu định dạng trên có 2 nhóm kí tự định dạng là %d và %f, với %d dùng để báo cho máy biết rằng cần phải hiển thị tham số tương ứng (biến a) theo định dạng số nguyên và %f dùng để báo cho máy cần hiển thị tham số tương ứng (biến x) theo định dạng số thực. Một số nhóm kí tự định dạng hay dùng trong C và ý nghĩa: Nhóm kí tự Áp dụng cho kiểu Ghi chú định dạng dữ liệu %d int, long, char Hiển thị tham số tương ứng dưới dạng số nguyên có dấu hệ đếm thập phân %i int, long, char Hiển thị tham số tương ứng dưới dạng số nguyên có dấu hệ đếm thập phân %o int, long, char Hiển thị tham số tương ứng dưới dạng số nguyên không dấu trong hệ đếm cơ số 8. %u int, long, char Hiển thị tham số tương ứng dưới dạng số nguyên không dấu. %x int, long, char Hiển thị tham số tương ứng dưới dạng số nguyên hệ đếm 16 (không có 0x đứng trước), sử dụng các chữ cái a b c d e f %X int, long, char Hiển thị tham số tương ứng dưới dạng số nguyên hệ đếm 16 (không có 0x đứng trước), sử dụng các chữ cái A B C D E F %e float, double Hiển thị tham số tương ứng dưới dạng số thực dấu phẩy động %f float, double Hiển thị tham số tương ứng dưới dạng số thực dấu phẩy tĩnh %g float, double Hiển thị tham số tương ứng số thực dưới dạng ngắn gọn hơn trong 2 dạng dấu phẩy tĩnh và dấu phẩy động %c int, long, char Hiển thị tham số tương ứng dưới dạng kí tự %s char * Hiển thị tham số tương ứng dưới dạng xâu kí tự (xâu kí tự) Để trình bày dữ liệu được đẹp hơn, C cho phép đưa thêm một số thuộc tính định dạng dữ liệu khác vào trong xâu định dạng như độ rộng tối thiểu, căn lề trái, căn lề phải. Độ rộng tối thiểu Trang 26
  27. Thông thường khi hiển thị dữ liệu, C tự động xác định số chỗ cần thiết sao cho hiển thị vừa đủ nội dung dữ liệu. Nếu ta muốn C hiển thị dữ liệu của ta trên một số lượng vị trí xác định bất kể nội dung dữ liệu đó có điền đầy số chỗ được cung cấp hay không, ta có thể chèn một số nguyên vào trong nhóm kí tự định dạng, ngay sau dấu %. Ví dụ khi hiển thị số nguyên a = 1234; printf("\n%5d",a); // dành 5 chỗ để hiển thị số nguyên a printf("\n%5d",34);// dành 5 chỗ để hiển thị số nguyên 34 Kết quả 1234 34 Ở đâykí hiệu thay cho dấu trắng (space). Như vậy với nhóm kí tự định dạng %md, m dùng để báo số chỗ cần dành để hiển thị dữ liệu, còn d báo rằng hãy hiển thị dữ liệu đó dưới dạng một số nguyên. Tương tự với các nhóm kí tự định dạng %mc khi hiển thị kí tự, và %ms khi hiển thị xâu kí tự. Ví dụ printf("\n%3d %15s %3c", 1, "nguyen van a", 'g'); printf("\n%3d %15s %3c", 2, "tran van b", 'k'); Kết quả Nếu nội dung dữ liệu không điền đầy số chỗ được cấp thì những chỗ không dùng đến sẽ được điền bởi dấu trắng. Khi số chỗ cần thiết để hiển thị nội dung dữ liệu lớn hơn m thì C tự động cung cấp thêm chỗ mới để hiển thị chứ không cắt bớt nội dung của dữ liệu để cho vừa m vị trí. Với dữ liệu là số thực ta sử dụng mẫu nhóm kí tự định dạng %m.nf để báo rằng cần dành m vị trí để hiển thị số thực, và trong m vị trí đó dành n vị trí để hiển thị phần thập phân. Ví dụ: printf("\n%f",12.345); printf("\n%.2f",12.345); printf("\n%8.2f",12.345); Kết quả 12.345000 12.35 12.35 Căn lề trái Trang 27
  28. Khi hiển thị dữ liệu, mặc định C căn lề phải. Nếu muốn căn lề trái khi hiển thị dữ liệu ta chỉ cần thêm dấu trừ - vào ngay sau dấu %. Ví dụ printf("\n%-3d %-15s %-4.2f %-3c", 1, "nguyen van a", 8.5, 'g'); printf("\n%-3d %-15s %-4.2f %-3c", 2, "tran van b", 6.75, 'k'); Kết quả 1 nguyen van a 8.50 g 2 tran van b 6.75 k 2.3.2. Lệnh nhập dữ liệu Cú pháp: scanf(xâu_định_dạng, [danh_sách_địa_chỉ]); Hàm scanf() dùng để nhập dữ liệu từ bàn phím. Cụ thể nó sẽ đọc các kí tự được nhập từ bàn phím, sau đó căn cứ theo xâu_định_dạng sẽ chuyển những thông tin đã nhập được sang kiểu dữ liệu phù hợp. Cuối cùng sẽ gán những giá trị vừa nhập được vào các biến tương ứng trong danh_sách_địa_chỉ. xâu_định_dạng trong hàm scanf() xác định khuôn dạng của các dữ liệu được nhập vào. Trong xâu_định_dạng có chứa các nhóm kí tự định dạng xác định khuôn dạng dữ liệu nhập vào. Địa chỉ của một biến được viết bằng cách đặt dấu & trước tên biến. Ví dụ giả sử ta có các biến có tên là a, x, ten_bien thì địa chỉ của chúng lần lượt sẽ là &a, &x, &ten_bien. danh_sách_địa_chỉ phải phù hợp với các nhóm kí tự định dạng trong xâu_định_dạng về số lượng, kiểu dữ liệu và thứ tự. Số nhóm kí tự định dạng bằng số địa chỉ của các biến trong danh_sách_địa_chỉ. Dưới đây là một số nhóm kí tự định dạng hay dùng và ý nghĩa Nhóm kí tự Ghi chú định dạng %d Định khuôn dạng dữ liệu nhập vào dưới dạng số nguyên kiểu int %o Định khuôn dạng dữ liệu nhập vào dưới dạng số nguyên kiểu int hệ cơ số 8 %x Định khuôn dạng dữ liệu nhập vào dưới dạng số nguyên kiểu int hệ cơ số 16 %c Định khuôn dạng dữ liệu nhập vào dưới dạng kí tự kiểu char %s Định khuôn dạng dữ liệu nhập vào dưới dạng xâu kí tự %f Định khuôn dạng dữ liệu nhập vào dưới dạng số thực kiểu float %ld Định khuôn dạng dữ liệu nhập vào dưới dạng số nguyên kiểu long %lf Định khuôn dạng dữ liệu nhập vào dưới dạng số thực kiểu double Ví dụ: #include #include void main() { Trang 28
  29. // khai bao bien int a; float x; char ch; char* str; // Nhap du lieu printf(“Nhap vao mot so nguyen”); scanf(“%d”,&a); printf(“\n Nhap vao mot so thuc”); scanf(“%f”,&x); printf(“\n Nhap vao mot ki tu”); fflush(stdin); scanf(“%c”,&ch); printf(“\n Nhap vao mot xau ki tu”); fflush(stdin); scanf(“%s”,str); // Hien thi du lieu vua nhap vao printf(“\n Nhung du lieu vua nhap vao”); printf(“\n So nguyen: %d”,a); printf(“\n So thuc : %.2f”,x); printf(“\n Ki tu: %c:,ch); printf(“\n Xau ki tu: %s”,str); } Kết quả: Nhap vao mot so nguyen: 2007 Nhap vao mot so thuc: 18.1625 Nhap vao mot ki tu: b Nhap vao mot xau ki tu: ngon ngu lap trinh C Nhung du lieu vua nhap vao So nguyen: 2007 So thuc: 18.16 Ki tu: b Xau ki tu: ngon Một số quy tắc cần lưu ý khi sử dụng hàm scanf() Quy tắc 1: Khi đọc số, hàm scanf() quan niệm rằng mọi kí tự số, dấu chấm (‘.’) đều là kí tự hợp lệ. Khi gặp các dấu phân cách như tab, xuống dòng hay dấu cách (space bar) thì scanf() sẽ hiểu là kết thúc nhập dữ liệu cho một số. Quy tắc 2: Khi đọc kí tự, hàm scanf() cho rằng mọi kí tự có trong bộ đệm của thiết bị vào chuẩn đều là hợp lệ, kể cả các kí tự tab, xuống dòng hay dấu cách. Quy tắc 3: Khi đọc xâu kí tự, hàm scanf() nếu gặp các kí tự dấu trắng, dấu tab hay dấu xuống dòng thì nó sẽ hiểu là kết thúc nhập dữ liệu cho một xâu kí tự. Vì vậy trước khi nhập dữ liệu kí tự hay xâu kí tự ta nên dùng lệnh fflush(stdin). Trang 29
  30. 2.3.3. Lệnh gán Biến có thể nhận một giá trị hằng hoặc giá trị của 1 biểu thức thông qua phép gán hay còn gọi là lệnh gán sau: Tên biến=giá trị; Hoặc Tên biến= Biểu thức; Ví dụ: x=1.234; y=2*x+sin(x); 2.3.4. Các lệnh nhập xuất khác Hàm gets(), có cú pháp gets(xâu_kí_tự); Hàm gets() dùng để nhập vào từ bàn phím một xâu kí tự bao gồm cả dấu cách, điều mà hàm scanf() không làm được. Hàm puts(), có cú pháp puts(xâu_kí_tự); Hàm puts() sẽ hiển thị ra màn hình nội dung xâu_kí_tự và sau đó đưa con trỏ xuống dòng mới. Vì vậy nó tương đương với lệnh printf(“%s\n”,xâu_kí_tự). Hàm getch(), có cú pháp getch(); Hàm getch() là hàm không có tham số. Nó đọc một kí tự bất kì nhập vào từ bàn phím nhưng không hiển thị kí tự đó lên màn hình. Lệnh getch() thường dùng để chờ người sử dụng ấn một phím bất kì rồi sẽ kết thúc chương trình. Để sử dụng các hàm gets(), puts(), getch() ta cần khai báo tệp tiêu đề conio.h. Ví dụ: #include #include void main() { // khai bao bien char* str; // Nhap du lieu puts(“Nhap vao mot xau ki tu:”); fflush(stdin); gets(str); // Hien thi du lieu vua nhap vao puts(“Xau vua nhap vao: ”); puts(str); puts(“An phim bat ki de ket thuc ”); getch(); } Kết quả: Nhap vao mot xau ki tu: Trang 30
  31. ngon ngu lap trinh C Xau vua nhap vao: ngon ngu lap trinh C An phim bat ki de ket thuc Trang 31
  32. THỰC HÀNH TH bài 1: CÀI ĐẶT, SỬ DỤNG MÔI TRƯỜNG LẬP TRÌNH C Mục tiêu của bài: Kiến thức: - Trình bày được các thành phần cơ bản của một chương trình C; - Nêu được các câu lệnh vào ra trong C. Kĩ năng: - Soạn thảo được một chương trình cơ bản; - Chạy và sửa lỗi chương trình trên turbo C. Thái độ: - Tích cực vận dụng nhưng kiến thức đã học vào thực tế. - Tuân thủ nội qui phòng thực hành, đảm bảo an toàn. Nội dung: 1. Thiết bị, dụng cụ, vật tư Máy tính cài phần mềm Code Block 16.01 hoặc phần mềm Turbo C++ 3.0 Giấy, bút. Trang 32
  33. 2. Trình tự thực hiện BẢNG TRÌNH TỰ THỰC HIỆN Yêu cầu kỹ Các bước Dụng cụ, thiết STT Thao tác thuật, an thực hiện bị vật tư toàn 1 Bước 1: Cách 1: File->New->emtyfile Máy tính cài Tạo được Tạo file Cách 2: Ctrl+Shift+N đặt phần mềm 1file .C. mới codeblock Lưu file trong folder 2 Bước 2: Cách 1: Vẽ lưu đồ sơ đồ giải Giấy, bút Giải thuật đề Tìm giải thuật giải phương thuật giải Cách 2: Biểu diễn bằng ngôn trình bậc nhất phương ngữ tự nhiên xét hệ số a trình bậc với 0 nhất 3 Bước 3: Soạn thảo chương trình trên file Máy tính cài Hoàn thành 1 Viết vừa tạo đặt phần mềm chương trình chương codeblock hoàn chỉnh trình gồm đầy đủ các phần. 4 Bước 4: Kick chọn biểu tượng Build and Máy tính cài Không báo Chạy run đặt phần mềm lỗi, hiển thị chương codeblock màn hình kết trình quả Trang 33
  34. 5 Bước 5: Máy tính cài Tìm ra đúng Kiểm tra đặt phần mềm nghiệm của kết quả codeblock phương trình bậc 1 3.An toàn lao động - Chọn nơi làm việc sạch sẽ, rộng rãi, thoáng mát; - Mặc quần áo bảo hộ khi vào phòng thực hành - Chú ý an toàn về điện khi thực hành; - Kiểm tra cẩn thận trước khi cấp nguồn cho máy. 4. Thao tác mẫu Bước 1: Tạo file mới Bước 3: Viết chương trình Bước 4: Chạy chương trình Bước 5: Kiểm tra kết quả STT Sai lầm Nguyên nhân Biện pháp phòng tránh Chương trình báo lỗi, Kiểm tra lỗi trước khi Thiếu câu lệnh, 1 không chạy được chạy, tìm và sửa lỗi tại Gõ sai cú câu lệnh chương trình các dòng báo đỏ Ít nhất 1 trong 2 hệ số a,b 2 Tìm sai nghiệm Để hệ số kiểu nguyên ép kiểu về kiểu số thực Chọn biểu tượng Run Trình biên dịch chưa cập Lưu chương trình trước 3 khi chưa lưu chương nhật thay đổi khi chạy trình BẢNG SAI HỎNG THƯỜNG GẶP 5. Thực hành Giao bài tập cho sinh viên. Sinh viên thực hành theo nhóm và theo trình tự các bước, thực hiện công việc ghi trong sổ thực hành. Bài 1: Nhập và hiển thị 2 số nguyên từ bàn phím? Bài 2: Nhập 2 số nguyên từ bàn phím, tính tổng , hiệu, tích, thương của 2 số đó? Bài 3: Tìm số hàng trăm, chục, đơn vị của 1 số nguyên 3 chữ số? Trang 34
  35. CHƯƠNG 3: CÁC LỆNH CẤU TRÚC MỤC TIÊU CỦA BÀI Sau khi học xong bài này người học có khả năng Kiến thức - Trình bày được cấu trúc lệnh khối, cách sử dụng lệnh lựa chọn theo điều kiện; - Nêu được cấu trúc của các lệnh lặp for, while, do while. Kĩ năng Viết được chương trình đơn giản sử dụng các câu lệnh lựa chọn, lệnh khối, lệnh lặp. Thái độ Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. 3.1. Lệnh khối Một cách hình thức ta có thể định nghĩa một lệnh khối là dãy các câu lệnh được đặt trong cặp dấu ngoặc nhọn { }. { lệnh_1; lệnh_2; . lệnh_n; } Trong lệnh khối có thể chứa lệnh khối khác, ta gọi đó là các lệnh khối lồng nhau. Sự lồng nhau của các lệnh khối là không hạn chế. Các lệnh trong lệnh khối được thực hiện tuần tự theo trật tự xuất hiện. { lệnh; { lệnh; } } C cho phép khai báo biến trong lệnh khối. Ràng buộc duy nhất là phần khai báo phải nằm trước phần câu lệnh. Ví dụ: #include #include void main() // Noi dung cua ham main() cung la mot khoi lenh { // khai bao bien Trang 35
  36. int c; c = 10; printf(“ Gia tri cua c = %d day la c ngoai”,c); // bat dau mot khoi lenh khac { int c; c = 10; printf(“\n Gia tri cua c = %d day la c trong”,c); printf(“\n Tang gia tri cua c them 10 don vi”); c = c + 10; printf(“\n Gia tri cua c = %d day la c trong”,c); } printf(“\n Gia tri cua c = %d day la c ngoai”,c); getch(); } Kết quả: Gia tri cua c = 10 day la c ngoai Gia tri cua c = 10 day la c trong Tang gia tri cua c them 10 don vi Gia tri cua c = 20 day la c trong Gia tri cua c = 10 day la c ngoai 3.2. Lệnh lựa chọn 3.2.1. Lệnh lựa chọn theo điều kiện if Câu lệnh if cho phép lựa chọn một trong hai nhánh tùy thuộc vào giá trị của biểu thức luận lý là đúng (true) hay sai (false) hoặc khác không hay bằng không. Lệnh if có 2 dạng: - Dạng 1(còn gọi là dạng if khuyết) Cú pháp: if (biểu_thức_điều_kiện) lệnh; Công dụng: nếu biểu thức luận lý đúng thì thực hiện khối lệnh và thoát khỏi if, ngược lại không làm gì cả và thoát khỏi if - Dạng 2(if đầy đủ) Cú pháp: if (biểu_thức_điều_kiện) lệnh_1; else lệnh_2; Công dụng: nếu biểu thức luận lý đúng thì thực hiện khối lệnh 1 và thoát khỏi if ngược lại thực hiện khối lệnh 2 và thoát khỏi if Lưu ý: là lệnh, lệnh_1 và lệnh_2 có thể là lệnh khối. Trang 36
  37. if (biểu_thức_điều_kiện) if (biểu_thức_điều_kiện) lệnh_1; lệnh_1; lệnh_kế_tiếp else lệnh_2; lệnh_kế_tiếp 0 1 0 1 biểu_thức_điều_kiện == 0 ? biểu_thức_điều_kiện = = 0 ? lệnh_1 lệnh_1 lệnh_2 lệnh_kế_tiếp lệnh_kế_tiếp Ví dụ 1: Viết chương trình nhập vào 2 số nguyên a, b. Tìm và in ra số lớn nhất. a. Phác họa lời giải Trước tiên ta cho giá trị a là giá trị lớn nhất bằng cách gán a cho max (max là biến được khai báo cùng kiểu dữ liệu với a, b). Sau đó so sánh b với a, nếu b lớn hơn a ta gán b cho max và cuối cùng ta được kết quả max là giá trị lớn nhất. b. Mô tả quy trình xử lý (giải thuật) Ngôn ngữ tự nhiên Ngôn ngữ C - Khai báo 3 biến a, b, max kiểu số - int ia, ib, imax; nguyên - printf("Nhap vao so a: "); - Nhập vào giá trị a scanf("%d", &ia); - Nhập vào giá trị b - printf("Nhap vao so b: "); - Gán a cho max scanf("%d", &ib); - Nếu b > a thì gán b cho max - imax = ia; - In ra kết quả max - if (ib > ia) imax = ib; - printf("So lon nhat = %d.\n", imax); c. Mô tả bằng lưu đồ Trang 37
  38. d. Viết chương trình Kết quả in ra màn hình Nhap vao so a : 10 Cho chạy lại chương trình và thử lại với: Nhap vao so b : 8 a = 7, b = 9 So lon nhat = 10. a = 5, b = 5 Quan sát và nhận xét kết quả Ví dụ 2: Viết chương trình nhập vào 2 số nguyên a, b. In ra thông báo "a bằng b" nếu a = b, ngược lại in ra thông báo "a khác b". a. Phác họa lời giải So sánh a với b, nếu a bằng b thì in ra câu thông báo "a bằng b", ngược lại in ra thông báo "a khác b". b. Mô tả quy trình xử lý (giải thuật) Ngôn ngữ tự nhiên Ngôn ngữ C - Khai báo 2 biến a, b kiểu số nguyên - int ia, ib; - Nhập vào giá trị a - printf("Nhap vao so a: "); - Nhập vào giá trị b scanf("%d", &ia); - Nếu a = b thì in ra thông báo "a bằng b" - printf("Nhap vao so b: "); Ngược lại (còn không thì) in ra thông scanf("%d", &ib); báo "a khác b" - if (ia == ib) printf("a bang b\n"); else printf("a khac b\n"); Trang 38
  39. c. Mô tả bằng lưu đồ d. Viết chương trình Kết quả in ra màn hình Nhap vao so a : 10 Cho chạy lại chương trình và thử lại với: Nhap vao so b : 8 a = 6, b = 6 a khac b a = 1, b = 5 Quan sát và nhận xét kết quả Lưu ý: Các lệnh if else lồng nhau thì else sẽ luôn luôn kết hợp với if nào chưa có else gần nhất. Vì vậy khi gặp những lệnh if không có else, Bạn phải đặt chúng trong những khối lệnh rõ ràng để tránh bị hiểu sai câu lệnh 3.2.2. Lệnh switch Lệnh switch cũng giống cấu trúc else if, nhưng nó mềm dẻo hơn và linh động hơn nhiều so với sử dụng if. Tuy nhiên, nó cũng có mặt hạn chế là kết quả của biểu Trang 39
  40. thức phải là giá trị hằng nguyên (có giá trị cụ thể). Một bài toán sử dụng lệnh switch thì cũng có thể sử dụng if, nhưng ngược lại còn tùy thuộc vào giải thuật của bài toán Cú pháp cấu trúc switch switch (biểu_thức) { case giá_trị_1: lệnh_1; [break;] case giá_trị_2: lệnh_2; [break;] case giá_trị_n: lệnh_n; [break;] [default: lệnh_n+1; [break;]] } Cơ chế hoạt động: câu lệnh switch ban đầu sẽ tính giá trị của biểu_thức, sau đó so sánh với các giá_trị_k với k = 1, 2, , n đứng sau case. Xảy ra 2 trường hợp Nếu trong dãy các giá trị giá_trị_1, giá_trị_2, tồn tại giá trị bằng biểu_thức. Gọi i là chỉ số của giá trị đầu tiên trong dãy thỏa mãn giá_trị_i bằng biểu_thức, khi đó lệnh_i sẽ được thực hiện. Sau khi thực hiện xong lệnh_i, nếu có lệnh break thì chương trình sẽ chuyển sang thực hiện lệnh tiếp sau cấu trúc switch. Nếu không có lệnh break thì chương trình sẽ chuyển sang thực hiện các lệnh sau lệnh_i nằm trong switch (tức là lệnh_i+1, lệnh_i+2 ) cho đến khi gặp lệnh break đầu tiên hoặc sau khi thực hiện xong lệnh n. Sau đó chương trình sẽ chuyển sang thực hiện lệnh tiếp theo sau cấu trúc switch. Nếu không tồn tại giá_trị_k (với k = 1, 2, n) nào bằng giá trị của biểu_thức thì sẽ có 2 khả năng: o Nếu có nhãn default: chương trình sẽ thực hiện lệnh_n+1 rồi chuyển sang thực hiện lệnh tiếp theo sau cấu trúc switch. o Nếu không có nhãn default: chương trình chuyển sang thực hiện lệnh tiếp theo sau cấu trúc switch. Sơ đồ: 0 0 0 biểu_thức == giá_trị_1 ? biểu_thức == giá_trị_2 ? . . . biểu_thức == giá_trị_n ? 1 1 1 lệnh_1 lệnh_2 lệnh_n 0 0 0 break ? break ? break ? 1 1 1 Ví dụ: Trang 40
  41. /* Ví dụ sau yêu cầu người dùng nhập vào một số nguyên không âm và đưa ra ngày trong tuần tương ứng với số nguyên đó. Và ở đây ta quy ước những số chia hết cho 7 ứng với Chủ nhật, chia 7 dư 1 ứng với thứ Hai, , chia 7 dư 6 ứng với thứ Bảy.*/ #include #include void main() { // khai bao bien int a; do { printf(“\n Nhap mot gia tri so nguyen khong am: “); scanf(“%d”,&a); if(a #include Trang 41
  42. int main () { int thang; clrscr(); printf("\n Nhap vao thangs trong nam "); scanf("%d",&thang); switch(thang) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: printf("\n Thang %d co 31 ngay ",thang); break; case 4: case 6: case 9: case 11: printf("\n Thang %d co 30 ngay ",thang); break; case 2: printf ("\ Thang 2 co 28 hoac 29 ngay"); break; default : printf("\n Khong co thang %d", thang); break; } getch(); return 0; } Lưu ý: giá trị của biểu thức kiểm tra phải là số nguyên tức là phải có kiểu dữ liệu là char, int, long. Một cách tương ứng các giá trị sau case cũng phải nguyên. Đây là một trong những điểm phân biệt giữa cấu trúc switch và if else. 3.3. Lệnh lặp Trong thuật toán có 3 cấu trúc điều khiển cơ bản là tuần tự, rẽ nhánh và lặp. Để thể hiện cấu trúc lặp, C cung cấp các cấu trúc lặp sau: vòng lặp for, vòng lặp while, vòng lặp do while. 3.3.1. Lệnh for Dạng thường gặp của vòng lặp for là Trang 42
  43. for([biểu_thức_1];[biểu_thức_2];[biểu_thức_3]) lệnh; Sơ đồ for([biểu_thức_1];[biểu_thức_2];[biểu_thức_3]) lệnh Thực hiện tính giá trị biểu_thức_1 Thực hiện tính giá trị Thực hiện tính giá trị biểu_thức_2 biểu_thức_3 0 biểu_thức_2 == 0 lệnh 1 Câu lệnh for thường dùng để thực hiện lặp đi lặp lại một công việc nào đó với số lần lặp xác định. Giải thích: + biểu_thức_1: khởi tạo giá trị ban đầu cho biến điều khiển. + biểu_thức_2: là quan hệ logic thể hiện điều kiện tiếp tục vòng lặp. + biểu_thức_3: phép gán dùng thay đổi giá trị biến điều khiển. Nhận xét: + biểu_thức_1 bao giờ cũng chỉ được tính toán một lần khi gọi thực hiện for. + biểu_thức_2,3 và thân for có thể thực hiện lặp lại nhiều lần. Lưu ý: + biểu_thức_1,2,3 phải phân cách bằng dấu chấm phẩy (;) + Nếu biểu_thức_2 không có, vòng for được xem là luôn luôn đúng. Muốn thoát khỏi vòng lặp for phải dùng một trong 3 lệnh break, goto hoặc return. + Với mỗi biểu thức có thể viết thành một dãy biểu thức con phân cách nhau bởi dấu phẩy. Khi đó các biểu thức con được xác định từ trái sang phải. Tính đúng sai của dãy biểu thức con trong biểu thức thứ 2 được xác định bởi biểu thức con cuối cùng. + Trong thân for (khối lệnh) có thể chứa một hoặc nhiều cấu trúc điều khiển khác. + Khi gặp lệnh break, cấu trúc lặp sâu nhất sẽ thoát ra. + Trong thân for có thể dùng lệnh goto để thoát khỏi vòng lặp đến vị trí mong muốn. + Trong thân for có thể sử dụng return để trở về một hàm nào đó. + Trong thân for có thể sử dụng lệnh continue để chuyển đến đầu vòng lặp (bỏ qua các câu lệnh còn lại trong thân). Ví dụ 1: Viết chương trình nhập vào số nguyên n. Tính tổng các giá trị lẻ từ 0 đến n. Trang 43
  44. Kết quả in ra màn hình Nhap vao so n : 5 Bạn thay các dòng từ 11 đến 16 bằng câu lệnh: Tong: 9. for(is=0, i=1; i = 1; i ) - Thay đổi biến điều khiển từ 7 đến 77, mỗi lần tăng 7: for(i = 7; i = 2; i –= 2) 3.3.2. Lệnh while Vòng lặp thực hiện lặp lại trong khi biểu thức còn đúng. Cú pháp: while (biểu thức) khối lệnh; Sơ đồ Trang 44
  45. while (biểu_thức) lệnh; Tính toán giá trị của biểu_thức lệnh 0 biểu_thức == 0? 1 Công dụng: Trước tiên biểu thức được kiểm tra nếu sai thì kết thúc vòng lặp while (khối lệnh không được thi hành 1 lần nào) nếu đúng thực hiện khối lệnh; lặp lại kiểm tra biểu thức - Biểu thức: có thể là một biểu thức hoặc nhiều biểu thức con. Nếu là nhiều biểu thức con thì cách nhau bởi dấu phẩy (,) và tính đúng sai của biểu thức được quyết định bởi biểu thức con cuối cùng. - Trong thân while (khối lệnh) có thể chứa một hoặc nhiều cấu trúc điều khiển khác. - Trong thân while có thể sử dụng lệnh continue để chuyển đến đầu vòng lặp (bỏ qua các câu lệnh còn lại trong thân). - Muốn thoát khỏi vòng lặp while tùy ý có thể dùng các lệnh break, goto, return như lệnh for. Ví dụ: Viết chương trình tính tổng các số nguyên từ 1 đến n, với n được nhập vào từ bàn phím. Trang 45
  46. Kết quả in ra màn hình Nhap vao so n : 5 Bạn thay các dòng từ 11 đến 12 bằng câu lệnh: Tong: 15. while(is = is+i, i++ < in); Chạy lại chương trình, quan sát và nhận xét kết quả 3.3.3. Lệnh do while Vòng lặp thực hiện lặp lại cho đến khi biểu thức sai. Cú pháp: do { lệnh; }while (biểu_thức); Sơ đồ do { lệnh; } while (biểu_thức) lệnh Tính toán giá trị của biểu_thức 0 biểu_thức == 0? 1 Công dụng: Thực hiện khối lệnh Kiểm tra biểu thức Nếu đúng thì lặp lại thực hiện khối lệnh Nếu sai thì kết thúc vòng lặp (khối lệnh được thi hành 1 lần) - Biểu thức: có thể là một biểu thức hoặc nhiều biểu thức con. Nếu là nhiều biểu thức con thì cách nhau bởi dấu phẩy (,) và tính đúng sai của biểu thức được quyết định bởi biểu thức con cuối cùng. - Trong thân do while (khối lệnh) có thể chứa một hoặc nhiều cấu trúc điều khiển khác. - Trong thân do while có thể sử dụng lệnh continue để chuyển đến đầu vòng lặp (bỏ qua các câu lệnh còn lại trong thân). - Muốn thoát khỏi vòng lặp do while tùy ý có thể dùng các lệnh break, goto, return. Ví dụ: Viết chương trình kiểm tra password. Trang 46
  47. Kết quả in ra màn hình Nhap vao password: 1123 Bạn thay các dòng từ 10 đến 14 bằng câu lệnh: Nhap vao password: 12346 do{}while(printf("Nhap vao password: "), scanf("%d", Nhap vao password: 12345 &in), in != PASSWORD); Chạy lại chương trình và quan sát kết quả - Các vòng lặp while, do{ }while, hay for sẽ kết thúc quá trình lặp khi biểu thức điều kiện của vòng lặp không còn được thỏa mãn. Tuy nhiên trong lập trình đôi khi ta cũng cần thoát khỏi vòng lặp ngay cả khi biểu thức điều kiện của vòng lặp vẫn còn được thỏa mãn. Để hỗ trợ người lập trình làm việc đó, ngôn ngữ C cung cấp 2 câu lệnh là continue và break Vòng lặp với các lệnh break và continue Điều kiện lặp còn thỏa mãn break continue Lệnh tiếp theo Lệnh tiếp theo Lệnh tiếp theo Lệnh continue Trang 47
  48. Khi gặp lệnh continue trong thân vòng lặp, chương trình sẽ chuyển sang thực hiện một vòng lặp mới và bỏ qua việc thực hiện các câu lệnh nằm sau lệnh continue trong thân vòng lặp. Ví dụ sau đây sẽ in ra màn hình các số tự nhiên lẻ và nhỏ hơn 100 #include #include void main() { int i; for(i = 1;i #include void main() { char ch; clrscr(); do { printf(“\n Nhap vao mot ki tu: “); fflush(stdin); scanf(“%c”,&ch); Trang 48
  49. printf(“\n Ki tu vua nhap vao la %c”,ch); if((ch ==’T’)||(ch ==’t’)) break; }while(1); printf(“\n An phim bat ki de ket thuc chuong trinh ”); getch(); } Kết quả thực hiện chương trình Nhap vao mot ki tu: a Ki tu vua nhap vao la a Nhap vao mot ki tu: 5 Ki tu vua nhap vao la 5 Nhap vao mot ki tu: t Ki tu vua nhap vao la t An phim bat ki de ket thuc chuong trinh Trang 49
  50. TH BÀI 2: LẬP TRÌNH VỚI LỆNH KHỐI VÀ LỆNH LỰA CHỌN Mục tiêu của bài: Kiến thức Trình bày được cấu trúc lệnh khối, cách sử dụng lệnh lựa chọn theo điều kiện. Kĩ năng Giải được một số bài toán so sánh đơn giản Thái độ - Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. - Cẩn thận, tỉ mỉ tuân thủ nội qui phòng thực hành, đảm bảo an toàn cho người và thiết bị. Nội dung: 1. Thiết bị, dụng cụ, vật tư Máy tính cài phần mềm Code Block 16.01 hoặc phần mềm Turbo C++ 3.0. Giấy, bút. 2. Trình tự thực hiện BẢNG TRÌNH TỰ THỰC HIỆN Yêu cầu kỹ Các bước Dụng cụ, thiết STT Thao tác thuật, an thực hiện bị vật tư toàn Trang 50
  51. 1 Bước 1: Cách 1: File->New->emtyfile Máy tính cài Tạo được Tạo file Cách 2: Ctrl+Shift+N đặt phần mềm 1file .C. mới codeblock Lưu file trong folder 2 Bước 2: Cách 1: Vẽ lưu đồ sơ đồ giải Giấy, bút Giải thuật đề Tìm giải thuật tìm nghiệm thuật giải Cách 2: Biểu diễn bằng ngôn của phương phương ngữ tự nhiên trình bậc 2. trình bậc 2 3 Bước 3: Soạn thảo chương trình trên file Máy tính cài Hoàn thành 1 Viết vừa tạo đặt phần mềm chương trình chương codeblock hoàn chỉnh trình gồm đầy đủ các phần. 4 Bước 4: Kick chọn biểu tượng Build and Máy tính cài Không báo Chạy run đặt phần mềm lỗi, hiển thị chương codeblock màn hình kết trình quả 5 Bước 5: Máy tính cài Tìm ra đúng Kiểm tra đặt phần mềm các nghiệm kết quả codeblock của phương trình bậc 2 3.An toàn lao động - Chọn nơi làm việc sạch sẽ, rộng rãi, thoáng mát; - Mặc quần áo bảo hộ khi vào phòng thực hành - Chú ý an toàn về điện khi thực hành; - Kiểm tra cẩn thận trước khi cấp nguồn cho máy. 4. Thao tác mẫu Bước 1: Tạo file mới Bước 3: Viết chương trình Bước 4: Chạy chương trình Bước 5: Kiểm tra kết quả STT Sai lầm Nguyên nhân Biện pháp phòng tránh Kiểm tra lỗi trước khi Chương trình báo lỗi, Thiếu câu lệnh, chạy, tìm và sửa lỗi tại 1 không chạy được Gõ sai cú câu lệnh các dòng báo đỏ chương trình Khai báo thiếu thư viện Khai báo thư viện Math.h Tính delta và xét điều 2 Tìm sai nghiệm Tính sai delta kiện theo delta Chọn biểu tượng Run Trình biên dịch chưa cập Lưu chương trình trước 3 khi chưa lưu chương nhật thay đổi khi chạy Trang 51
  52. trình BẢNG SAI HỎNG THƯỜNG GẶP 5. Thực hành Giao bài tập cho sinh viên. Sinh viên thực hành theo nhóm và theo trình tự các bước, thực hiện công việc ghi trong sổ thực hành. Bài 1: Giải phương trình bậc 2 với hệ số a,b,c nhập từ bàn phím? Bài 2: Nhập vào số nguyên dương n, kiểm tra xem n là số chính phương hay không? Bài 3: Nhập vào số nguyên dương n từ 1 đến 12, kiểm tra xem n là tháng nào trong năm? Trang 52
  53. TH BÀI 3: LẬP TRÌNH VỚI LỆNH LẶP Kiến thức Trình bày được cấu trúc lệnh lặp for, while, do while, cách sử dụng lệnh lặp này theo từng bài toán. Kĩ năng Viết chương trình sử dụng các câu lệnh lặp for, while, do while. Thái độ - Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. - Cẩn thận, tỉ mỉ tuân thủ nội qui phòng thực hành, đảm bảo an toàn cho người và thiết bị. Nội dung: 1. Thiết bị, dụng cụ, vật tư Máy tính cài phần mềm Code Block 16.01 Turbo C++ 3.0 Giấy, bút. 2. Trình tự thực hiện BẢNG TRÌNH TỰ THỰC HIỆN Yêu cầu kỹ Các bước Dụng cụ, thiết STT Thao tác thuật, an thực hiện bị vật tư toàn 1 Bước 1: Cách 1: File->New->emtyfile Máy tính cài Tạo được Tạo file Cách 2: Ctrl+Shift+N đặt phần mềm 1file .C. mới codeblock Lưu file trong folder 2 Bước 2: Cách 1: Vẽ lưu đồ sơ đồ giải Giấy, bút Giải thuật đề Tìm giải thuật kiểm tra số thuật giải Cách 2: Biểu diễn bằng ngôn nguyên tố kiểm tra số ngữ tự nhiên nguyên tố 3 Bước 3: Soạn thảo chương trình trên file Máy tính cài Hoàn thành 1 Viết vừa tạo đặt phần mềm chương trình chương codeblock hoàn chỉnh trình gồm đầy đủ các phần. 4 Bước 4: Kick chọn biểu tượng Build and Máy tính cài Không báo Chạy run đặt phần mềm lỗi, hiển thị chương codeblock màn hình kết trình quả 5 Bước 5: Máy tính cài Kiểm tra Kiểm tra đặt phần mềm đúng các số kết quả codeblock nguyên tố Trang 53
  54. 3.An toàn lao động - Chọn nơi làm việc sạch sẽ, rộng rãi, thoáng mát; - Mặc quần áo bảo hộ khi vào phòng thực hành - Chú ý an toàn về điện khi thực hành; - Kiểm tra cẩn thận trước khi cấp nguồn cho máy. 4. Thao tác mẫu Bước 1: Tạo file mới Bước 3: Viết chương trình Bước 4: Chạy chương trình Bước 5: Kiểm tra kết quả BẢNG SAI HỎNG THƯỜNG GẶP 5. Thực hành Giao bài tập cho sinh viên. Sinh viên thực hành theo nhóm và theo trình tự các bước, thực hiện công việc ghi trong sổ thực hành. Bài 1: Tính tổng S=1+2+ .+n với n là số nguyên dương nhập từ bàn phím? Bài 2: Nhập vào số nguyên dương n, tính giai thừa của số n đó? Bài 3: Nhập vào số nguyên dương n, kiểm tra xem n là số nguyên tố hay không? Bài 4: Hiển thị ra màn hình tất cả các nghiệm của số nguyên a? Trang 54
  55. TH BÀI 3: LẬP TRÌNH VỚI LỆNH LẶP (tiếp) Mục tiêu của bài: Kiến thức Trình bày được cấu trúc lệnh lặp for, while, do while, cách sử dụng lệnh lặp này theo từng bài toán. Kĩ năng Giải được một số bài toán sử dụng lệnh lặp. Thái độ - Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. Cẩn thận, tỉ mỉ tuân thủ nội qui phòng thực hành, đảm bảo an toàn cho người và thiết bị. Nội dung: 1. Thiết bị, dụng cụ, vật tư Máy tính cài phần mềm Code Block 16.01 hoặc phần mềm Turbo C++ 3.0 Giấy, bút. 2. Trình tự thực hiện BẢNG TRÌNH TỰ THỰC HIỆN Yêu cầu kỹ Các bước Dụng cụ, thiết STT Thao tác thuật, an thực hiện bị vật tư toàn 1 Bước 1: Cách 1: File->New->emtyfile Máy tính cài Tạo được Tạo file Cách 2: Ctrl+Shift+N đặt phần mềm 1file .C. mới codeblock Lưu file trong folder 2 Bước 2: Cách 1: Vẽ lưu đồ sơ đồ giải Giấy, bút Giải thuật đề Tìm giải thuật tính tính tổng thuật giải Cách 2: Biểu diễn bằng ngôn các số lẻ từ 1 tính tổng ngữ tự nhiên đến n của các số lẻ từ 1 -> n 3 Bước 3: Soạn thảo chương trình trên file Máy tính cài Hoàn thành 1 Viết vừa tạo đặt phần mềm chương trình chương codeblock hoàn chỉnh trình gồm đầy đủ các phần. 4 Bước 4: Kick chọn biểu tượng Build and Máy tính cài Không báo Chạy run đặt phần mềm lỗi, hiển thị chương codeblock màn hình kết trình quả 5 Bước 5: Máy tính cài Tìm ra đúng Kiểm tra đặt phần mềm tổng của các Trang 55
  56. kết quả codeblock số lẻ từ 1 ->n 3.An toàn lao động - Chọn nơi làm việc sạch sẽ, rộng rãi, thoáng mát; - Mặc quần áo bảo hộ khi vào phòng thực hành - Chú ý an toàn về điện khi thực hành; - Kiểm tra cẩn thận trước khi cấp nguồn cho máy. 4. Thao tác mẫu Bước 1: Tạo file mới Bước 3: Viết chương trình Bước 4: Chạy chương trình Bước 5: Kiểm tra kết quả BẢNG SAI HỎNG THƯỜNG GẶP STT Sai lầm Nguyên nhân Biện pháp phòng tránh Chương trình báo lỗi, Kiểm tra lỗi trước khi Thiếu câu lệnh, 1 không chạy được chạy, tìm và sửa lỗi tại Gõ sai cú câu lệnh chương trình các dòng báo đỏ Tìm sai các số lẻ từ 1 Kiểm tra các số lẻ trước 2 Chưa có câu lệnh kiểm tra đến n khi tính tổng Đặt giá trị biến S=0 trước 3 Tính sai tổng Chưa đặt biến S=0 khi tính tổng 5. Thực hành Giao bài tập cho sinh viên. Sinh viên thực hành theo nhóm và theo trình tự các bước, thực hiện công việc ghi trong sổ thực hành. Bài 1: Tính tổng S=1+3+ .+n với n là số nguyên dương nhập từ bàn phím? Bài 2: Tính dân số của thành phố A sau 10 năm, biết rằng dân số hiện tại là 2000 và mỗi năm dân số tăng 5% mỗi năm? Bài 3: Hiển thị ra màn hình tất cả các số nguyên tố từ 1 đến số nguyên dương a? Trang 56
  57. CHƯƠNG 4: HÀM TRONG C MỤC TIÊU CỦA BÀI Sau khi học xong bài này người học có khả năng Kiến thức: Trình bày về các loại chương trình con, cách khai báo hàm, các hàm thư viện thường gặp. Kĩ năng: Viết được một chương trình con đơn giản và gọi chương trình con trong hàm main. Thái độ: Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. 4.1. Khái niệm về hàm và thư viện 4.1.1. Chương trình con (Subprogram) Trong khi lập trình chúng ta thường gặp những đoạn chương trình lặp đi lặp lại nhiều lần ở những chỗ khác nhau. Để tránh rườm rà và tiết kiệm công sức, những đoạn chương trình đó được thay thế bởi các chương trình con tương ứng và khi cần ta chỉ việc gọi những chương trình con đó ra mà không phải viết lại cả đoạn chương trình đó. Lấy ví dụ khi giải các bài toán lượng giác ta thường xuyên cần phải tính giá trị sin của đại lượng lượng giác x nào đó. Như vậy ta nên lập một chương trình con tên là sin và tham số là x để tính giá trị sin(x). Mỗi khi cần tính toán giá trị sin của một đại lượng y nào đó thì ta chỉ cần gọi chương trình con sin đã lập sẵn và truyền đại lượng y làm tham số cho chương trình con sin đó thì ta vẫn thu được kết quả mong muốn mà không phải viết lại cả đoạn chương trình tính giá trị sin(y). Bên cạnh chương trình con sin còn có rất nhiều chương trình con khác được tạo sẵn như cos, exp (dùng để tính lũy thừa cơ số e), pow (tính lũy thừa), sqrt (tính căn bậc 2), giúp người lập trình tính toán giá trị của các đại lượng thông dụng. Những chương trình con này nằm trong thư viện các chương trình con mẫu và được trình biên dịch C quản lý, vì vậy chúng còn được gọi là các chương trình con chuẩn. Trình biên dịch Turbo C++ phân loại và đặt các chương trình con chuẩn này trong các đơn vị chương trình khác nhau dưới dạng các tệp tiêu đề như stdio.h, conio.h, math.h, string.h Ngoài ra còn có một lý do khác cần đến chương trình con. Khi ta giải quyết một bài toán lớn thì chương trình của ta có thể rất lớn và dài, điều này làm cho việc sửa chữa, gỡ rối, hiệu chỉnh chương trình gặp nhiều khó khăn. Nhưng nếu ta chia bài toán lớn, phức tạp ban đầu thành các bài toán con nhỏ hơn và tương đối độc lập với nhau, rồi lập các chương trình con giải quyết từng bài toán con, cuối cùng ghép các chương trình con đó lại thành một chương trình giải quyết bài toán ban đầu thì sẽ rất tiện lợi cho việc phát triển, kiểm tra và sửa chữa cả chương trình. Việc này tương tự như trong dây chuyền sản xuất công nghiệp khi ta lắp ráp sản phẩm hoàn thiện từ các bán thành phẩm, các module được chế tạo ở những nơi khác nhau. Vì các bán thành phẩm này được chế tạo độc lập nên khi phát hiện lỗi ở module nào ta chỉ việc tìm đến nơi sản xuất ra nó để sửa chữa. Trang 57
  58. Việc chia nhỏ một chương trình thành các chương trình con đảm nhận những công việc nhỏ khác nhau chính là tư tưởng chính cho phương pháp lập trình có cấu trúc (structured programming). Cần lưu ý là có khi một chương trình con chỉ sử dụng đúng một lần nhưng nó vẫn làm cho chương trình trở nên sáng sủa và dễ đọc, dễ hiểu hơn. Có 2 loại chương trình con là hàm (function) và thủ tục (procedure). Sự khác nhau giữa hàm và thủ tục là ở chỗ hàm sau khi thực hiện xong thì sẽ trả về giá trị, còn thủ tục không trả về giá trị gì cả. Mặc dù vậy hàm và thủ tục là tương đương nhau, tức là có thể xây dựng được thủ tục có chức năng tương đương với một hàm bất kì và có thể xây dựng được hàm có chức năng tương đương với một thủ tục bất kì. Vì thế có những ngôn ngữ lập trình cho phép chương trình con có thể là hàm và thủ tục (Pascal) và có những ngôn ngữ chỉ cho phép chương trình con là hàm mà thôi (như C, Java). Lưu ý là nếu chương trình con là hàm thì nó luôn có giá trị trả về. Nếu thực sự không có giá trị gì để trả về (nghĩa là nó hoạt động giống thủ tục) thì ta phải khai báo hàm đó có kiểu giá trị trả về là “không là kiểu giá trị nào cả” (kiểu void trong C). 4.1.2. Một số đặc tính của hàm trong C Một chương trình C có thể bao gồm nhiều hàm và trong đó nhất thiết phải có hàm main(). Hàm trong C có một số đặc tính khác biệt sau: - Giá trị của hàm có thể không dùng đến. Đó là trường hợp hàm printf() và scanf() mà chúng ta đã dùng nhiều trong các chương trước với công dụng là lệnh hiển thị và nhập dữ liệu. Hai hàm này có giá trị là số, song chúng ta hầu như không sử dụng đến. - Hàm có thể không có giá trị trả lại qua tên hàm (giá trị gán cho tên hàm). Ví dụ với các hàm có kiểu void như hàm main() - Hàm có thể không có đối số. Ví dụ hàm main(). 4.1.3. Thư viện hàm chuẩn Cũng như các ngôn ngữ khác, C có nhiều hàm được lập sẵn. Để thuận lợi cho việc sử dụng, các hàm này được chia thành các nhóm theo chức năng và được lưu trong các tệp tiêu đề header có tên *.h. Sau đây là một số tệp header (tệp thư viện mẫu): stdio.h Thư viện các hàm input/output (printf,scanf, ) math.h Thư viện các hàm toán học (sin,có,pow, ) string.h Thư viện các hàm về xâu ký tự (strlen,strcpy,strcmp, ) ctype.h Thư viện các hàm xử lý ký tự (toupper, ) conio.h Thư viện các hàm về màn hình,bàn phím (clrscr(),getch(), ) Trước khi sử dụng các hàm, phải khai báo các tệp header chứa chúng bằng lệnh khai báo sau: #include Ví dụ: Trước khi dùng hàm sin phải có khai báo tệp header math.h như sau: #include Trang 58
  59. Mặc dù C cung cấp khá nhiều hàm, song không thể đáp ứng mọi yêu cầu của tất cả người dùng ở các lĩnh vực xử lý khác nhau. Như các ngôn ngữ khác, C cung cấp cơ chế xây dựng hàm cho người dùng. Hàm do người dùng tự xây dựng gọi là hàm do người sử dụng định nghĩa (User Defined Function - UDF) 4.2. Quy trình xây dựng hàm 4.2.1. Khai báo hàm Cú pháp khai báo một hàm trong C là như sau [ ] ([ , ]) Thân hàm Khai báo của một hàm được chia làm 2 phần: - Dòng đầu hàm: [ ] ([ , ]) - Thân hàm: là tập hợp các khai báo và câu lệnh đặt trong cặp dấu ngoặc nhọn { } Trong thân hàm có ít nhất một lệnh return. Ví dụ sau là khai báo và định nghĩa hàm tính giai thừa của một số nguyên dương. Ta quy ước rằng giai thừa của một số âm thì bằng –1, của 0 bằng 0, của một số nguyên dương a là a! = a (a-1) 1. int giai_thua(int a) Dòng đầu hàm { int ket_qua; Các khai báo int i; ket_qua = 1; for(i = 0;i<a;i++) ket_qua = ket_qua * i; Các câu lệnh if(a < 0) ket_qua = -1; if(a == 0) ket_qua = 0; return ket_qua; } Các thành phần của dòng đầu hàm Dòng đầu hàm là các thông tin được trao đổi giữa bên trong và bên ngoài hàm. Khi nói tới dòng đầu hàm là ta nói tới tên của hàm, hàm đó cần những thông tin gì từ Trang 59
  60. môi trường để hoạt động (các tham số đầu vào), hàm đó cung cấp những thông tin gì cho môi trường (những tham số đầu ra và giá trị trả về). Dòng đầu hàm phân biệt các hàm với nhau, hay nói cách khác không được có 2 hàm có dòng đầu hàm giống nhau. Kiểu dữ liệu trả về của hàm Thông thường hàm sau khi được thực hiện sẽ trả về một giá trị kết quả tính toán nào đó. Để sử dụng được giá trị đó ta cần phải biết nó thuộc kiểu dữ liệu gì. Kiểu dữ liệu của đối tượng tính toán được hàm trả về được gọi là kiểu dữ liệu trả về của hàm. Trong C, kiểu dữ liệu trả về của hàm có thể là kiểu dữ liệu bất kì (kiểu dữ liệu có sẵn hoặc kiểu dữ liệu do người dùng tự định nghĩa) nhưng không được là kiểu dữ liệu mảng. Nếu kiểu dữ liệu trả về là kiểu void thì hàm không trả về giá trị nào cả. Trường hợp ta không khai báo kiểu dữ liệu trả về thì chương trình dịch của C sẽ ngầm hiểu rằng kiểu dữ liệu trả về của hàm là kiểu int. Tên hàm Tên hàm là có thể là bất kì một định danh hợp lệ nào. Tuy nhiên tên hàm nên mang nghĩa gợi ý chức năng công việc mà hàm thực hiện. Ví dụ một hàm có chức năng tính và trả về bình phương của một số thực x thì nên có tên là binh_phuong. Trong C, các hàm không được đặt tên trùng nhau. Tham số của hàm Tham số của hàm là các thông tin cần cho hoạt động của hàm và các thông tin, kết quả tính toán được hàm trả lại. Tức là có những tham số chứa dữ liệu vào cung cấp cho hàm, có những tham số chứa dữ liệu ra mà hàm tính toán được. Các tham số sử dụng trong lời khai báo hàm được gọi là tham số hình thức. Nó là tham số giả định của hàm. Khi khai báo tham số hình thức của hàm phải chỉ ra tên của tham số và kiểu dữ liệu của tham số. Các tham số được cung cấp cho hàm trong quá trình thực hiện của hàm được gọi là tham số thực. Kiểu dữ liệu của tham số thực cung cấp cho hàm trong chương trình phải giống kiểu dữ liệu của tham số hình thức tương ứng với tham số thực đó, nếu không sẽ có báo lỗi biên dịch. Một hàm có thể có một, nhiều hoặc không có tham số nào cả. Nếu có nhiều tham số thì chúng phải được phân cách với nhau bằng dấu phẩy. Lưu ý là nếu hàm không có tham số nào cả thì vẫn phải có cặp dấu ngoặc đơn sau tên hàm, ví dụ main(). Lệnh return Trong chương trình, một hàm được thực hiện khi ta gặp lời gọi hàm của hàm đó trong chương trình. Một lời gọi hàm là tên hàm theo sau bởi các tham số thực trong chương trình. Sau khi hàm thực hiện xong, nó sẽ trở về chương trình đã gọi nó. Có 2 cách để từ hàm trở về chương trình đã gọi hàm: - Sau khi thực hiện tất cả các câu lệnh có trong thân hàm. - Khi gặp lệnh return. Cú pháp chung của lệnh return là returnbiểu_thức; Trang 60
  61. Khi gặp lệnh này, chương trình sẽ tính toán giá trị của biểu_thức, lấy kết quả tính toán được làm giá trị trả về cho lời gọi hàm rồi kết thúc việc thực hiện hàm, trở về chương trình đã gọi nó. Trong lệnh return cũng có thể không có phần biểu_thức, khi đó ta sẽ kết thúc thực hiện hàm mà không trả về giá trị nào cả. Ví dụ và phân tích. #include #include int max(int x, int y, int z) { int max; max = x>y?x:y; max = max>z?max:z; return max; } void main() { int a,b,c; clrscr(); printf("\n Nhap gia tri cho 3 so nguyen a, b, c: "); scanf("%d %d %d",&a,&b,&c); printf("\n Gia tri cac so vua nhap: "); printf(" a = %-5d b = %-5d c = %-5d"); printf("\n Gia tri lon nhat trong 3 so la %d",max(a,b,c)); getch(); } 4.2.2. Sử dụng hàm Một hàm sau khi khai báo thì có thể sử dụng. Để sử dụng một hàm (hay còn nói là gọi hàm) ta sử dụng cú pháp sau: ([danh sách các tham số]) Ví dụ: chương trình dưới đây sẽ khai báo và định nghĩa một hàm có tên là Uscln với 2 tham số đều có kiểu unsigned int. Hàm Uscln tìm ước số chung lớn nhất của 2 tham số này theo thuật toán Euclid và trả về ước số chung tìm được. Sau đó ta sẽ gọi hàm Uscln trong hàm main để tìm ước số chung lớn nhất của 2 số nguyên được nhập từ bàn phím. #include #include unsigned int Uscln(unsigned int a, unsigned int b) { unsigned int u; if (a<b) { Trang 61
  62. u = a; a = b; b = u; } do { u = a%b; a = b; b = u; }while (u!=0); return a; } int main() { unsigned int a, b; do { printf("\n Nhap vao 2 so nguyen duong a va b "); printf("\n a = "); scanf("%d",&a); printf("\n b = "); scanf("%d",&b); if(a*b == 0) { printf("\n Khong hop le"); continue; } printf("\n Uoc chung lon nhat cua %d va %d la: %d", a, b, Uscln(a, b)); }while ((a != 0)||(b != 0)); printf("\n An phim bat ki de ket thuc chuong trinh "); getch(); return 0; } Kết quả khi thực hiện: Nhap vao 2 so nguyen duong a va b a = 6 b = 9 Uoc chung lon nhat cua 6 va 9 la: 3 Nhap vao 2 so nguyen duong a va b a = 15 b = 26 Uoc chung lon nhat cua 15 va 26 la: 1 Nhap vao 2 so nguyen duong a va b a = 3 Trang 62
  63. b = 0 Khong hop le Nhap vao 2 so nguyen duong a va b a = 0 b = 0 Khong hop le An phim bat ki de ket thuc chuong trinh Lưu ý: - Nếu có nhiều tham số trong danh sách tham số thì các tham số được phân cách với nhau bằng dấu phẩy - Cho dù hàm có một, nhiều hay không có tham số thì vẫn luôn luôn cần cặp dấu ngoặc đơn đứng sau tên hàm 4.2.3. Quy tắc hoạt động của hàm Trong chương trình, khi gặp một lời gọi hàm thì chuyển thi hành đến hàm được gọi. Quá trình diễn ra như sau: - Nếu hàm có tham số, trước tiên các tham số sẽ được gán giá trị thực tương ứng - Chương chình sẽ thực hiện tiếp các câu lệnh trong thân hàm bắt đầu từ lệnh đầu tiên đến câu lệnh cuối cùng - Khi gặp lệnh return hoặc dấu } cuối cùng trong thân hàm, chuwogn trình sẽ thoát khỏi hàm để trở về chương trình gọi nó và thực hiện tiếp tục những câu lệnh của chương trình này. Ví dụ: 4.2.4. Tính tổng thể và cục bộ của biến Phạm vi của các biến Một biến sau khi khai báo thì có thể được sử dụng trong chương trình. Tuy nhiên tùy vào vị trí khai báo biến mà phạm vi sử dụng các biến sẽ khác nhau. Nguyên tắc sử dụng biến là biến khai báo trong phạm vi nào thì được sử dụng trong phạm vi đó. Một biến có thể được khai báo trong chương trình chính hoặc trong các chương trình con hoặc thậm chí trong một lệnh khối. Nếu biến được khai báo trong một lệnh khối thì nó chỉ có thể được gọi trong lệnh khối đó thôi, không thể gọi từ bên ngoài lệnh khối được. Một biến được khai báo trong một chương trình con chỉ có thể được sử Trang 63
  64. dụng trong phạm vi chương trình con đó. Một biến được khai báo trong chương trình chính thì có thể được sử dụng trong toàn bộ chương trình, trong tất cả các chương trình con cũng như trong các lệnh khối của chương trình. Lưu ý Một số ngôn ngữ lập trình như Pascal cho phép khai báo một chương trình con nằm trong một chương trình con khác, nhưng ngôn ngữ C không cho phép khai báo một chương trình con nằm trong một chương trình con khác. Bên trong một lệnh khối thì có thể có chứa lệnh khối khác. Khi đó biến được khai báo ở lệnh khối bên ngoài có thể được sử dụng ở lệnh khối bên trong. Việc trùng tên của các biến: Trong cùng một phạm vi ta không được phép khai báo 2 biến có cùng tên nhưng ta có thể khai báo 2 biến trùng tên thuộc 2 phạm vi khác nhau. Nếu có 2 biến trùng tên khai báo ở 2 phạm vi khác nhau thì xảy ra 2 trường hợp: o Hai phạm vi này tách rời nhau: khi đó các biến sẽ có tác dụng ở phạm vi riêng của nó, không ảnh hưởng đến nhau. o Phạm vi này nằm trong phạm vi kia: khi đó nếu chương trình đang ở phạm vi ngoài (tức là đang thực hiện câu lệnh nằm ở phạm vi ngoài) thì biến khai báo ở phạm vi ngoài có tác dụng, còn nếu chương trình đang ở phạm vi trong (đang thực hiện câu lệnh nằm ở phạm vi trong) thì biến khai báo ở phạm vi trong sẽ có tác dụng và nó che lấp biến trùng tên ở bên ngoài. Ví dụ: #include void main() { { int a = 1; printf(“\n a = %d”,a); { int a = 2; printf(“\n a = %d”,a); } printf(“\n a = %d”,a); } { int a = 3; printf(“\n a = %d”,a); } } Kết quả thực hiện chương trình a = 1 a = 2 a = 1 Trang 64
  65. a = 3 Phân loại biến Theo phạm vi sử dụng, biến chia làm 2 loại: biến cục bộ (biến địa phương – local variable) và biến toàn cục (global variable). Biến địa phương Là các biến được khai báo trong lệnh khối hoặc trong thân chương trình con. Việc khai báo các biến cục bộ phải được đặt trước phần câu lệnh trong lệnh khối hoặc trong chương trình con. Biến toàn cục Các biến toàn cục là biến được thấy bởi toàn bộ chương trình, và có thể được sử dụng bởi một mã lệnh bất kỳ. Chúng được khai báo bên ngoài các hàm của chương trình và lưu giá trị của chúng trong suốt sự thực thi của chương trình. Các biến này có thể được khai báo bên ngoài main() hoặc khai báo bất kỳ nơi đâu trước lần sử dụng đầu tiên. Tuy nhiên, tốt nhất để khai báo các biến toàn cục là tại đầu chương trình, nghĩa là trước hàm main(). int ctr; /* ctr is global */ void blk1(void); void blk2(void); void main(void) { ctr = 10; blk1 (); . . } void blk1(void) { int rtc; if (ctr > 8) { rtc = rtc + 1; blk2(); } } void blk2(void) { int ctr; ctr = 0; } Trong đoạn mã lệnh trên, ctr là một biến toàn cục và được khai báo bên ngoài hàm main() và blk1(), nó có thể được tham chiếu đến trong các hàm. Biến ctr trong Trang 65
  66. blk2(), là một biến cục bộ và không có liên quan với biến toàn cục ctr. Nếu một biến toàn cục và cục bộ có cùng tên, tất cả các tham chiếu đến tên đó bên trong khối chứa định nghĩa biến cục bộ sẽ được kết hợp với biến cục bộ mà không phải là biến toàn cục. Các biến toàn cục được lưu trữ trong các vùng cố định của bộ nhớ. Các biến toàn cục hữu dụng khi nhiều hàm trong chương trình sử dụng cùng dữ liệu. Tuy nhiên, nên tránh sử dụng biến toàn cục nếu không cần thiết, vì chúng giữ bộ nhớ trong suốt thời gian thực hiện chương trình. Vì vậy việc sử dụng một biến toàn cục ở nơi mà một biến cục bộ có khả năng đáp ứng cho hàm sử dụng là không hiệu quả. Ví dụ sau sẽ giúp làm rõ hơn điều này: void addgen(int i, int j) { return(i + j); } int i, j; void addspe(void) { return(i + j); } Cả hai hàm addgen() và addspe() đều trả về tổng của các biến i và j. Tuy nhiên, hàm addgen() được sử dụng để trả về tổng của hai số bất kỳ; trong khi hàm addspe() chỉ trả về tổng của các biến toàn cục i và j. Lưu ý: - Hàm main() cũng chỉ là một chương trình con, nhưng nó là chương trình con đặc biệt ở chỗ chương trình được bắt đầu thực hiện từ hàm main(). - Biến khai báo trong hàm main() không phải là biến toàn cục mà là biến cục bộ của hàm main(). Trang 66
  67. CHƯƠNG 5: DỮ LIỆU KIỂU MẢNG MỤC TIÊU CỦA BÀI Sau khi học xong bài này người học có khả năng Kiến thức: Trình bày được khái niệm về Mảng, cách khai báo và sử dụng mảng 1 chiều và mảng 2 chiều Kĩ năng - Phân biệt được mảng 1 chiều và mảng 2 chiều; - Lựa chọn loại khai báo mảng cho từng bài tập; - Khai báo, hiển thị mảng 1 chiều, 2 chiều. Thái độ: Vận dụng tích cực, linh hoạt các kiến thức đã học vào các bài học tiếp theo, áp dụng viết các chương trình cơ bản. 5.1. Khái niệm và khai báo mảng 5.1.1. Khái niệm về mảng Một biến (biến đơn) tại một thời điểm chỉ có thể biểu diễn được một giá trị. Vậy để có thể lưu trữ được một dãy các giá trị cùng kiểu chẳng hạn như các thành phần của vector trong không gian n chiều chúng ta cần n biến a1, a2, ,an. rất cồng kềnh và rất bất tiện nhất là khi n lớn và lại không phải là cố định. Các ngôn ngữ lập trình đưa ra một khái niệm mảng để giải quyết vấn đề này. Mảng là một tập hợp hữu hạn các phần tử có cùng kiểu dữ liệu được lưu trữ kế tiếp nhau trong bộ nhớ. Các phần tử trong mảng có cùng tên (và cũng là tên mảng) nhưng phân biệt với nhau ở chỉ số cho biết vị trí của chúng trong mảng. • Các thông tin về mảng: Với một mảng phải xác định các thông tin: tên mảng, kiểu các phần tử (kiểu mảng), số phần tử trong mảng (kích thước mảng). Ví dụ như chúng ta nói a là mảng có 20 phần tử, kiểu nguyên. Mảng cũng như các biến đơn khác trong ngôn ngữ C, trước khi sử dụng nó phải đảm bảo là nó đã được cấp phát trong bộ nhớ và đã sẵn sàng để sử dụng • Số chiều của mảng: trong ví dụ chúng ta nêu trên về vector, chúng ta có một dãy n các số, nếu như chúng ta dùng một mảng để lưu trữ các số đó thì chúng ta cần mảng có n phần tử và chỉ cần 1 chỉ số để xác định các phần tử - đây là mảng một chiều. Nếu như chúng ta cần một mảng để biểu diễn một bảng có n dòng, m cột, và để xác định một phần tử trong mảng chúng ta cần 2 chỉ số: chỉ số dòng và chỉ số cột, như vậy chúng ta có mảng 2 chiều. 5.1.2. Khai báo và sử dụng mảng Khai báo mảng Trong C để khai báo một mảng ta sử dụng cú pháp khai báo sau: kiểu_dữ_liệu tên_mảng [kích_thước_mảng]; Trong đó kiểu_dữ_liệu là kiểu dữ liệu của các phần tử trong mảng. tên_mảng là tên của mảng. kích_thứớc_mảng cho biết số phần tử trong mảng. Ví dụ: int mang_nguyen[10]; // khai báo mảng 10 phần tử có kiểu dữ liệu int float mang_thuc[4]; // khai báo mảng 4 phần tử có kiểu dữ liệu float Trang 67
  68. char mang_ki_tu[6]; // khai báo mảng 6 phần tử có kiểu dữ liệu char Trong ví dụ trên, mảng mang_nguyen được lưu trữ trên 20 ô nhớ (mỗi ô nhớ có kích thước 1 byte, 2 ô nhớ kích thước là 2 byte lưu trữ được một số nguyên kiểu int) liên tiếp nhau. Do C đánh số các phần tử của mảng bắt đầu từ 0 nên phần tử thứ i của mảng sẽ có chỉ số là i-1 và do vậy sẽ có tên là mang_nguyen[i-1]. Ví dụ: phần tử thứ nhất của mảng là mang_nguyen[0], phần tử thứ 2 là mang_nguyen[1], phần tử thứ 5 là mang_nguyen[4] mang_nguyen[0] mang_nguyen[1] mang_nguyen[9] Kích thước của mảng bằng kích thước một phần tử nhân với số phần tử. Sử dụng mảng Đểtruy nhập vào một phần tử của mảng thông qua tên của nó. Tên một phần tử của mảng được tạo thành từ tên mảng và theo sau là chỉ số của phần tử đó trong mảng được đặt trong cặp dấu ngoặc vuông tên_mảng[chỉ_số_của_phần_tử] Ví dụ với khai báo int mang_nguyen[3]; Thì mang_nguyen[0] sẽ là phần tử thứ nhất của mảng mang_nguyen[1] sẽ là phần tử thứ 2 của mảng mang_nguyen[2] sẽ là phần tử thứ 3 của mảng Với mảng nhiều chiều như int a[6][5]; thì a[0] là phần tử đầu tiên của một mảng, phần tử này bản thân nó lại là một mảng một chiều. Phần tử đầu tiên của mảng một chiều a[0] sẽ là a[0][0]. Phần tử tiếp theo của a[0] sẽ là a[0][1] Và dễ dàng tính được a[2][3] sẽ là phần tử thứ 4 của phần tử thứ 3 của a. Một cách tổng quát a[i][j] sẽ là phần tử thứ j+1 của a[i], mà phần tử a[i] lại là phần tử thứ i+1 của a. 5.1.2.1. Khai báo mảng 1 chiều Cú pháp Kiểu_mảng tên_mảng [ số_phần_tử]; Trong đó: - Kiểu_mảng: đây là kiểu của mảng, là tên một kiểu dữ liệu đã tồn tại, có thể là kiểu chuẩn hoặc kiểu dữ liệu do người lập trình định nghĩa . - tên_mảng : là tên của mảng, do người lập trình đặt, theo quy tắc về tên của C - số_phần_tử : là hằng (hoặc biểu thức hằng) nguyên, dương là số phần tử của mảng. Ví dụ: int vector [15]; // tên mảng: vector, có 15 phần tử, kiểu int float MT[10], D[20]; // có hai mảng kiểu float: MT có 10 phần tử, D có 20 phần tử char * s[30]; // s là mảng có 30 phần tử kiểu char * (mảng các con trỏ) Trang 68
  69. Khi gặp (dòng lệnh) định nghĩa một mảng, chương trình dịch sẽ cấp phát một vùng nhớ (lên tiếp) cho đủ các phần tử liên tiếp của mảng, ví dụ vector[15] sẽ được cấp phát một vùng nhớ có kích thước 15*sizeof(int) =30 byte 5.1.2.2. Khai báo mảng 2 chiều Mảng hai chiều có thể hiểu như bảng gồm các dòng các cột, các phần tử thuộc cùng một kiểu dữ liệu nào đó. Mảng hai chiều được định nghĩa như sau. Cú pháp Kiểu_mảng tên_mảng [sd][sc]; Trong đó: - Kiểu_mảng: đây là kiểu của mảng, là tên một kiểu dữ liệu đã tồn tại, có thể là kiểu chuẩn hoặc kiểu dữ liệu do người lập trình định nghĩa. - tên_mảng : là tên của mảng, do người lập trình đặt, theo quy tắc về tên của C. - sd, sc : là hằng (hoặc biểu thức hằng) nguyên, dương tương ứng là số dòng và số cột mảng, số phần tử của mảng sẽ là sd*sc. Ví dụ: int a[2][5]; // a là mảng số nguyên có 2 dòng, 5 cột (có 10 phần tử) float D[3][10]; // D là mảng số thực có 3 dòng, 10 cột (có 30 phần tử) char DS[5][30]; // DS là mảng kí tự có 5 dòng, 30 cột Khi gặp một định nghĩa mảng, chương trình dịch sẽ cấp phát một vùng nhớ liên tiếp có kích thước là sd*sc*sizeof (Kiểu_mảng) cho mảng. Có thể coi mảng 2 chiều n dòng, m cột là mảng 1 chiểu có n phần tử, mỗi phần tử lại là 1 mảng một chiều có m phần tử (mảng của mảng). Ví dụ với float D[3][10] có thể xem D là mảng có 3 phần tử D[0], D[1], D[2], mỗi phần tử này là mảng có 10 phần tử. 5.2. Một số bài toán với mảng 1 chiều 5.2.1. Nhập dữ liệu cho mảng Sau khi khai báo mảng ta phải nhập dữ liệu cho mảng. Nhập dữ liệu cho mảng là nhập dữ liệu cho từng phần tử của mảng. Mỗi một phần tử của mảng thực chất là một biến có kiểu dữ liệu là kiểu dữ liệu chung của mảng. Để nhập dữ liệu cho các phần tử của mảng ta có thể dùng hàm scanf() hoặc lệnh gán tương tự như biến thông thường. Ví dụ float a[10]; // khai bao mot mang so thuc co 10 phan tu int i; // Nhap tu ban phim mot so thuc va gan gia tri so thuc do // cho phan tu thu 2 cua mang, tuc la a[1] scanf(“%f”,&a[1]); // Gán giá trị cho phần tử a[2] a[2] = a[1] + 5; Nếu ta muốn gán giá trị cho các phần tử của mảng một cách hàng loạt, ta có thể dùng lệnh for. Ví dụ int b[10]; int i; Trang 69
  70. // Nhap gia tri tu ban phim cho tat ca cac phan tu cua mang b for(i = 0; i #include void main() { int a[5]; int i, k; // Nhap gia tri cho cac phan tu cua mang a tu ban phim for(i = 0; i < 5; i++) { printf(“\n a[%d] = “, i); scanf(“%d”, &a[i]); } Trang 70