Tóm tắt nội dung môn học C là một ngôn ngữ lập trình cấu trúc bậc cao được các nhà lập trình chuyên nghiệp sử dụng phổ biến để phát triển các phần mềm hệ thống hệ điều hành, chương trình
Trang 1TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
-o0o -
Tạ Tuấn Anh
Bài giảng điện tử môn học NGÔN NGỮ LẬP TRÌNH C
Trang 2Tóm tắt nội dung môn học
C là một ngôn ngữ lập trình cấu trúc bậc cao được các nhà lập trình chuyên nghiệp sử dụng phổ biến để phát triển các phần mềm hệ thống (hệ điều hành, chương trình dịch, cơ sở dữ liệu, ) Lý do ngôn ngữ C đươc ưu chuộng chính là tính mềm dẻo và ngắn gọn của nọ Một chương trình được viết ở ngôn ngữ C có tính khả chuyển cao Nó có thể được dịch và chạy trong nhiều loại máy tính (PC, Sun, Mainframe, ) cũng như trên nhiều nền hệ điều hành (DOS, UNIX, ) Ngoài ra C cho phép viết chương trình bám sát cách tổ chức bộ nhớ chương trình khi chạy Do vậy một chương trình được dịch từ C luôn có kích thước nhỏ gọn hơn một chương trình cùng loại được dịch từ các ngôn ngữ bậc cao khác như PASCAL Nhưng cũng chính vì lí do này mà việc nắm bắt và thành thạo ngôn ngữ C sẽ khó khăn hơn nhiều so với ngôn ngữ khác Môn học này giới thiệu cho các học viên các kiến thức căn bản cũng như nâng cao về ngôn ngữ lập trình C Bên cạnh các kiến thức về cú pháp cũng như kĩ năng viết chương trình C, học viên còn nắm bắt được các vấn đề liên quan đến tổ chức bộ nhớ của một chương trình
Kiến thức yêu cầu
Để tiếp thu tốt kiến thức môn học này, yêu cầu học viên trước khi học đã tìm hiểu các khái niệm cơ bản trong Tin học, có kĩ năng căn bản viết một chương trình có cấu trúc bằng một ngôn ngữ bậc cao như PASCAL Ngoài ra một số kiến thức về cấu trúc dữ liệu và giải thuật (danh sách móc nối, cây tìm kiếm, ) có thể giúp học viên sử dụng C để viết các chương trình ứng dụng
Tổng thời lượng: 45 tiết
MỤC LỤC
TÀI LIỆU THAM KHẢO
Nhập môn Lập trình Ngôn ngữ C
Trần Việt Linh, Lê Đăng Hưng, Lê Đức Trung, Nguyễn Thanh Thuỷ
Nhà Xuất bản Khoa học Kỹ thuật, 2000
Trang 3CHƯƠNG 1 - NHẬP MÔN LẬP TRÌNH C
Mục đích của chương này là giới thiệu tổng quan về ngôn ngữ C bao gồm các kiến thức về lịch
sử, đặc điểm và vai trò của nó Học viên được làm quen với các chương trình viết bằng C cũng như cách dịch chúng để chạy
Yêu cầu: Có một phiên bản cài đặt của trình biên dịch Turbo C hay một trình biên dịch khác để
chạy thử chương trình
Thời lượng: 5 tiết
Mục 1.1 - Tổng quan về ngôn ngữ C
Mục này cho phép học viên làm quen với một chương trình viết dưới ngôn ngữ C và tìm hiểu lịch
sử của nó Các thành phần cơ bản của một chương trình C được giới thiệu để học viên có một cái nhìn tổng quan về ngôn ngữ lập trình này
Yêu cầu: Đã có khái niệm về lập trình và ngôn ngữ lập trình
Thời lượng: 3 tiết
Bài 1 - Lịch sử hình thành và phát triển
Tóm tắt nội dung:
Ngôn ngữ lập trình C ra đời vào đầu thập kỉ 70 với mục đích dùng để viết hệ điều hành UNIX C được phát triển rất mạnh sau đó và được chuẩn hoá với tên gọi ANSI C Ngôn ngữ này được các nhà lập trình chuyên nghiệp rất ưa chuộng để phát triển các phần mềm hệ thống Một mở rộng của C là C++ ra đời vào đầu thập kỉ 80 Nó là một ngôn ngữ lập trình hướng đối tượng được phát triển trên nền của C
Thời lượng: 1 tiết
Ngôn ngữ C do Brian W.Kernighan và Denis M Ritchie phát triển vào đầu những năm 70 tại phòng thí nghiệm BELL (Hoa Kỳ) với mục đích ban đầu để phát triển hệ điều hành UNIX Bối cảnh ra đời xuất phát từ nhu cầu cần phải có một ngôn ngữ lập trình hệ thống thay thế cho hợp ngữ (ASSEMBLY) rất nặng nề trong lập trình Hơn nữa một chương trình viết bằng hợp ngữ không có tính khả chuyển vì chúng gắn chặt với bộ lệnh của vi xử lí
Tiền thân của C phải kể đến các ngôn ngữ BCPL do Martin Richard nghiên cứu Tiếp đến là ngôn ngữ B do Ken Thompson xây dựng năm 1970 dùng để viết hệ điều hành UNIX cho dòng máy tính PDP-7 C là ngôn ngữ được kế thừa từ B và hoàn thiện để có được các tính năng mạnh của một ngôn ngữ lập trình hệ thống có khả năng ứng dụng rộng rãi như ngày nay Đó là các tính năng:
Trang 4- Lập trình bậc cao: Giống như PASCAL, chương trình C sử dụng tập các câu lệnh điều
khiển như rẽ nhánh, lặp ở mức độ trừu tượng của lưu đồ giải thuật Điều này cho phép viết các giải thuật bằng ngôn ngữ C khá dễ dàng
- Lập trình cấu trúc: Một chương trình C có thể được phân chia, cấu trúc thành các modul
nhỏ Điều này giúp phát triển chương trình một cách hệ thống hơn và dễ bảo trì
- Lập trình hệ thống: Không giống như PASCAL, ngôn ngữ C không dùng nhiều kiểu dữ
liệu trừu tượng C cho phép các thao tác với bộ nhớ chương trình rất uyển chuyển Một người lập trình trên ngôn ngữ C có thể tự do tổ chức và lưu trữ dữ liệu trên bộ nhớ theo ý mình Tính năng này là vô cùng quan trọng khi cần phát triển các chương trình hệ thống liên quan nhiều đến bộ nhớ máy tính Ngoài ra ngôn ngữ C hỗ trợ phần lớn các phép xử lí
mà một hợp ngữ có thể làm
- Tính khả chuyển: Một chương trình viết trên ngôn ngữ C có thể được dịch ra mã chương
trình trên nhiều dòng máy và hệ điều hành khác nhau bởi khả năng tương thích của các câu lệnh trong chương trình Ngoài ra C còn có bộ tiền xử lí tạo ra khả năng biên dịch theo điều kiện để việc dịch chương trình thích ứng cho từng hệ thống khác nhau
- Tính nhỏ gọn: Một chương trình viết trên C sau khi dịch có độ tối ưu về mã lệnh hơn bất
cứ một ngôn ngữ bậc cao nào khác Chính vì vậy các chương trình được dịch từ ngôn ngữ
C thường có kích thước nhỏ gọn
Với tất cả các tính năng trên, ngôn ngữ C là một ngôn ngữ cực kì hiệu quả và có sức diễn cảm trong lập trình Nó đã trở thành ngôn ngữ lập trình mà các nhà lập trình chuyên nghiệp ưa chuộng trong nhiều lĩnh vực Trong lĩnh vực lập trình hệ thống, có tới 90% chương trình được viết bằng ngôn ngữ C Ngoài ra nó còn được dùng để viết chương trình trong các lĩnh vực hiện đại khác của Tin học về xử lí tín hiệu, số liệu, văn bản,
Ngôn ngữ C đã được viện tiêu chuẩn quốc gia Mỹ (ANSI) chuẩn hoá và công bố vào năm
1988 với tên gọi là ANSI C Bên cạnh ngôn ngữ C người lập trình còn biết đến một ngôn ngữ lập trình có tên tương tự là C++ Đây là một ngôn ngữ lập trình được mở rộng từ C để thêm khả năng lập trình hướng đối tượng Vì C++ là ngôn ngữ bao trùm lên C nên để học tốt C++ yêu cầu người lập trình trước hêt phải nắm vững C
#include <stdio.h>
void main()
Trang 52 Chương trình thứ hai
Để có thể thấy rõ hơn cấu trúc của một chương trình trong C, chúng ta tiếp tuc tìm hiểu ngôn ngữ thông qua một ví dụ thứ hai Ở ví dụ này chúng ta sẽ tạo một chương trình cho phép in diện tích của một hình tròn tương ứng với một bán kính được người sử dụng nhập vào
- Hàm: Một chương trình C có thể được cấu trúc bằng nhiều hàm Trong chương trình trên,
chúng ta đã khai báo một hàm để tính diện tích của một hình tròn với bán kính truyền vào như là một tham số thực (float) Kết quả của rõ ràng phải là một số thực Hàm này được gọi trong hàm chính của chương trình để in giá trị diện tích hình tròn ra ngoài màn hình
- Hàm chính: Một chương trình hoạt động thế nào được thể hiện bởi các câu lệnh trong hàm
chính Trong hàm chính của chương trình trên chúng ta đã khai báo một biến thực để chứa giá trị của bán kính hình tròn do người sử dụng nhập vào từ bàn phím Lệnh gọi hàm scanf() cho phép chương trình lấy dữ liệu bán kính do người sử dụng nhập vào Dòng lệnh
Trang 6cuối cùng của hàm chính dùng để in giá trị diện tích của hình tròn có bán kính tương ứng
ra màn hình Giá trị diện tích được tính thông qua hàm dientich() đã được khai báo
Bài 3 - Các thành phần của chương trình C
Tóm tắt nội dung:
Cũng như các ngôn ngữ lập trình khác, một chương trình C được viết từ các từ khoá, biến, câu lệnh, hàm, Trong bài này chúng ta xem chi tiết các thành phần có trong một chương trình C để biết được ý nghĩa và vai trò của chúng
Thời lượng: 1 tiết
1 Từ vựng
Một chương trình C được xây dựng trên một bộ từ vựng bao gồm tập kí tự có phân biệt chữ hoa và thường Chính vì vậy khi viết chương trình C chúng ta không được phép sử dụng tuỳ tiện chữ hoa hay chữ thường Ví dụ hàm chính của chương trình bắt buộc phải viết là main mà không được viết là MAIN hay Main Trong một chương trình C chúng ta gặp hai loại bộ từ vựng quan trọng là từ khoá và tên của người sử dụng
Từ khoá: Từ khoá là một bộ từ vựng được định nghĩa từ trước đối với một ngôn ngữ và chỉ để sử
dụng vào các mục đích đã được xác định trong chương trình Một số từ khoá hay dùng là các từ khoá kiểu dữ liệu (char, int, long, float, double, ), các lệnh điều khiển (if, switch, for, do, while, ), v.v
Bảng các từ khoá trong ngôn ngữ C
extern far float for
register return short signed sizeof static struct switch
volatile while
Tên: Trong chương trình người sử dụng cần tên để đặt cho biến, hàm, kiểu dữ liệu mới Tên của
người sử dụng đòi hỏi phải là một chuỗi kí tự là các chữ cái, chữ số và gạch nối ‘_’ Tên phải bắt đầu bằng một chữ cái hoặc gạch nối
2 Cấu trúc cơ bản của chương trình
Trong bài 2 chúng ta đã thấy được cấu trúc cơ bản của chương trình C Phần này sẽ trình bày khái quát về các thành phần trong cấu trúc của chương trình
Trang 7a Khai báo tiêu đề
Một tệp tiêu đề trong chương trình C chứa mô tả các hàm có thể được gọi trong chương trình (xem mục 6.2 - Tệp tiêu đề) Khi cần gọi một hàm nào trong chương trình ta phải khai báo tệp tiêu đề có mô tả tương ứng cho hàm Chính vì vậy các hàm thư viện luôn được chỉ ra cùng với các tệp tiêu đề tương ứng khi được trình bày
b Khai báo hằng, cấu trúc dữ liệu
Các hằng số trong chương trình C thường được định nghĩa bằng chỉ thị #define (xem bài 35
- Một số chỉ thị tiền xử lí) Ngoài các kiểu dữ liệu cơ bản, một chương trình C có thể có các cấu trúc dữ liệu phức do người sử dụng định nghĩa Các cấu trúc này thường được khai báo ở phần đầu chương trình (xem mục 3.4 - Cấu trúc)
c Khai báo hàm và/hoặc nguyên mẫu hàm
Chương trình C được cấu trúc bởi các hàm (xem mục 2.3 - Hàm) Một hàm thể hiện một modul con trong một chương trình Nó có thể nhận tham số thực hiện và trả về kết quả cho nơi gọi hàm Thân của một hàm được chia làm hai phần: khai báo biến (xem mục 2.1 - Biến, hằng số
và biểu thức) và lệnh thực hiện (xem mục 2.2 - Các cấu trúc lệnh điều khiển) Các biến luôn được khai báo ở phần đầu thân hàm sau đó mới đến các câu lệnh Mỗi câu lệnh trong chương trình C phải được kết thúc bằng một dấu chấm phẩy ‘;’ Chúng ta có thể tạo một khối lệnh bằng cách đặt chúng trong cặp dấu {} Thân hàm cũng phải được đặt trong cặp dấu này
d Khai báo biến
Trong một chương trình C có thể khai báo biến dạng tổng thể hay cục bộ (biến của một hàm) Một biến tổng thể được khai báo bên ngoài hàm và nó có thể sử dụng trong tất cả các hàm của chương trình Ngược lại biến cục bộ chỉ có thể sử dụng trong hàm nơi nó được khai báo
Mục 1.2 - Biên dich chương trình
Mục này đưa ra cho người sử dụng một kiến thức chuyên sâu về vấn đề biên dịch một chương trình Các trình IDE (Integrated Development Environment) được biết đến như là một môi trường tích hợp trợ giúp việc phát triển chương trình bao gồm các công việc soạn thảo, biên dịch và gỡ rối Học viên sẽ được tìm hiểu một trình IDE được dùng phổ biến trong môi trường DOS là Turbo C
Yêu cầu: Có trình cài đặt Turbo C hoặc Borland C++
Thời lượng: 2 tiết
Trang 8Bài 4 - Quá trình biên dịch
Tóm tắt nội dung:
Biên dịch một chương trình là quá trình dịch một chương trình viết dưới dạng văn bản như C sang chương trình mã máy như tệp exe trong DOS Quá trình này có thể phải qua nhiều pha khác nhau và có thể xảy ra lỗi tại mỗi pha
Thời lượng: 1 tiết
Ngôn ngữ lập trình C là một ngôn ngữ dạng biên dịch Chương trình được viết bằng C muốn chạy được trên máy tính phải trải qua một quá trình biên dịch để chuyển đổi từ dạng mã nguồn sang chương trình dạng mã thực hiện Toàn bộ quá trình biên dịch ở trong ngôn ngữ được minh hoạ trong hình 1 Quá trình này được chia làm hai giai đoạn chính: giai đoạn dịch và giai đoạn liên kết
Mã ngu?n
Chuong trìnhHình 1: Quá trình biên dich một chương trình C
1 Giai đoạn dịch (compiling)
Mục đích của giai đoạn này là chuyển đổi tất cả mã chương trình được viết dưới ngôn ngữ
C sang dạng mã máy Ba công đoạn được thực hiện lần lượt là: tiền xử lí mã nguồn, dịch C sang Assembly và dịch Assembly sang mã máy
- Công đoạn tiền xử lí sẽ nhận mã nguồn của chương trình và thực hiện xoá bỏ tất cả chú
thích của chương trình Ngoài ra tất cả các chỉ thị tiền xử lí (bắt đầu bằng #) cũng được xử
lí ngay trong công đoạn này Ví dụ chỉ thị #include cho phép ghép thêm mã chương trình của một tệp tiêu đề vào mã nguồn cần dịch Các hằng số được định nghĩa bằng #define sẽ được thay thế bằng giá trị cụ thể tại mỗi nơi sử dụng trong chương trình
Trang 9- Công đoạn dịch C cho phép phân tích cú pháp của mã nguồn C và sau đó chuyển chúng
sang dạng mã Assemly là môt ngôn ngữ bậc thấp gần với tập lệnh của bộ vi xử lí
- Công đoạn dịch Assembly cho phép dịch chương trình sang mã máy Sau công đoạn này
một tệp mã máy (.o) thường được sinh ra trong hệ thống
Như vậy sau giai đoạn dịch các lỗi chương trình có thể được phát hiện và thông báo cho người sử là các lỗi về cú pháp chương trình Nó cũng có thể phát hiện lỗi không tồn tại (hoặc có
mà đặt đường dẫn tìm kiếm sai để không tìm thấy) tệp tiêu đề trong công đoạn tiền xử lí
2 Giai đoạn liên kết (linking)
Trong giai đoạn này mã máy của một chương trình dịch từ nhiều nguồn khác nhau được liên kết lại với nhau để tạo thành chương trình đích duy nhất Mã máy của các hàm thư viện gọi trong chương trình cũng được đưa vào chương trình cuối trong giai đoạn này Chính vì vậy mà các lỗi liên quan đến việc gọi hàm hay sử dụng biến tổng thể mà không tồn tại sẽ bị phát hiện Kể
cả lỗi viết chương trình chính không có hàm main() cũng được phát hiện trong khi liên kết Để liên kết với các hàm thư viện cần phải đặt đúng đường dẫn tìm kiếm thư viện đến các tệp chứa
mã máy thư viện (.obj, lib, )
Bài 5 - Turbo C
Tóm tắt nội dung:
Turbo C là một trình IDE cho ngôn ngữ C chạy trên nền DOS Một số phiên bản hay dùng bao gồm Turbo C 1.0, Turbo C++ 3.0 Ngoài ra ta có thể dùng các phiên bản chạy trên nên hệ điều hành Windows có tên là Borland C++
Thời lượng: 1 tiết
1 Môi trường trợ giúp phát triển (IDE)
Để trợ giúp cho việc phát triển ứng dụng trên một ngôn ngữ một cách thuận tiện, các nhà sản xuất cung cấp các tiện ích cho phép người sử dụng thao tác biên soạn chương trình, dịch hay gỡ rối bằng các thao tác đơn giản qua phím nóng Như vậy nhờ có IDE (Intergrated Development
Environment) mà lập trình viên không phải thực hiện các pha biên dịch bằng các câu lệnh phức tạp mà chỉ cần đơn giản là nhấn một phím nóng Quá trình sửa lỗi cũng rất thuận tiện do IDE định vị giúp người lập trình vị trí lỗi của chương trình ngay trên màn hình soạn thảo Một IDE thường có ba thành phần cơ bản là:
- Công cụ soạn thảo giúp lập trình viên soạn thảo chương trình trên ngôn ngữ được hỗ trợ
Trình soạn thảo này có thể thực hiện đổi màu các từ khoá trong chương trình để giúp người lập trình quan sát chương trình một cách trực quan hơn
- Công cụ biên dịch và chạy chương trình Bằng một thao tác đơn giản lập trình viên có thể
yêu cầu biên dịch toàn bộ chương trình xong rồi chạy Nếu chương trình có lỗi thì công cụ này sẽ thông báo loại lỗi cùng với vị trí của lỗi trong chương trình đến người sử dụng Chính vì vậy việc tiến hành sửa lỗi chương trình trong IDE là rất đơn giản
Trang 10- Công cụ gỡ rối giúp lập trình viên có thể chạy lần bước một chương trình theo từng dòng
lệnh Trong quá trình lần bước lập trình viên có thể quan sát sự thay đổi giá trị các biến trong chương trình qua đó mà phát hiện ra lỗi
2 Turbo C
Có rất nhiều trình IDE khác nhau cho ngôn ngữ C nhưng được phổ dụng nhất trong môi trường DOS hoặc Windows là các phiên bản của Turbo C Chúng ta có thể kể ra một số phiên bản hay sử dụng là Turbo C chỉ hỗ trợ ngôn ngữ C và chạy trên nền DOS, Turbo C++ 3.0 hỗ trợ
C và C++ chạy trên DOS, các phiên bản từ 3.1 trở lên được đổi tên là Borland C++ và chạy trên nền Windows
Khi dịch một chương trình trên Turbo C cần chú ý thiết lập đúng đường dẫn tìm kiếm tệp tiêu đề và thư viện Ví dụ với phiên bản Turbo C++ để xác lập các đường dẫn thư mục này ta cần dùng menu và vào lựa chọn Options|Directories Khi đó một hộp hội thoại sẽ xuất hiện để cho chúng ta đặt đường dẫn thư mục tìm kiếm tệp tiêu đề (Include) và thư mục tìm kiếm thư viện (Library) Thường thì các tệp tiêu đề được lưu trong thư mục con INCLUDE của thư mục cài đặt Turbo Còn các tệp thư viện được lưu trong thư mục con LIB
Hình 2 Màn hình IDE của Turbo C++ 3.0 Chúng ta thường dùng phím nóng của IDE để thực hiện nhanh một số thao tác Sau đây là một số phím nóng thông dụng:
Phím nóng Ý nghĩa F3 Mở tệp nguồn
F9 Biên dịch chương trình và tạo tập tin EXE Ctrl+F9 Biên dịch và chạy chương trình
F4, F7, F8 Chạy lần vết, gỡ rối
Trang 11Alt+F3 Đóng một cửa sổ F5, F6 Chuyển cửa sổ
Trang 12CHƯƠNG 2 - LẬP TRÌNH C CƠ BẢN
Mục đích của chương này là giới thiệu tới học viên các kiến thức căn bản để viết một chương trình C Đó là các kiểu dữ liệu, biểu thức, hàm xuất nhập dữ liệu, các cấu trúc lệnh điều khiển trong chương trình Một chương trình C được cấu trúc với các hàm Học viên sẽ được tìm hiểu cách khai báo và sử dụng hàm cũng như cách truyền tham số cho nó
Yêu cầu: Đã có kiến thức tổng quan về ngôn ngữ C được giới thiệu trong chương 1
Thời lượng: 12 tiết
Mục 2 1 - Biến, hằng số và biểu thức
Mục này giới thiệu cách khai báo biến trong chương trình với các kiểu dữ liệu Người sử dụng có thể tạo một biểu thức tính toán trên cơ sở các biến và hằng số của kiểu dữ liệu cơ bản Để xuất và nhập dữ liệu ta có thể sử dụng các hàm thư viện printf() và scanf() tương ứng
Yêu cầu: Có khái niệm về biểu diễn dữ liệu trong máy tính
Thời lượng: 6 tiết
Bài 6 - Các kiểu dữ liệu cơ bản
Tóm tắt nội dung:
Các kiểu dữ liệu cơ bản trong C được chia làm loại Loại số nguyên bao gồm các kiểu char, int và long Loại số thực có hai kiểu float và double Tất cả các loại dữ liệu khác đều được biểu diễn và
sử dụng trên hai loại dữ liệu cơ bản này
Thời lượng: 1 tiết
1 Biến
Biến là một đơn vị bộ nhớ chứa dữ liệu của chương trình Dữ liệu của biến có thể thay đổi trong quá trình chương trình chạy Mỗi biến chỉ có thể chứa một kiểu loại dữ liệu nhất định Cách khai báo biến trong chương trình C như sau:
<kiểu dữ liệu> <danh sách tên biến>;
Trang 132 Các kiểu dữ liệu cơ bản
Bảng các kiểu dữ liệu cơ bản trong C
Kiểu dữ liệu Số byte Phạm vi có dấu Phạm vi không dấu
Ví dụ:
unsigned int x; /* bi ến nguyên không dấu */
signed int y; /* bi ến nguyên có dấu */
int z; /* bi ến nguyên có dấu */
char c; /* bi ến nguyên 1 byte không dấu */
Chú ý trong ngôn ngữ C không tồn tại kiểu dữ liệu cơ bản cho logic Logic đúng sai ở trong chương trình C được biểu diễn thông qua một số nguyên với giá trị 0 thể hiện sai (FALSE) và khác 0 (hay dùng giá trị 1) thể hiện đúng (TRUE) Do vậy khi muốn tạo biến logic ta thường dùng một biến nguyên int để thay thế
Ví dụ:
int flag; /* t ạo biến logic bằng int */
flag = TRUE; /* flag = 1 */
Cũng như dữ liệu kiểu logic, ngôn ngữ C cũng không tạo một kiểu dữ liệu đặc thù cho các
kí tự Thực tế một kí tự được biểu diễn trong bộ nhớ máy tính là một số nguyên 1 byte Việc ánh
xạ kí tự nào tương ứng với con số nào được qui ước trong bảng mã ASCII Chính vì chỉ có một byte bộ nhớ cho biểu diễn kí tự nên bảng mã ASCII chỉ có 256 kí tự mà thôi Do vậy để có một biến kí tự trong ngôn ngữ C ta dùng kiểu dữ liệu char
Ví dụ:
char c;
c = ‘A’; /* th ực chất c = 65 do ‘A’ có mã ASCII là 65 */
Như vậy chúng ta có thể thấy kiểu dữ liệu cơ bản của C chỉ bao gồm hai loại số nguyên và
số thực Tất các các loại dữ liệu khác đều được quy về cách biểu diễn số
BÀI TẬP
Câu 1: Viết khai báo biến cho các loại dữ liệu sau:
Trang 14a) Hệ số a, b, c của một phương trình bậc 2 bất kì
b) Điểm kiểm tra của một môn học
c) Số dân của một đất nước
d) Số nhà của một phố
e) Chữ cái đầu tiên của một tên người
f) Tổng số vụ tai nạn giao thông tăng/giảm so với năm trước
g) Giới tính của một người
Câu 2: Chỉ ra các khai báo biến sai trong những khai báo sau đây:
Trong một chương trình để gán giá trị cho một biến ta phải dùng các hằng số Với mỗi loại
dữ liệu ta có cách viết hằng số khác nhau Sau đây là cách biểu diễn hằng số trong ngôn ngữ C
Trang 15Ngoài ra một số kí tự đặc biệt khác được viết theo quy ước:
2 Khai báo biến có khởi tạo giá trị
<kiểu dữ liệu> <tên biến> = <hằng số>;
BÀI TẬP
Câu 1: Chỉ ra các khai báo biến hằng số sai cho những câu sau đây:
Trang 16Để in dữ liệu chúng ta dùng hàm printf(), còn để nhập dữ liệu thì dùng hàm scanf() Hai hàm này
sử dụng các định dạng để chỉ ra loại dữ liệu dùng trong việc xuất và nhập
Thời lượng: 1 tiết
Các hàm vào ra chuẩn của C được khai báo nguyên mẫu trong tệp tiêu đề <stdio.h> có hai hàm cơ bản là printf() và scanf()
1 Xuất dữ liệu bằng printf()
Trang 17Trong định dạng in dữ liệu chúng ta có thể thêm vào các thuộc tính chỉ ra số ô chữ dùng để
in dữ liệu Khi đó dữ liệu in ra sẽ được căn sang trái số ô mà nó dành ra để in dữ liệu Ví dụ %5d
là in số thập phân tại 5 ô trắng, hay %5.2f là in số thực với 5 ô trong đó 2 ô cho phần thực
Trang 18scanf ("%d%d%d", &a, &b, &c); /* nh ập số nguyên cho 3 biến a, b, c */
Tham số truyền vào cho hàm nhập dữ liệu có một chuỗi định dạng bao gồm các mã định dạng dữ liệu để mô tả loại dữ liệu được nhập Chúng ta sử dụng các kí tự định dạng dữ liệu (‘%d’, ‘%f’, ‘%c’, ‘%s’) giống như sử dụng đối với hàm printf() trong chuỗi định dạng này Các tham số cần thiết khác cho một hàm scanf() là địa chỉ vùng nhớ nơi lưu dữ liệu được nhập vào
Do vậy để nhập giá trị cho biến nào thì ta phải lấy địa chỉ bộ nhớ của biến đó khi truyền vào cho hàm scanf() Để lấy địa chỉ của biến ta dùng toán tử & trước tên biến
Chú ý một lỗi bộ nhớ chương trình như ví dụ sau:
int a;
scanf("%d", a); /* nh ập giá trị cho biến a nhưng không lấy địa chỉ */
Đây không phải là một lỗi cú pháp nên chương trình vẫn có thể dịch và chạy được Nhưng khi chạy giá trị số nguyên được người sử dụng nhập vào sẽ không được lưu cho biến a vì địa chỉ lưu giá trị là một địa chỉ không xác định có giá trị bằng số a hiện tại
Để đảm bảo quá trình nhập một kí tự hay một xâu không nhận phải dữ liệu rác trong chương trình ta thường sử dụng câu lệnh fflush(stdin) trước mỗi lần nhập Lí do cần phải có câu lệnh này sẽ được giải thích trong bài nói về vấn đề vào ra với kênh xuất nhập (xem bài 31 - Kênh xuất nhập)
3 Thao tác trực tiếp với màn hình và bàn phím
Một chương trình C viết cho hệ điều hành DOS có thể sử dụng các hàm thao tác trực tiếp với màn hình và bàn phím được khai báo trong tệp tiêu đề <conio.h> Hai hàm hay dùng trong thư viện này là:
clrscr() xoá toàn bộ kí tự hiển thị trên màn hình
getch() chờ nhận một phím được bấm trên bàn phím, kết quả trả về mã phím được bấm
Chương trình mẫu (hexa.c): Nhập một số nguyên dạng thập phân và in ra màn hình số hexa
printf("Mot so thap phan: ");
scanf("%d", &x); /* nh ập số thập phân vào biến x */
printf("So hexa cua no la %x", x); /* in s ố hexa của nó */
getch(); /* d ừng màn hình xem kết quả */
}
Trang 19b) scanf("%d%d", &a, &b);
c) scanf("%d%f", &a, &b);
Câu 2: Viết chương trình cho phép người sử dụng nhập vào một kí tự bất kì và thực hiện in ra mã
ASCII tương ứng của nó
Câu 3: Viết chương trình in ra màn hình một trang giới thiệu về bản thân bạn như tên, năm sinh,
Thời lượng: 2 tiết
Một biểu thức được xây dựng trên cơ sở kết hợp các biến và hằng số cùng với các toán tử
để tạo thành các phép tính Bởi vì trong ngôn ngữ C chỉ có các kiểu dữ liệu số (nguyên hoặc thực) nên một biểu thức luôn trả về kết quả là một số Sau đây chúng ta sẽ xem xét các toán tử có thể được sử dụng trong biểu thức theo nhóm
1 Nhóm toán tử số học
% Lấy phần dư phép chia a%2
Trang 20Các toán tử toán học có thể áp dụng cho các toán hạng là biến, hằng số hoặc là một biểu thức con Riêng toán tử % chỉ áp dụng cho hai số kiểu nguyên Chú ý kết quả của biểu thức là số nguyên hay số thực phụ thuộc vào kiểu dữ liệu của hai toán hạng Nếu hai toán hạng đều là số nguyên thì kết quả của biểu thức sẽ là một số nguyên Trường hợp có một toán hạng là số thực thì kết quả biểu thức là số thực
Ví dụ:
int i = 5;
float f;
/* chia cho m ột số nguyên */
f = i/2; /* f = 2 vì k ết quả của biểu thức chỉ là một số nguyên */
/* chia cho m ột số thực */
f = i/2.0; /* f = 2.5 vì k ết quả của biểu thức là một số thực */
Thứ tự ưu tiên của các toán tử số học trong một biểu thức theo trật tự truyền thống Ví dụ 3+5*2 sẽ cho ta kết quả là 13
>= So sánh lớn hơn hoặc bằng a>=5
Các toán tử so sánh cũng có thể áp dụng cho các toán hạng là biến, hằng số hoặc là một biểu thức con Kết quả của biểu thức so sánh luôn trả về kết quả là 1 thể hiện phép so sánh đúng hoặc 0 thể hiện phép so sánh sai Ví dụ 3<5 cho kết quả là 1 còn 3>5 cho kết quả là 0
3 Nhóm toán tử quan hệ logic
&& Quan hệ và (and) (a<5)&&(b==0)
|| Quan hệ hoặc (or) (a<5)||(b==0)
! Quan hệ đảo (not) !(a<5)
Các toán tử quan hệ áp dụng được cho các biến, hằng số và biểu thức con trả về giá trị số Nếu toán hạng có giá trị 0 thì được coi như là một mệnh đề sai, khác 0 cho một mệnh đề đúng Giá trị biểu thức thể hiện kết quả của kết hợp logic hai mệnh đề, 1 nếu kết hợp logic là đúng, 0 cho trường hợp sai Ví dụ 3<7&&8>6 cho kết quả là 1, !3 cho giá trị 0
4 Nhóm toán tử trên bit
& Và bit (2 ngôi) a&5
Trang 21| Hoặc bit (2 ngôi) a|5
> Dịch bit sang phải a>>2
<< Dịch bit sang trái a<<2
Tương tự như toán tử số học, toán tử trên bit thực hiện các phép tính số học trên bit với các
số nguyên Các toán hạng dùng cho các toán tử trên bit phải là số nguyên Kết quả của biểu thức hoàn toàn phụ thuộc vào phép tính trên bit của các số hạng sau khi đã được phân tích thành số nhị phân Ví dụ 5&4 cho kết quả là 4 (101&100=100), 5|3 cho kết quả là 7 (101|011=111)
int b = a == 5; /* t ương đương b=(a==5) và khi đó b có giá trị 1 */
int c = a = 5; /* t ương đương c=(a=5) và khi đó c có giá trị 5 */
Ngoài ra chúng ta còn có một số phép gán đi kèm một phép tính số học Bảng dưới đây trình bày một số toán tử gán loại này
Toán tử Ý nghĩa Ví dụ Biểu thức tương đương
&= tự và bit a&=5 a=a&5
>>= tự dịch bit phải a>>=5 a=a>>5
Trang 22<<= tự dịch bit trái a<<=5 a=a<<5
6 Nhóm toán tử tăng/giảm
Toán tử Ý nghĩa Dạng tiền tố Dạng hậu tố
Các toán tử tăng/giảm chỉ áp dụng cho một toán hạng là biến kiểu nguyên Nó làm tăng hay giảm biến nguyên này 1 đơn vị Có hai cách dùng toán tử tăng giảm dưới dạng tiền tố và hậu tố
Sự khác nhau của hai cách dùng này là giá trị trả về của biểu thức Biểu thức của toán tử dùng dạng tiền tố trả về giá trị của biến sau khi thực hiện tăng/giảm còn ở dạng hậu tố là giá trị của biến trước khi được tăng/giảm
7 Toán tử điều kiện
Ngôn ngữ C hỗ trợ xây dựng một biểu thức điều kiện trong đó kết quả của biểu thức phụ thuộc vào một điều kiện kiểm tra Biểu thức này có dạng:
<biểu thức kiểm tra> ? <biểu thức 1> : <biểu thức 2>
Nếu <biểu thức kiểm tra> có giá trị đúng (khác 0) thì biểu thức lấy giá trị của <biểu thức 1> còn không lấy giá trị của <biểu thức 2>
từ int sang float) Trong trường hợp phép chuyển kiểu mà bị mất thông tin thì nó không thể thực hiện được tự động Khi đó ta cần phải có một phép ép kiểu bắt buộc theo định dạng dưới đây
(<ki ểu mới>) <biểu thức>
Trang 23b=(int)(5/2.0); /* đúng vì số thực 2.5 bị ép kiểu về số nguyên 2 */
Như vậy phép chuyển kiểu tự động chỉ thực hiện được khi nó không bị mất mát thông tin
Sơ đồ sau đây là thể hiện việc chuyển kiểu tự động có thể thực hiện trên các kiểu dữ liệu cơ bản
char >int >long >float >double
9 Thứ tư ưu tiên của các toán tử
Một biểu thức có thể là sự kết hợp của nhiều toán tử trong các nhóm với nhau Khi đó cần
có một trật tự xác định được thứ tự thực hiện của các toán tử trong biểu thức Sau đây là quy tắc thứ tự ưu tiên của các toán tử được sắp xếp phân theo nhóm Trong trường hợp có nhiều toán tử trong nhóm thì trật tự kết hợp được quy ước từ phải sang trái hay ngược lại là phụ thuộc vào mỗi nhóm
Mức ưu tiên Nhóm toán tử Trật tự
1 Nhóm 1 ngôi ( !, ~, ++, , ) <<<
2 Nhóm toán học (*, /, %, +, -) >>>
3 Nhóm dịch bit (<<, >>) >>>
4 Nhóm so sánh (<, <=, >, >=, ==, !=) >>>
5 Nhóm toán tử trên bit (&, |, ^) >>>
6 Nhóm quan hệ logic (&&, ||) >>>
7 Toán tử điều kiện (?:) <<<
Trang 24Thời lượng: 1 tiết
Để thực hiện tính toán các công thức toán học phức tạp chúng ta cần phải sử dụng các hàm toán học của thư viện Muốn sử dụng chúng cần phải khai báo tệp tiêu đề <math.h> trong chương trình
Một số hàm toán học trong <math.h>
double ceil(double x) số nguyên nhỏ nhất >= x double cos(double x) cosine của x (radians) double exp(double x) ex
double fabs (double x ) |x|
double floor(double x) số nguyên lớn nhất <= x double log(double x) ln x
double log10(double x ) log10x double pow(double x, double y) xydouble sin(double x) sine của x double sqrt(double x) căn bậc hai của x
double tan(double x) tangent của x
Trang 25Các hằng số toán học
M_E số tự nhiên e M_PI số pi
MAXFLOAT số thực thực float lớn nhất Ngoài ra chúng ta còn có một số hàm toán học với số nguyên trong <stdlib.h>
Câu 1: Viết chương trình quay sổ xố cho giải đặc biệt là một số ngẫu nhiên có 9 chữ số
Câu 2: Viết chương trình cho đọc một góc theo độ rồi in ra màn hình sin, cos và tan của góc đó
Mục 2.2 - Các cấu trúc lệnh điều khiển
Cũng như các ngôn ngữ lập trình bậc cao khác, C có các cấu trúc lệnh điều khiển để tạo ra các rẽ nhánh giải thuật và các vòng lặp Trong mục này học viên sẽ được tìm hiểu các câu lệnh if, switch, for, while và do while
Yêu cầu: Có kiến thức về lưu đồ giải thuật
Thời lượng: 3 tiết
Trang 26if (<bi ểu thức>) <lệnh đơn hoặc khối lệnh>
[else <lệnh đơn hoặc khối lệnh>]
Câu lệnh if dùng để thực hiện một câu lệnh đơn hay một khối lệnh tuỳ thuộc vào một biểu thức kiểm tra Nếu <biểu thức> cho kết quả là đúng thì nhánh chính của câu lệnh if được thực hiện, trường hợp sai thì nhánh else (nếu có) sẽ được thực hiện Chú ý rằng một lệnh đơn luôn kết thúc bằng dấu chấm phẩy ‘;’ còn các lệnh của một khối nằm trong cặp dấu {}
printf("Nhap he so cua phuong trinh bac nhat\n");
printf("He so a: "); scanf("%f", &a);
printf("He so b: "); scanf("%f", &b);
Trang 27in lịch làm việc trong tuần
Trang 28Câu 1: Viết chương trình giải và biện luận phương trình bậc 2 (ax2+bx+c=0)
Câu 2: Viết chương trình đọc vào một số của tháng trong năm rồi in ra màn hình tên của tháng đó
trong tiếng Anh
Câu 3: Cho bốn số a, b, c, d đọc vào từ bàn phím Hãy tìm giá trị cực đại và gán cho biến có tên
là Max và in ra kết quả của nó
Câu 4: Viết chương trình nhập vào phần thực và phần ảo của một số phức xong rồi in ra màn
hình dạng hoàn chỉnh của số phức đó
Câu 5: Viết chương trình đọc vào một số thể hiện tổng số giây rồi in ra số giờ, phút, giây tương
đương Ví dụ 7322 giây là tương đương 2 giờ, 2 phút, 2 giây
Bài 12 - Cấu trúc lệnh lặp
Tóm tắt nội dung:
Vòng lặp được chia làm hai loại là vòng lặp có điều kiện lặp kiểm tra trước (while) và vòng lặp kiểm tra sau (do while) Trong C vòng lặp for là vòng lặp cùng loại vòng lặp while nhưng có thêm các lệnh khởi tạo khi bắt đầu vòng lặp và lệnh thực hiện sau mỗi lần lặp Câu lệnh break để kết thúc một vòng lặp, còn continue để quay trở lại một lần lặp mới
Thời lượng: 2 tiết
1 Lệnh for
Dạng thức chung:
for ([<kh ởi tạo>]; [<điều kiện lặp>]; [<sau lặp>]) <lệnh hoặc khối lệnh>
Vòng lặp for cho phép thực hiện một lệnh hoặc một khối lệnh lặp nhiều lần khi mà <điều kiện lặp> kiểm tra còn đúng Phần <khởi tạo> của vòng for cho phép thực hiện một số lệnh khi bắt đầu thực hiện vòng lặp Phần <sau lặp> là những câu lệnh được thực hiện sau mỗi lần lặp Trong mỗi phần khởi tạo và sau lặp nếu có nhiều câu lệnh thì chúng được phân cách nhau bởi dấu phẩy ‘,’
Ví dụ:
int i, j;
Trang 29/* in 5 dòng Hello b ằng cách lặp với biến i mang 5 giá trị (1-5) */
for (i=1; i<=5; i++)
printf("Hello\n") ;
/* s ử dụng nhiều lệnh trong khởi tạo và sau lặp */
for (i=1, j=1; i<=2*j; i+=3, j++)
while (< điều kiện lặp>) <lệnh hoặc khối lệnh>
Các câu lệnh trong vòng lặp while được thực hiện lặp chừng nào biểu thức <điều kiện lặp> còn mang giá trị đúng Các câu lệnh trong vòng lặp chỉ được thực hiện sau khi đã kiểm tra điều kiện lặp đúng Vì vậy while được gọi là vòng lặp có số lần lặp không xác định và kiểm tra điều kiện lặp trước
Trang 30<khởi tạo của vòng for>
while (<điều kiện lặp>)
<các lệnh lặp>
} while (< điều kiện lặp>);
Vòng lặp do while chỉ khác với vòng lặp while ở chỗ <điều kiện lặp> được kiểm tra sau mỗi lần lặp Do vậy ta có thể gọi do while là vòng lặp có số lần lặp không xác định và kiểm tra điều kiện lặp sau
Chú ý: Ngược lại với vòng lặp repeat until của PASCAL, điều kiện kiểm tra của do while là
điều kiện lặp lại chứ không phải điều kiện ra
Khi cần những vòng lặp kiểm tra điều kiện lặp sau thì bắt buộc phải sử dụng do while Ví
dụ cần nhập một số nguyên n trong khoảng [1, 10] bằng một vòng lặp để khi người sử dụng nhập sai giá trị thì nhập lại Khi đó ta phải dùng do while vì rõ ràng phải nhập dữ liệu rồi ta mới kiểm tra xem có cần phải nhập lại không
Trang 31- continue: bỏ qua tất cả các lệnh còn lại trong vòng lặp và quay trở lại từ đầu vòng lặp
- break: ra khỏi vòng lặp tức thì mà không phụ thuộc vào điều kiện lặp Người ta thường dùng break để thoát ra khỏi các vòng lặp vô hạn
Ví dụ:
int value;
/* Nhập giá trị nguyên dương cho value, để kết thúc nhập 0 */
while (scanf("%d'', &value ) == 1 && value != 0)
{
if (value < 0) {
printf("Ch ỉ nhập số nguyên dương\n'');
break; /* Thoát kh ỏi vòng lặp tức thì */
}
if (value > 100) {
printf("B ỏ qua không xử lí số lớn hơn 100\n'');
continue; /* Quay l ại để nhập giá trị mới */
{ /* Pi_4 là t ổng của biểu thức Pi/4 */
float Pi_4, epsilon;
int mauso, dau;
/* kh ởi tạo các giá trị cho phép tính tổng */
Pi_4 = 0;
mauso = 1; /* mauso c ủa số hạng đầu tiên */
dau = 1; /* d ấu của số hạng đầu tiên */
dau = -dau; /* đảo dấu cho số hạng sau */
mauso += 2; /* t ăng mẫu số cho số hạng sau */
}while(epsilon>0.001); /* l ặp khi độ chính xác > 0.001 */
printf("Pi co do chinh xac 0.001 = %f", Pi_4*4);
Trang 32Câu 3: In ra các cách để có 20000 đồng với 3 loại giấy bạc: 500 đ, 200 đ và 100 đ
Câu 4: Viết chương trình dùng vòng lặp để hiện các hình sau trên màn hình
Yêu cầu: Hiểu khái niệm phân chia modul chương trình và giải thuật đệ quy
Thời lượng: 2 tiết
Trang 33Bài 13 - Cấu trúc chương trình với hàm
Tóm tắt nội dung:
Các hàm trong chương trình C là một modul chương trình đẳng cấp Chúng có thể gọi lẫn nhau trong chương trình Một hàm có thể trả về kết quả nhưng cũng có thể không (hàm void) Khai báo nguyên mẫu của hàm là một khai báo hàm chỉ có tiêu đề mà không có phần thi hành
Thời lượng: 1 tiết
1 Hàm trong ngôn ngữ C
Một chương trình C được cấu trúc thông qua các hàm Mỗi hàm là một modul nhỏ trong chương trình Nó có thể được gọi nhiều lần tại các vị trí khác nhau trong chương trình Trong C không phân biệt thủ tục và hàm như PASCAL mà nó coi thủ tục như là một hàm mà không trả về
dữ liệu Một đặc điểm khác biệt nữa đó là không có khái niệm thủ tục con, tất cả các hàm kể cả hàm chính (main) đều có cùng một cấp duy nhất (cấu trúc hàm đẳng cấp) Một hàm có thể gọi một hàm khác bất kì của chương trình
- <tên hàm> là một tên do người sử dụng đặt thoả mãn yêu cầu về đặt tên trong C Nếu hàm
có tên là main thì đó là hàm chính của chương trình
- <kiểu trả về> là kiểu của dữ liệu trả về cho hàm Nó có thể là một kiểu dữ liệu cơ bản (char, int, ) hay kiểu phức hợp (xem chương 3 - Các cấu trúc dữ liệu phức) Khi muốn viết một thủ tục (hàm không có kết quả) thì kiểu trả về ta để là void Kiểu trả về có thể không được khai báo, khi đó trình biên dịch lấy mặc định là kiểu int
- <danh sách tham số> được khai báo giống như khai báo biến Các tham số trong danh sách được phân cách bởi dấu phẩy ‘,’ Nếu dùng từ khoá void cho danh sách tham số của một hàm thì hàm đó không có bất kì một tham số nào
- <thân hàm> bao gồm phần khai báo biến ở đầu (bắt buộc) và các câu lệnh sau khai báo biến
Để thoát ra khỏi hàm và trả về một giá trị ta dùng câu lệnh return <biểu thức> Nếu là hàm void thì câu lệnh return không có giá trị trả về kèm theo
Ví dụ:
/* hàm tính max hai s ố nguyên */
int max (int a, int b)
{
return (a > b) ? a: b;
}
Trang 34/* hàm in bình ph ương của số 1 đến 10, hàm không có tham số */
Chương trình mẫu (hampi.c): Hàm tính số Pi theo công thức Pi/4 = 1-1/3+1/5-1/7+ với độ
chính xác là tham số truyền vào
int mauso, dau;
/* kh ởi tạo các giá trị cho phép tính tổng */
Pi_4 = 0;
mauso = 1; /* mauso c ủa số hạng đầu tiên */
dau = 1; /* d ấu của số hạng đầu tiên */
/* vòng l ặp tính tổng */
do
{
sh = 1.0/mauso; /* sh mang giá tr ị số hạng mới */
Pi_4 += dau*sh; /* thêm s ố hạng mới */
dau = -dau; /* đảo dấu cho số hạng sau */
mauso += 2; /* t ăng mẫu số cho số hạng sau */
}while(sh*4>epsilon); /* l ặp khi độ chính xác > epsilon */
/* in kết quả của hàm tính Pi với độ chính xác epsilon */
printf("Pi co do chinh xac %f = %f", epsilon, Pi(epsilon));
Trang 35}
2 Khai báo nguyên mẫu (prototype) cho hàm
Khi một hàm gọi đến một hàm khác trong chương trình thì hàm được gọi đã phải được biết đến từ trước trong chương trình Một hàm được coi là đã "biết đến" khi nó đã khai báo đầy đủ hoặc có khai báo nguyên mẫu (prototype) của nó Một khai báo nguyên mẫu cho hàm thì chỉ có phần tiêu đề hàm mà không có thân hàm Trong nguyên mẫu của hàm cần chỉ ra được tên hàm, kiểu dữ liệu của các tham số truyền vào và kết quả trả về Dưới đây là khai báo nguyên mẫu của các hàm ở ví dụ trên
int max(int, int); /* m ột khai báo nguyên mẫu hàm phải có ; kết thúc */
void squares();
Trong một chương trình để giúp người đọc nhanh chóng nắm bắt cấu trúc của nó thì phần đầu của chương trình thường có khai báo nguyên mẫu của các hàm trong chương trình Các khai báo hàm đầy đủ có thân hàm thường được viết phần sau của chương trình vì người đọc ít khi quan tâm đến nội dung chi tiết của từng hàm
Chương trình mẫu (nguyenmau.c): Một chương trình tính max hai số có sử dụng khai báo
nguyên mẫu hàm
#include <stdio.h>
/* khai báo prototype cho các hàm c ủa chương trình */
int max(int, int);
float fmax(float, float);
void main()
{
int a, b;
float fa, fb;
printf("Nhap hai so nguyen: ");
scanf("%d%d", &a, &b);
printf("Gia tri lon nhat la %d\n", max(a, b));
printf("Nhap hai so thuc: ");
scanf("%f%f", &fa, &fb);
printf("Gia tri lon nhat la %f\n", fmax(fa, fb));
}
/* khai báo hàm đầy đủ */
int max(int a, int b)
Trang 36BÀI TẬP
Câu 1: Viết hàm cho phép tính diện tích của các hình vuông, hình tròn, hình thang trong một
chương trình Tạo một menu chương trình để người sử dụng lựa chọn một phương án tính diện tích theo cách thức sau
1 Tính diện tích hình vuông
2 Tính diện tích hình tròn
3 Tính diện tích hình thang
Hãy ấn một số để chọn:
Câu 2: Tạo các hàm cho giải và biện luận phương trình bậc nhất và bậc hai Hàm giải phương
trình bậc hai sẽ gọi hàm phương trình bậc nhất khi hệ số a của phương trình bằng 0 Viết chương trình cho phép người sử dụng lựa chọn các công việc như sau
1 Giải và biện luận phương trình bậc nhất
2 Giải và biện luận phương trình bậc hai
Thời lượng: 1 tiết
C là ngôn ngữ cho phép viết các hàm đệ qui Một hàm đệ qui là hàm mà trong thân hàm lại gọi đến chính nó Ví dụ để tính n! ta sử dụng công thức đệ qui:
Trang 37Chương trình mẫu (daoso.c): Sử dụng hàm đệ qui để in số đảo của một số nguyên dương Ví dụ
12345 có số đảo là 54321
#include <stdio.h>
void insodao(int n)
{
int donvi, conlai
donvi = n%10; /* tính ph ần đơn vị của số n */
conlai = n/10; /* giá tr ị từ phần chục của n */
Câu 1: Viết hàm tính an với a là số thực, n nguyên dương, theo hai cách: đệ qui và không đệ qui
Câu 2: Viết hàm đếm số chữ số của một số nguyên n bất kì dùng phương pháp đệ qui
Câu 3: Hãy dùng hàm tính n! để viết chương trình hoàn chỉnh tính Ckn = n! / (k! * (n-k)!)
Câu 4: Dãy số Fibonacci là dãy số F1, F2, F3, ,Fn được tạo ra với công thức Fn=Fn-1+Fn-2 với
F1 = 1, F2 = 1 Thí dụ: 1, 1, 2, 3, 5, 8, 13, 21,
Hãy lập chương trình dùng hàm đệ qui để in ra dãy số đó
Trang 38CHƯƠNG 3 – CÁC CẤU TRÚC DỮ LIỆU PHỨC
Chỉ có các dữ liệu kiểu cơ bản là không thể đủ để viết một chương trình với những loại dữ liệu phức tạp Trong chương này học viên sẽ nắm bắt được cách thức tạo các cấu trúc dữ liệu phức như mảng, xâu, cấu trúc bản ghi ở trong ngôn ngữ C Con trỏ cũng được coi là một loại dữ liệu phức trong C Loại dữ liệu con trỏ cho phép người sử dụng quản lí bộ nhớ rất hiệu quả trong chương trình C
Yêu cầu: Có kiến thức về lập trình C cơ bản trong chương 2
Thời lượng: 10 tiết
Mục 3.1 - Mảng dữ liệu
Mảng dữ liệu là một tập các phần tử có cùng kiểu dữ liệu được lưu trữ liên tiếp nhau trong bộ nhớ Số phần tử của mảng luôn được xác định ban đầu là một hằng số Chúng ta có thể truy cập vào các phần tử của mảng thông qua chỉ số Một mảng có thể là một chiều hay nhiều chiều
Yêu cầu: Đã tìm hiểu các kiểu dữ liệu cơ bản
Thời lượng: 2 tiết
Bài 15 - Mảng một chiều
Tóm tắt nội dung:
Mảng ở trong C được khai báo với số phần tử của mảng là một hằng số Các phần tử trong mảng luôn luôn được đánh chỉ số tăng dần từ 0 cho đến hết
Thời lượng: 1 tiết
Mảng là một cấu trúc dữ liệu trong bộ nhớ có khả năng lưu trữ một tập các phần tử có cùng kiểu dữ liệu Các phần tử này được bố trí nằm liên tiếp với nhau và được đánh chỉ số Để truy cập một phần tử ta truy cập theo chỉ số của nó Mảng có một hạn chế là số phần tử trong mảng luôn phải được xác định từ trước như là môt hằng số Vì vậy khi khai báo mảng ta luôn khai báo với
số phẩn tử lớn nhất cần có để dùng trong thực tế
Một mảng trong ngôn ngữ C được khai báo với số phần tử của nó Các phần tử được đánh chỉ số từ 0 và tăng dần lên Chỉ có một cách đánh chỉ số này ở trong C Điều đó làm nên sự khác biệt cho mảng của C với mảng của những ngôn ngữ khác như PASCAL
Khai báo mảng:
<kiểu phần tử> <tên mảng>[<hằng số phần tử>];
Trang 39Truy cập một phần tử theo chỉ số (bắt đầu từ 0):
for (i=0; i<5; i++) a[i] = 0;
Một mảng có thể được khai báo với giá trị khởi tạo cho các phần tử Danh sách giá trị khởi tạo được đặt trong dấu ngoặc kép {}
Chương trình mẫu (mangso.c): Nhập một dãy số nguyên n phần tử (1>=n>=20) sau đó tìm tổng
của dãy số In ra màn hình dãy số sau khi đã sắp xếp
#include <stdio.h>
void main()
{
int a[20], n, i, j, sum, tg;
/* nh ập số phần tử có kiểm tra để nhập lại */
Trang 40for(i=0; i<n; i++)
b Xếp các số có giá trị tuyệt đối lớn hơn 10 lên đầu dãy
c Trong dãy kết quả nhận được từ câu trên hãy xóa bớt số thứ 3 của dãy và số thứ N của dãy Đưa các dãy kết quả ra màn hình
Câu 3: Viết chương trình đê nhập một mảng số nguyên rồi thực hiện sắp xếp chúng theo thứ tự
tăng dần Đọc một số nguyên mới vào từ bàn phím để chèn nó vào dãy số đã sắp xếp mà vẫn đảm bảo thứ tự
Câu 4: Nhập dữ liệu cho 2 mảng số A, B rồi sắp xếp theo thứ tự tăng dần Hãy trộn hai mảng đó
lại để có mảng thứ 3 là mảng C với điều kiện mảng C cũng được sắp xếp theo thứ tự tăng dần ngay sau khi trộn
Bài 16 - Mảng nhiều chiều