CHƯƠNG 1 6 NHỮNG KHÁI NIỆM CƠ BẢN VỀ NGÔN NGỮ C 6 GIỚI THIỆU 6 1.1 CÁC CHƯƠNG TRÌNH DỊCH C CƠ BẢN 6 1.2 ĐẶC ĐIỂM CỦA NGÔN NGỮ C 7 1.3 CẤU TRÚC CƠ BẢN CỦA MỘT CHƯƠNG TRÌNH C 7 1.4 BIÊN DỊCH VÀ THỰC THI MỘT CHƯƠNG TRÌNH 9 1.5 BIẾN, HẰNG, ĐỊNH DANH 10 1.5.1 Biến (variable) 10 1.5.2 Hằng (constant) 10 1.5.3 Định danh (identifier) 11 1.5.4 Từ khóa (Keywords) 12 1.6 CÁC KIỂU DỮ LIỆU CƠ SỞ VÀ DẪN XUẤT 12 1.6.1 Những kiểu dữ liệu cơ sở 12 1.6.2 Những kiểu dữ liệu dẫn xuất 14 1.7 NHẬP VÀ XUẤT TRONG C 15 1.7.1 Xuất dữ liệu hàm printf 16 1.7.2 Cách xuất dữ liệu dạng có quy cách 17 1.7.3 Phương thức nhập dữ liệu 18 1.7.4 Bộ nhớ đệm Nhập và Xuất (Buffered IO) 19 1.8 SỬ DỤNG TRÌNH BIÊN DỊCH DEVCC++ 20 CHƯƠNG 2 28 TOÁN TỬ VÀ BIỂU THỨC 28 GIỚI THIỆU 28 2.1 BIỂU THỨC 28 2.2 CÁC TOÁN TỬ SỐ HỌC 29 2.2.1 Các toán tử một ngôi (unary) 29 2.2.2 Các toán tử hai ngôi (binary) 30 2.3 TOÁN TỬ GÁN 31 2.4 TOÁN TỬ QUAN HỆ 31 2.5 TOÁN TỬ LUẬN LÝ 32 2.6 TOÁN TỬ LUẬN LÝ NHỊ PHÂN 32 2.7 ÉP KIỂU TRONG C 33 2.8 ĐỘ ƯU TIÊN CỦA TOÁN TỬ 35 CHƯƠNG 3 39 CÁC CẤU TRÚC ĐIỀU KHIỂN 39 GIỚI THIỆU 39 3.1 CẤU TRÚC LỰA CHỌN 39 3.1.1 Câu lệnh if 40 3.1.2 Câu lệnh if...then...else 41 3.1.3 Nhiều lựa chọn các câu lệnh if...then...else 43 3.1.4 Các cấu trúc if lồng nhau 45 2 3.1.5 Toán tử ? 47 3.1.6 Câu lệnh switch 47 3.2 VÒNG LẶP 50 3.2.1 Vòng lặp for 50 3.2.2 Vòng lặp while 55 3.2.3 Vòng lặp do...while 57 3.3 CÁC LỆNH NHẨY 59 3.3.1 Lệnh break 59 3.3.2 Lệnh continue 59 3.3.3 Lệnh return 60 CHƯƠNG 4 61 SỬ DỤNG HÀM TRONG C 61 GIỚI THIỆU 61 4.1 SỬ DỤNG HÀM TRONG C 61 4.2 CẤU TRÚC HÀM 62 4.2.1 Các đối số của một hàm 62 4.2.2 Sự trả về từ một hàm 63 4.2.3 Kiểu giá của một hàm 64 4.3 NGUYÊN MẪU HÀM 65 4.4 ĐỊNH NGHĨA HÀM 65 4.5 GỌI HÀM 66 4.5.1 Truyền tham số cho hàm 67 4.5.2 Sự lồng nhau giữa các lời gọi hàm 69 4.5.3 Hàm trong chương trình nhiều tập tin 70 4.6 PHẠM VI CỦA BIẾN 70 4.6.1 Biến cục bộ 70 4.6.2 Tham số hình thức 71 4.6.3 Biến toàn cục 72 4.7 LỚP LƯU TRỮ 73 4.7.1 Biến tự động (auto) 74 4.7.2 Biến ngoại (extern) 74 4.7.3 Biến tĩnh (static) 75 4.7.4 Biến thanh ghi (register) 76 4.8 ĐỆ QUI 77 4.9 MỘT SỐ THƯ VIỆN THÔNG DỤNG TRONG C 79 CHƯƠNG 5 81 MẢNG, XÂU KÍ TỰ 81 GIỚI THIỆU 81 5.1 KIỂU DỮ LIỆU MẢNG 81 5.1.1 Mảng một chiều 81 5.1.2 Mảng đa chiều 88 5.3 CHUỖI KÍ TỰ 93 5.3.1 Khai báo chuỗi 93 5.3.2 Xuất chuỗi 93 5.3.3 Nhập chuỗi 94 5.3.4 Truyền chuỗi vào hàm 95 5.3.5 Mảng chuỗi kí tự 96 3 5.3.6 Một số hàm trong thư viện string.h 98 CHƯƠNG 6 99 KIỂU DỮ LIỆU CON TRỎ
Trang 1LỜI NÓI ĐẦU
Ngôn ngữ lập trình C là ngôn ngữ được sử dụng rộng rãi và phổ biến đối với các lập trình viên chuyên nghiệp cũng như các nhà phát triển phần mềm Cho đến nay, ngôn ngữ lập trình C vẫn được coi là ngôn ngữ lập trình cơ bản nhất đối với hầu hết sinh viên các trường đại học Giáo trình ngôn ngữ lập trình C được biên soạn làm giáo trình cho sinh viên bậc đại học và cao đẳng chuyên ngành Công nghệ thông tin của khoa Công nghệ Thông tin - trường Đại học Điện lực Giáo trình này cũng có thể làm tài liệu tham khảo cho các giảng viên trong quá trình giảng dạy
Nội dung giáo trình tập trung vào các kiến thức căn bản nhất của ngôn ngữ lập trình C giúp người đọc bước đầu tiếp cận dễ dàng với ngôn ngữ lập trình này Các nội dung chính được trình bày trong giáo trình bao gồm:
Chương 1: Những khái niệm cơ bản về ngôn ngữ C
Chương 2: Toán tử và biểu thức
Chương 3: Các cấu trúc điều khiển
Chương 4: Sử dụng hàm trong C
Chương 5: Mảng, xâu kí tự
Chương 6: Con trỏ
Chương 7: Kiểu dữ liệu cấu trúc
Chương 8: Quản lý tệp tin trong C
Trong quá trình biên soạn giáo trình này, chúng tôi đã cố gắng để hoàn chỉnh Tuy nhiên không thể tránh khỏi thiếu sót Vì vậy, rất mong nhận được các ý kiến đóng góp từ các bạn đồng nghiệp, các em sinh viên để giáo trình ngày càng hoàn thiện hơn
Các tác giả xin gửi lời cảm ơn chân thành tới Giannini, Mario, Kernighan, Brian W.; Ritchie, Dennis M, King, K N, Thompson, Ken, Phạm Văn Ất, Scott Robert Ladd, tập đoàn Aptech, là các tác giả các tài liệu tham khảo [1,2,3,4,5,6,7] làm cơ sở chính cho việc biên soạn giáo trình
Các tác giả gửi lời chân thành cảm ơn đến PGS.TS Ngô Quốc Tạo, Viện CNTT, TS Đào Nam Anh, trường Đại học Điện lực đã có những nhận xét quí báu trong quá trình biên soạn giáo trình này
Hà nội, ngày 01 tháng 07 năm 2013
Nhóm biên soạn
1
Trang 2MỤC LỤC
LỜI NÓI ĐẦU 1
CHƯƠNG 1 6
NHỮNG KHÁI NIỆM CƠ BẢN VỀ NGÔN NGỮ C 6
GIỚI THIỆU 6
1.1 CÁC CHƯƠNG TRÌNH DỊCH C CƠ BẢN 6
1.2 ĐẶC ĐIỂM CỦA NGÔN NGỮ C 7
1.3 CẤU TRÚC CƠ BẢN CỦA MỘT CHƯƠNG TRÌNH C 7
1.4 BIÊN DỊCH VÀ THỰC THI MỘT CHƯƠNG TRÌNH 9
1.5 BIẾN, HẰNG, ĐỊNH DANH 10
1.5.1 Biến (variable) 10
1.5.2 Hằng (constant) 10
1.5.3 Định danh (identifier) 11
1.5.4 Từ khóa (Keywords) 12
1.6 CÁC KIỂU DỮ LIỆU CƠ SỞ VÀ DẪN XUẤT 12
1.6.1 Những kiểu dữ liệu cơ sở 12
1.6.2 Những kiểu dữ liệu dẫn xuất 14
1.7 NHẬP VÀ XUẤT TRONG C 15
1.7.1 Xuất dữ liệu - hàm printf 16
1.7.2 Cách xuất dữ liệu dạng có quy cách 17
1.7.3 Phương thức nhập dữ liệu 18
1.7.4 Bộ nhớ đệm Nhập và Xuất (Buffered I/O) 19
1.8 SỬ DỤNG TRÌNH BIÊN DỊCH DEV-C/C++ 20
CHƯƠNG 2 28
TOÁN TỬ VÀ BIỂU THỨC 28
GIỚI THIỆU 28
Trang 32.1 BIỂU THỨC 28
2.2 CÁC TOÁN TỬ SỐ HỌC 29
2.2.1 Các toán tử một ngôi (unary) 29
2.2.2 Các toán tử hai ngôi (binary) 30
2.3 TOÁN TỬ GÁN 31
2.4 TOÁN TỬ QUAN HỆ 31
2.5 TOÁN TỬ LUẬN LÝ 32
2.6 TOÁN TỬ LUẬN LÝ NHỊ PHÂN 32
2.7 ÉP KIỂU TRONG C 33
2.8 ĐỘ ƯU TIÊN CỦA TOÁN TỬ 35
CHƯƠNG 3 39
CÁC CẤU TRÚC ĐIỀU KHIỂN 39
GIỚI THIỆU 39
3.1 CẤU TRÚC LỰA CHỌN 39
3.1.1 Câu lệnh if 40
3.1.2 Câu lệnh if then else 41
3.1.3 Nhiều lựa chọn các câu lệnh if then else 43
3.1.4 Các cấu trúc if lồng nhau 45
2
Trang 43.1.5 Toán tử ? 47
3.1.6 Câu lệnh switch 47
3.2 VÒNG LẶP 50
3.2.1 Vòng lặp for 50
3.2.2 Vòng lặp while 55
3.2.3 Vòng lặp do while 57
3.3 CÁC LỆNH NHẨY 59
3.3.1 Lệnh break 59
3.3.2 Lệnh continue 59
3.3.3 Lệnh return 60
CHƯƠNG 4 61
SỬ DỤNG HÀM TRONG C 61
GIỚI THIỆU 61
4.1 SỬ DỤNG HÀM TRONG C 61
4.2 CẤU TRÚC HÀM 62
4.2.1 Các đối số của một hàm 62
4.2.2 Sự trả về từ một hàm 63
4.2.3 Kiểu giá của một hàm 64
4.3 NGUYÊN MẪU HÀM 65
4.4 ĐỊNH NGHĨA HÀM 65
4.5 GỌI HÀM 66
4.5.1 Truyền tham số cho hàm 67
4.5.2 Sự lồng nhau giữa các lời gọi hàm 69
4.5.3 Hàm trong chương trình nhiều tập tin 70
4.6 PHẠM VI CỦA BIẾN 70
4.6.1 Biến cục bộ 70
4.6.2 Tham số hình thức 71
Trang 54.6.3 Biến toàn cục 72
4.7 LỚP LƯU TRỮ 73
4.7.1 Biến tự động (auto) 74
4.7.2 Biến ngoại (extern) 74
4.7.3 Biến tĩnh (static) 75
4.7.4 Biến thanh ghi (register) 76
4.8 ĐỆ QUI 77
4.9 MỘT SỐ THƯ VIỆN THÔNG DỤNG TRONG C 79
CHƯƠNG 5 81
MẢNG, XÂU KÍ TỰ 81
GIỚI THIỆU 81
5.1 KIỂU DỮ LIỆU MẢNG 81
5.1.1 Mảng một chiều 81
5.1.2 Mảng đa chiều 88
5.3 CHUỖI KÍ TỰ 93
5.3.1 Khai báo chuỗi 93
5.3.2 Xuất chuỗi 93
5.3.3 Nhập chuỗi 94
5.3.4 Truyền chuỗi vào hàm 95
5.3.5 Mảng chuỗi kí tự 96
3
Trang 65.3.6 Một số hàm trong thư viện string.h 98
CHƯƠNG 6 99
KIỂU DỮ LIỆU CON TRỎ 99
GIỚI THIỆU 99
6.1 MỘT SỐ KHÁI NIỆM CƠ BẢN 99
6.1.1 Cách lưu trữ biến trong bộ nhớ 99
6.1.2 Khái niệm con trỏ 99
6.1.3 Các trường hợp sử dụng con trỏ 100
6.1.4 Khai báo con trỏ 100
6.1.5 Làm việc với con trỏ 100
6.2 CÁC PHÉP TOÁN TRÊN CON TRỎ 102
6.2.1 Gán giá trị cho con trỏ 102
6.2.2 Phép toán số học trên con trỏ 103
6.2.3 Phép toán so sánh con trỏ 104
6.2.4 Con trỏ không kiểu (void) và phép ép kiểu con trỏ 105
6.2.5 Con trỏ đa cấp 106
6.3 TRUYỀN CON TRỎ VÀO HÀM 107
6.4 CON TRỎ VÀ MẢNG MỘT CHIỀU 108
6.5 CON TRỎ VÀ MẢNG NHIỀU CHIỀU 111
6.5.1 Khai báo mảng hai chiều dưới dạng con trỏ 111
6.5.2 Truy xuất đến các phần tử của mảng haichiều: 112
6.6 CON TRỎ VÀ CHUỖI KÍ TỰ 115
6.7 CON TRỎ HÀM 116
6.7.1 Khai báo con trỏ hàm 116
6.7.2 Gán giá trị cho con trỏ hàm 116
6.7.3 So sánh các con trỏ hàm 116
6.7.4 Gọi một hàm thông qua con trỏ hàm 117
Trang 76.7.5 Truyền con trỏ hàm như một tham số 118
6.7.6 Trả về một con trỏ hàm 119
6.7.7 Sử dụng mảng các con trỏ hàm 120
6.8 CẤP PHÁT BỘ NHỚ 121
6.8.1 Hàm malloc() 122
6.8.2 Hàm free() 127
6.8.3 Hàm calloc() 127
6.8.4 Hàm realloc() 129
CHƯƠNG 7 131
KIỂU DỮ LIỆU CẤU TRÚC 131
GIỚI THIỆU 131
7.1 KHÁI NIỆM KIỂU DỮ LIỆU CẤU TRÚC 131
7.1.1 Định nghĩa cấu trúc 132
7.1.2 Khai báo biến cấu trúc 133
7.1.3 Truy cập tới các thành phần của một cấu trúc 134
7.1.4 Khởi tạo biến cấu trúc 136
7.1.5 Phép gán đối với biến cấu trúc 137
7.1.6 Cấu trúc lồng trong cấu trúc 137
7.2 MẢNG CẤU TRÚC 139
7.2.1 Khai báo mảng cấu trúc 139
4
Trang 87.2.2 Khởi tạo mảng cấu trúc 141
7.3 CON TRỎ CẤU TRÚC 141
7.3.1 Con trỏ tới biến cấu trúc 141
7.3.2 Con trỏ và mảng cấu trúc 143
7.4 TRUYỀN THAM SỐ CẤU TRÚC CHO HÀM 145
7.4.1 Truyền biến cấu trúc vào hàm 145
7.4.2 Truyền mảng cấu trúc vào hàm 150
CHƯƠNG 8 152
QUẢN LÝ TẬP TIN 152
GIỚI THIỆU 152
8.1 KHÁI NIỆM STREAM VÀ TẬP TIN (FILE) 152
8.1.1 Stream văn bản 152
8.1.2 Stream nhị phân 152
8.2 CÁC HÀM VỀ TẬP TIN VÀ CẤU TRÚC FILE 152
8.2.1 Các hàm cơ bản về tập tin 153
8.2.2 Con trỏ tập tin 153
8.3 CÁC TẬP TIN VĂN BẢN 154
8.3.1 Mở một tập tin văn bản 154
8.3.2 Đóng một tập tin văn bản 155
8.3.3 Hàm fprintf() 155
8.3.4 Hàm fscanf() 156
8.3.5 Hàm fputc() 157
8.3.6 Hàm fgetc() 157
8.3.7 Hàm fputs() 158
8.3.8 Hàm fgets() 159
8.4 TẬP TIN NHỊ PHÂN 160
8.4.1 Mở, đóng một tập tin nhị phân 160
8.4.2 Ghi dữ liệu vào một tập tin nhị phân
Trang 9160
8.4.3 Đọc dữ liệu từ tập tin nhị phân 162
8.5 CÁC HÀM XỬ LÝ TẬP TIN 164
8.5.1 Hàm feof() 164
8.5.2 Hàm rewind() 165
8.5.3 Hàm ferror() 165
8.5.4 Hàm remove() 166
8.5.5 Hàm rename() 166
8.5.6 Hàm fflush() 167
8.5.7 Hàm ftell() 168
8.5.8 Hàm fseek() 169
8.5.9 Các stream chuẩn 170
5
Trang 10CHƯƠNG 1 NHỮNG KHÁI NIỆM CƠ BẢN VỀ NGÔN NGỮ C
Chương này trình bày các vấn đề sau:
Trong hệ điều hành UNIX, trên 90% các chương trình nguồn được viết bằng
C rất hiệu quả để viết các chương trình thuộc nhiều lĩnh vực khác nhau C cũng được dùng để lập trình hệ thống Một chương trình hệ thống có ý nghĩa liên quan đến hệ điều hành của máy tính hay những tiện ích hỗ trợ nó.C cho phép thao tác trên những thành phần cơ bản của máy tính như bits, bytes, địa chỉ… Hơn nữa,
mã C rất khả chuyển, nghĩa là phần mềm viết cho loại máy tính này có thể chạy trên một loại máy tính khác và ít bị lỗi C có năm kiểu dữ liệu cơ bản, nhưng nó không được xem ngang hàng với ngôn ngữ cao cấp về mặt kiểu dữ liệu C cho phép chuyển kiểu dữ liệu Nó cho phép thao tác trực tiếp trên bit, byte, word
Trang 11và con trỏ (pointer) Vì vậy, nó được dùng cho lập trình mức hệ thống 1.1 CÁC CHƯƠNG TRÌNH DỊCH C CƠ BẢN
Ngôn ngữ lập trình C hiện tại thường sử dụng các trình dịch sau đây:
- Turbo C/C++, Borland C/C++ của hãng Borland International Inc
- C-Free của của hãng phần mềm ProgramArts
- Dev C/C++ của hãng Bloodshed Software
- Các phần mềm mã nguồn mở Code::Blocks, Eclipse
6
Trang 12- MSC, VC của Microsoft Corp
- Lattice C của Lattice
Sau này, C++ đã được phát triển từ C, bổ sung các yếu tố về lập trình hướng đối tượng từ C
1.2 ĐẶC ĐIỂM CỦA NGÔN NGỮ C
Ngôn ngữ lập trình C có một số đặc điểm sau đây:
C là ngôn ngữ lập trình cấu trúc Tuy nhiên, C không phải là ngôn ngữ cấu
không cho phép việc tạo hàm trong hàm
C là ngôn ngữ có độ thích nghi cao Bởi các kiểu dữ liệu và cấu trúc điều
đổi về phần cứng của máy tính
C được sử dụng rộng rãi trong các lĩnh vực chuyên nghiệp vì đáp ứng được
có tính hiệu quả cao
C cung cấp những cấu trúc điều khiển như các câu lệnh lựa chọn, lệnh lặp
Pascal
C cung cấp con trỏ và khả năng định địa chỉ số học
C cho phép hàm được gọi đệ quy và các biến cục bộ của hàm sẽ được tự
hoặc được tạo mới với mỗi lần gọi mới
C tương đối thoải mái trong chuyển đổi dữ liệu
1.3 CẤU TRÚC CƠ BẢN CỦA MỘT CHƯƠNG TRÌNH C
C có chính xác là 32 từ khóa Những từ khóa này kết hợp với cú pháp của C hình thành ngôn ngữ C Nhưng nhiều trình biên dịch cho C đã thêm vào những từ khóa dùng cho việc tổ chức bộ nhớ ở những giai đoạn tiền xử lý nhất định
Một số quy tắc khi lập trình C như sau:
Tất cả từ khóa là chữ thường (không in hoa)
Ðoạn mã trong chương trình C có phân biệt chữ thường và chữ hoa Ví dụ :
khác với DO WHILE
Từ khóa không thể dùng cho các mục đích khác như đặt tên biến (variable
tên hàm (function name)
Cấu trúc cơ bản nhất của C gồm 5 phần: Phần tiền xử lý, phần khai báo các biến ngoài, các hàm nguyên mẫu, định nghĩa các hàm và phần chương trình chính Một chương trình C thông thường có dạng như sau:
#include<stdio.h> //Gọi tiền xử lý
#define // định nghĩa hằng xâu ký tự
Trang 13typedef // Định nghĩa kiểu dữ liệufunction prototype // Nguyên mẫu các hàm
int x,y; // Phần khai báo các biến ngoài
7
Trang 14void main // Chương trình chính{
Trang 15lại chứa nó trong nhiều tập tin nhỏ Khi lập trình, những hàm được chứa
có thể được dùng cho nhiều loại tác vụ khác nhau Một hàm (được viết bởi
viên) có thể được đặt trong thư viện và được dùng bởi nhiều chương trình
cầu Vài trình biên dịch cho phép hàm được thêm vào thư viện chuẩn trong
lại yêu cầu tạo một thư viện riêng
Phần khai báo các biến ngoài: Đây là khu vực các biến toàn cục, được
phần các biến ngoài của chương trình C
Khai báo các hàm nguyên mẫu: Trong Pascal chương trình con có 2 loại: thủ tục và
hàm, ở trong C chỉ có một loại chương trình con duy nhất đó là hàm Hàm trong C có
thể trả về giá trị hay không trả về giá trị Trong các hàm có sử dụng khai báo các biến
dùng trong phạm vi hàm đó
Trang 16 Phần định nghĩa các hàm: Chương trình C được chia thành từng đơn vị gọi là hàm
Tên hàm luôn được theo sau là cặp dấu ngoặc đơn () Trong dấu ngoặc đơn
Trang 17khi một chương trình C được thực thi Lệnh getch() cuối thân chương trình dùng để lưu lại trên màn hình các kết quả
Dấu kết thúc câu lệnh: Dòng int x,y; trong đoạn mã mẫu là một câu lệnh
(statement) Một câu lệnh trong C được kết thúc bằng dấu chấm phẩy (;) C không hiểu
việc xuống dòng dùng phím enter, khoảng trắng dùng phím spacebar hay một khoảng
cách do dùng phím tab Có thể có nhiều hơn một câu lệnh trên cùng một hàng nhưng
mỗi câu lệnh phải được kết thúc bằng dấu chấm phẩy Một câu lệnh không được kết
thúc bằng dấu chấm phẩy được xem như một câu lệnh sai
Dòng chú thích (Comment): Những chú thích thường được viết để mô tả công việc
của một lệnh đặc biệt, một hàm hay toàn bộ chương trình Trình biên dịch
1.4 BIÊN DỊCH VÀ THỰC THI MỘT CHƯƠNG TRÌNH
Những bước khác nhau của việc dịch một chương trình C từ mã nguồn thành
mã thực thi được thực hiện như sau :
# include file Source file
Tập tin thêm vào Chương trình gốc
Other Library File Compiler
User-generated Thư viện Trình biên dịch
Object File C
ác tậ
p tin th
ực thi kh
Trang 18a Object File
người dùng Tập tin đối tượng
Linker
Bộ liên kết
Executable File Tập tin thực thi
Soạn thảo/Xử lý từ: Lập trình viên dùng một trình xử lý từ (word processor) hay trình soạn
thảo (editor) để viết mã nguồn (source code) C chỉ chấp nhận loại mã nguồn viết dưới dạng
tập tin văn bản chuẩn Một số trình biên dịch (compiler) C căn bản đã được liệt kê trong
mục 1.1
9
Trang 19 Mã nguồn: Ðây là đoạn văn bản của chương trình mà người dùng có thể đọc
vào của trình biên dịch C
Bộ tiền xử lý C: Từ mã nguồn, bước đầu tiên là chuyển nó qua bộ tiền xử lý của C
tập tin bị thay đổi, toàn chương trình không phải biên dịch lại
Bộ liên kết (Linker): Mã đối tượng cùng với những thủ tục hỗ trợ trong thư viện chuẩn và
những hàm được dịch riêng lẻ khác kết nối lại bởi bộ liên kết để cho ra mã có thể thực thi
1 Bao nhiêu bộ nhớ sẽ được gán?
2 Mỗi đơn vị dữ liệu được lưu trữ ở đâu trong bộ nhớ?
Các ngôn ngữ lập trình hiện đại cho phép chúng ta sử dụng các tên tượng
(variable), chỉ đến một vùng bộ nhớ nơi mà các giá trị cụ thể được lưu trữ Kiểu dữ
định tổng số bộ nhớ được chỉ định Những tên được gán cho biến giúp chúng ta sử
liệu khi cần đến
Khai báo biến:
<Kiểu dữ liệu> danh sách tên các biến;
Trang 20Ví dụ:
int a; // khai báo biến a có kiểu dữ liệu là số nguyên
float b; // khai báo biến a có kiểu dữ liệu là số thực
char c; // khai báo biến a có kiểu dữ liệu là ký tự
Các kí hiệu a, b và c trong đoạn mã trên là các biến Tên biến giúp chúng ta
tránh phải nhớ địa chỉ của vị trí bộ nhớ Khi đoạn mã được viết và thực thi, hệ điều hành đảm nhiệm việc cấp không gian nhớ còn trống cho những biến này Hệ điều hành ánh xạ một tên biến đến một vị trí xác định trong bộ nhớ (ô nhớ) Để tham chiếu tới một giá trị riêng biệt trong bộ nhớ, chúng ta chỉ cần chỉ ra tên của biến
Trang 21của biến, thậm chí có thể thay đổi giá trị của biến Trong thực tế, đôi khi cần sử
khoản mục mà giá trị của chúng không bao giờ bị thay đổi Một hằng là một giá trị
bị thay đổi Chẳng hạn, 5 là một hằng số, giá trị toán học luôn là 5 và không thể bị thay đổi
Trong C, biểu diễn hằng ký tự bằng ký hiệu trong bảng mã ASCII đặt giữa
đơn ví dụ ‘A’ hoặc bằng số thứ tự của ký tự đó trong bảng mã ASCII và đặt
Ví dụ:
X, sum, m_ncount, Array10: Là những
định danh đúng 2sum, print!, #Multiple: Là
những định danh sai
Các định danh có thể có chiều dài tuỳ ý, nhưng số ký tự trong một biến được nhận diện bởi trình biên dịch thì thay đổi theo trình biên dịch Các định danh trong
C có phân biệt chữ hoa và chữ thường, cụ thể While sẽ khác while
Một số nguyên tắc cho việc chỉ đặt tên định danh
Các quy tắc đặt tên biến khác nhau tuỳ ngôn ngữ lập trình Tuy nhiên, vài quy ước chuẩn được tuân theo như :
Trang 22 Các ký tự theo sau ký tự đầu bằng một chuỗi các chữ cái hoặc con số và cũng
gồm ký tự đặc biệt như dấu gạch dưới
Tránh dùng ký tự O tại những vị trí mà có thể gây lầm lẫn với số không (0) và
cái l (chữ thường của chữ hoa L) có thể lầm lẫn với số 1
Tên riêng nên tránh đặt tên cho biến
11
Trang 23 Theo tiêu chuẩn C các chữ cái thường và hoa thì xem như khác nhau chẳng hạn,
add và Add là khác nhau
Việc phân biệt chữ hoa và chữ thường khác nhau tuỳ theo ngôn ngữ lập trình
nhất nên đặt tên cho biến theo cách thức chuẩn
Tên một biến nên có ý nghĩa, gợi tả và mô tả rõ kiểu dữ liệu của nó Ví dụ, nếu tìm tổng
của hai số thì tên biến lưu trữ tổng nên đặt là sum (tổng) Nếu đặt tên là s hay ab12 thì
không hay lắm
1.5.4 Từ khóa (Keywords)
Tất cả các ngôn ngữ dành một số từ nhất định cho mục đích riêng được gọi là
“từ khóa” Những từ này được sử dụng mặc định và có một ý nghĩa đặc biệt trong ngữ cảnh của từng ngôn ngữ Khi đặt tên cho các biến, chúng ta cần bảo đảm rằng không dùng bất cứ từ khóa nào làm tên biến C định nghĩa 32 từ khoá sau đây:
Bảng 1.1: Từ khóa trong C
Ngoài một số từ khoá dùng để khai báo các kiểu dữ liệu như long, int, double, float, còn có các từ khoá của các câu lệnh như if, for, while,
1.6 CÁC KIỂU DỮ LIỆU CƠ SỞ VÀ DẪN XUẤT
Kiểu dữ liệu thường được dùng trong các công cụ lập trình có thể được
phân chia thành: Kiểu dữ liệu số - lưu trữ giá trị số
Kiểu dữ liệu ký tự - lưu trữ thông tin mô tả
Những kiểu dữ liệu này có thể có tên khác nhau trong các ngôn ngữ lập trình khác nhau Ví dụ, một kiểu dữ liệu số được gọi trong C là int trong khi đó với Pascal được gọi là integer Tương tự, một kiểu dữ liệu ký tự được đặt tên là char[ ] trong C trong khi đó trong Visual Basic nó được đặt tên là string Trong bất cứ trường hợp nào, các dữ liệu được lưu trữ luôn giống nhau Ðiểm khác duy nhất là các biến được dùng trong một công cụ phải được khai báo theo tên của kiểu dữ liệu được hỗ trợ bởi chính công cụ đó
1.6.1 Những kiểu dữ liệu cơ sở
C có 5 kiểu dữ liệu cơ bản là int, float, double, character và void Tất cả những kiểu dữ liệu khác dựa vào một trong số những kiểu này
Kiểu dữ liệu int
Là kiểu dữ liệu lưu trữ dữ liệu số nguyên và là một trong những kiểu dữ liệu cơ
Trang 24con số
Trong C, để lưu trữ một giá trị số nguyên trong một biến tên là num1, ta khai
báo như sau: int num1;
12
Trang 25Kích thước của kiểu dữ liệu int được xác định tùy thuộc vào hệ điều hành Cụ thể, với hệ điều hành 16 bit (MS-DOS), mỗi biến được khái báo kiểu int sẽ được cấp phát 16 bit (2 byte) bộ nhớ, cho phép lưu trữ các số nguyên trong phạm vi -32768 tới 32767 Với hệ điều hành 32 bit (Windows 9x/2000/NT/XP), kiểu dữ liệu này có kích thước 4 byte, cho phép lưu trữ các số nguyên trong phạm vi -2147483648 tới 2147483647
Kiểu dữ liệu float
Một biến có kiểu dữ liệu số thực được dùng để lưu trữ các giá trị chứa phần
Trong C, để lưu trữ một giá trị float trong một biến tên gọi là num2, việc khai
báo như sau: float num2;
Biến đã khai báo là kiểu dữ liệu float có thể lưu giá trị thập phân có độ chính xác tới 6 con số Biến này được cấp phát 32 bit (4 byte) của bộ nhớ
Kiểu dữ liệu double
Kiểu dữ liệu double được dùng khi giá trị được lưu trữ vượt quá giới hạn về dung lượng của kiểu dữ liệu float Biến có kiểu dữ liệu là double có thể lưu trữ nhiều hơn khoảng hai lần số các chữ số của kiểu float Số các chữ số chính xác mà kiểu dữ liệu float hoặcdouble có thể lưu trữ tùy thuộc vào hệ điều hành cụ thể của máy tính
Các con số được lưu trữ trong kiểu dữ liệu float haydouble được xem như
thống tính toán Tuy nhiên, sử dụng kiểu dữ liệu float tiết kiệm bộ nhớ một nửa so
liệu double
Trong C, để lưu trữ một giá trị double trong một biến có tên là num3, sẽ
như sau :
float num3;
Kiểu dữ liệu double cho phép độ chính xác cao hơn (tới 10 con số) Một biến khai báo kiểu dữ liệu double chiếm 64 bit (8 byte) trong bộ nhớ
Kiểu dữ liệu char
Kiểu dữ liệu char chiếm 1 byte bộ nhớ và được dùng để lưu trữ một ký tự đơn Một kiểu dữ liệu char có thể lưu một ký tự đơn được bao đóng trong hai dấu nháy đơn (‘’) Ví dụ kiểu dữ liệu char như: ‘a’, ‘m’, ‘$’ ‘%’
Có thể lưu trữ những chữ số như những ký tự bằng cách bao chúng bên trong cặp dấu nháy đơn Không nên nhầm lẫn chúng với những giá trị số Ví dụ, ‘1’,
‘5’ và ‘9’ sẽ không được nhầm lẫn với những số 1, 5 và 9
Kiểu dữ liệu void
C có một kiểu dữ liệu đặc biệt gọi là void Kiểu dữ liệu này chỉ cho trình biên dịch C biết rằng không có dữ liệu của bất cứ kiểu nào Trong C, các hàm số
Trang 26gì để trả về, kiểu dữ liệu void được sử dụng để chỉ ra điều này
Dung lượng nhớ và phạm vi giá trị của những kiểu này thay đổi theo mỗi loại
bộ xử lý và việc cài đặt các trình biên dịch C khác nhau
13
Trang 271.6.2 Những kiểu dữ liệu dẫn xuất
Các kiểu dữ liệu cơ bản (char, int, float và double) mà chúng ta đã thảo luận ở trên được sử dụng cho việc trình bày dữ liệu thực sự trong bộ nhớ của máy tính Những kiểu dữ liệu này có thể được sửa đổi sao cho phù hợp với những tình huống khác nhau một cách chính xác Kết quả, chúng ta có được các kiểu dữ liệu dẫn xuất từ những kiểu cơ bản này
Một bổ từ (modifier) được sử dụng để thay đổi kiểu dữ liệu cơ bản nhằm phù hợp với các tình huống đa dạng Ngoại trừ kiểu void, tất cả các kiểu dữ liệu khác
có thể cho phép những bổ từ đứng trước chúng Bổ từ được sử dụng với C là signed, unsigned, long và short Tất cả chúng có thể được áp dụng cho dữ liệu kiểu ký tự và kiểu số nguyên Bổ từ long cũng có thể được áp dụng cho double.Ðể khai báo một biến kiểu dẫn xuất, chúng ta cần đặt trước khai báo biến thông thường một trong những từ khóa của bổ từ
Các kiểu có dấu (signed) và không dấu(unsigned)
Khi khai báo một số nguyên, mặc định đó là một số nguyên có dấu Tính quan
Với việc thêm từ unsigned vào trước kiểu dữ liệu int, miền giá trị cho những
số dương có thể được tăng lên gấp đôi Chẳng hạn, với lệnh khai báo và gán giá trị cho biến như sau:
unsigned int x = 35650;
Không gian cấp phát cho kiểu biến này vẫn giữ nguyên Nghĩa là, biến x được
cấp phát 2 byte như khi nó dùng kiểu int Tuy nhiên, những giá trị mà một kiểu unsgned int hỗ trợ sẽ nằm trong khoảng từ 0 đến 65535, thay vì là -32768 tới
32767 mà kiểu int hỗ trợ Theo mặc định, int là một kiểu dữ liệu có dấu
Các kiểu long và short
Chúng được sử dụng khi một số nguyên có chiều dài ngắn hơn hoặc dài hơn chiều dài bình thường Một bổ từ short được áp dụng cho kiểu dữ liệu khi chiều dài yêu cầu ngắn hơn chiều dài số nguyên bình thường và một bổ từ long được dùng khi chiều dài yêu cầu dài hơn chiều dài số nguyên bình thường
Bổ từ short được sử dụng với kiểu dữ liệu int Nó sửa đổi kiểu dữ liệu int theo hướng chiếm ít vị trí bộ nhớ hơn Bởi vậy, trong khi một biến kiểu int chiếm giữ 16 bit (2 byte) thì một biến kiểu short int (hoặc chỉ là short), chiếm giữ 8 bit (1 byte) và cho phép những số có trong phạm vi từ -128 tới 127
Bổ từ long được sử dụng tương ứng một miền giá trị rộng hơn Nó có thể được
sử dụng với int cũng như với kiểu dữ liệu double Khi được sử dụng với kiểu dữ liệu int, biến chấp nhận những giá trị số trong khoảng từ -2,147,483,648 đến 2,147,483,647 và chiếm giữ 32 bit (4 byte) Tương tự, kiểu long double của một
Trang 28Một biến long int được khai báo như sau:
long int num;
Nó cũng có thể được khai báo đơn giản như long num Một số long integer có thể được khai báo như long int hay chỉ là long Tương tự, ta có short int hay short Bảng 1.2trình bày phạm vi giá trị cho các kiểu dữ liệu khác nhau và số bit nó chiếm giữ dựa theo tiêu chuẩn ANSI
14 Kiểu Dung lượng xấp xỉ
signed int 16 Giống như kiểu int
unsigned short int 16 0 tới 65, 535
signed short int 16 Giống như kiểu short int
long int 32 -2,147,483,648 tới 2,147,483,647 signed long int 32 Giống như kiểu long int
unsigned long int 32 0 tới 4,294,967,295
long double 128 10 con số thập phân
Bảng 1.2: Các kiểu dữ liệu và phạm vi
Chương trình sau đây trình bày cách khai báo những kiểu dữ liệu trên
char c; /* c là biến kiểu char */
int x; /* x là biến kieur
float y;/* y là biến kiểu float */
double z; /* z là biến kiểu double */
long l; /* l là biến kiểu long int */
short t;/* t là biến kiểu short
}
1.7 NHẬP VÀ XUẤT TRONG C
Trong bất kỳ ngôn ngữ lập trình nào, việc nhập giá trị cho các biến và in chúng
ra sau khi xử lý có thể được làm theo hai cách:
1 Thông qua phương tiện nhập/xuất chuẩn (I / O)
2 Thông qua những tập tin
Trang 29Trong phần này ta sẽ nói về chức năng nhập và xuất cơ bản Nhập và xuất (I/O) luôn là các thành phần quan trọng của bất kỳ chương trình nào Ðể tạo tính hữu ích, chương trình của bạn cần có khả năng nhập dữ liệu vào và hiển thị lại những kết quả của nó
Trong C, thư viện chuẩn cung cấp những thủ tục cho việc nhập và xuất Thư
Trang 30trên đĩa hay trên bất cứ thiết bị lưu trữ nào khác Dữ liệu đầu ra cũng có thể được
Hàm printf() được sử dụng để xuất dữ liệu ra màn hình Nguyên mẫu của hàm là:
printf ( <Chuỗi định dạng>, Danh sách giá trị );
Trong đó chuỗi định dạng là phần xâu ký tự định dạng cách thức hiển thị theo chuẩn ra
màn hình Phần danh sách giá trị thường được cách nhau bởi dấu phẩy Do đó C cung cấp các
kiểu định dạng dành riêng cho mỗi kiểu dữ liệu khác nhau (xem Bảng 1.3)
Chuỗi định dạng Kiểu dữ liệu Đối số có dạng
%X int Số nguyên hệ 16 bắt đầu từ chữ cái A,B,C
%e,%E float,double Dạng thập phân dấu chấm động
%f,%lf float, Dạng thập phân dấu chấm tĩnh
%g,%G double Hai loại thập phân dấu chấm tĩnh và động
Trang 31ký tự:
printf (“Hello!”);
Nếu ta sử dụng xuất ra nhiều biến với nhiều kiểu dữ liệu khác nhau trên một hàng hoặc trên nhiều hàng, thì đối với một loại biến khác nhau, xuất ra ở vị trí nào trong chuỗi thì phải định dạng kiểu dữ liệu cho loại biến đó tương ứng với vị trí xuất ra
Chương trình sau đây sẽ khai báo, nhập giá trị cho một số nguyên và một số thực, sau khi hiển thị giá trị của chúng ra màn hình
16
Trang 32Chú ý : Để thuận tiện cho việc trình bày, từ đây về sau kí hiệu (enter) sẽ được
sử dụng để biểu thị việc xuống dòng, kết thúc một thao tác nhập liệu từ bàn phím 1.7.2 Cách xuất dữ liệu dạng có quy cách
Các lệnh định dạng có thể có bổ từ (modifier), để thay đổi các đặc tả chuyển
đổi gốc Sau đây là các bổ từ được chấp nhận trong câu lệnh printf() Nếu có
nhiều bổ từ được dùng thì chúng tuân theo trình tự sau:
Bổ từ ‘-’
Dữ liệu sẽ được canh trái bên trong không gian dành cho nó, chúng sẽ được in bắt đầu từ vị trí ngoài cùng bên trái
Bổ từ xác định độ rộng
Chúng có thể được dùng với kiểu: float, double hay char array (chuỗi-string)
Bổ từ xác định độ rộng là một số nguyên xác định độ rộng nhỏ nhất của trường dữ liệu Các dữ liệu có độ rộng nhỏ hơn sẽ cho kết quả canh phải trong trường dữ liệu Các dữ liệu có kích thước lớn hơn sẽ được in bằng cách dùng thêm những vị trí cho
đủ yêu cầu.Ví dụ, %10f là lệnh định dạng cho các mục dữ liệu kiểu số thực với độ rộng trường dữ liệu thấp nhất là 10
Bổ từ xác định độ chính xác
Chúng có thể được dùng với kiểu float,double hay mảng ký tự Bổ từ xác định
độ rộng chính xác được viết dưới dạng m với m là một số nguyên Nếu sử dụng với
kiểu float và double, chuỗi số chỉ ra số con số tối đa có thể được in ra phía bên phải dấu chấm thập phân
Nếu phần phân số của các mục dữ liệu kiểu floathaydouble vượt quá độ rộng
Trang 33 Bổ từ ‘l’
17
Trang 34Bổ từ này có thể được dùng để hiển thị số nguyên như: long int hay một
tham số kiểu double Mã định dạng tương ứng cho nó là %ld
Bổ từ ‘h’
Bổ từ này được dùng để hiển thị kiểu short int Mã định dạng tương ứng cho
nó là %hd Bổ từ ‘*’
Bổ từ này được dùng khi người dùng không muốn chỉ trước độ rộng của trường
mà muốn chương trình xác định nó Nhưng khi đi với bổ từ này, một tham số được yêu cầu phải chỉ ra độ rộng trường cụ thể
Chương trình sau đây sẽ khai báo, gán giá trị cho 2 số nguyên (int) và 2 số thực (float), sau đó in ra màn hình giá trị của chúng theo các quy cách định dạng khác nhau
Để nhập dữ liệu C cung cấp hàm scanf(), với nguyên
mẫu như sau:
scanf ( <Chuỗi định dạng>, &Tên biến );
Tương tự như với hàm printf(), hàm scanf() khi nhập dữ liệu ta vẫn phải định dạng kiểu dữ liệu của biến Ví dụ, khi nhập dữ liệu cho biến kiểu nguyên, ta phải định dạng biến kiểu nguyên là %d C cung cấp các định dạng cho biến trong hàm scanf() sau đây:
Định dạng Ý nghĩa
Trang 35%c Nhập ký tự
%ld Nhập số nguyên kiểu longint
%lf Nhập số nguyên kiểu double
18
Trang 36Bảng 1.4: Chuỗi định dạng khi nhập dữ liệu
Chương trình sau đây cho phép người dùng nhập vào các số nguyên và số thực sau đó hiển thị giá trị của chúng ra màn hình
Trang 370
0
1.7.4 Bộ nhớ đệm Nhập và Xuất (Buffered I/O)
Ngôn ngữ C bản thân nó không định nghĩa các thao tác nhập và xuất Tất cả thao tác nhập và xuất được thực hiện bởi các hàm có sẵn trong thư viện hàm của C,
đó là bộ nhớ đệm Nhập và Xuất - được dùng để đọc và viết các ký tự ASCII Một vùng đệm là nơi lưu trữ tạm thời, nằm trên bộ nhớ máy tính hoặc trên thẻ nhớ của bộ điều khiển thiết bị (controller card) Các ký tự nhập vào từ bàn phím
được đưa vào bộ nhớ và đợi đến khi người dùng nhấn phím return hay enter thì
chúng sẽ được thu nhận như một khối và cung cấp cho chương trình
Trang 38Nó đơn giản lấy về ký tự tiếp theo và sẵn sàng đưa ra cho chương trình Chúng
ta nói rằng hàm này trả về một giá trị có kiểu ký tự
Entered character is: T
Hàm putchar(): Là hàm xuất ký tự trong C, nó sẽ xuất một ký tự lên màn hình tại vị trí
con trỏ màn hình Hàm này yêu cầu một tham số Tham số của hàm putchar()
c = getchar(); /*Nhập giá trị cho biến kí tự c*/
putchar(c); /*Hiển thị nội dung biến kí tự c*/ putchar (‘B’); /*Hiển thị kí tự B*/
putchar(‘9’); /*Hiển thị con số 9*/
putchar(‘\t’); /*Chèn một khoảng tab*/
putchar(‘\n’); /*Dấu xuống dòng*/
}
1.8 SỬ DỤNG TRÌNH BIÊN DỊCH DEV-C/C++
Dev-C/C++ là một môi trường phát triển được tích hợp đầy đủ các tính năng, nó có khả năng tạo ra các chương trình C/C++ dựa trên Window hoặc DOS bằng cách sử dụng hệ thống biên dịch Mingw hoặc Cygwin Dev-C/C++ có ưu điểm đơn giản, gọn nhẹ, chạy trên môi trường window nhưng có nhược điểm là phần trợ giúp (help) không đầy đủ, các chế độ debug chương trình không thuận tiện
Để bắt đầu, click vào biểu tượng Dev-C/C++ trên máy tính, một cửa sổ
Trang 39chương trình sẽ được mở ra như trên Hình 1.2 Trên cửa sổ này bao gồm các thanh menu chính như sau:
File,chứa các chức năng cơ bản như: New(tạo một file mã nguồn hoặc một project
mới), Open Project or File (mở một project hoặc một file đã có),
Reopen(mở lại các
file mã nguồn đã được mở trước đó), Save (lưu file mã nguồn), Save as (lưu file mã
20
Trang 40nguồn với tên khác), Save All (lưu tất cả các file đang được mở), Close(đóng file đang làm việc), Close All (đóng tất cả các file đang mở) Project là một khái niệm mở rộng của C trong C++, sẽ không được đề cập đến trong giáo trình này
Edit: Là thanh menu chứa các chức năng phục vụ cho quá trình soạn thảo file mã
nguồn, chẳng hạn như Undo (bỏ qua thao tác vừa thực hiện), Redo(thực hiện lại thao
tác vừa bị bỏ qua), Cut(cắt đi một đoạn mã), Copy(sao chép một đoạn mã ), Paste(dán
một đoạn mã)
Search: Chứa các chức năng tìm kiếm hoặc thay thế các đoạn mã trong một
trình nguồn như Find, Find in Files, Replace, v.v
View:Chứa các chức năng hiển thị tùy chọnnhư Project/Class Browser (hiển thị thông
tin project/class), Statusbar (hiển thị thanh trạng thái),Toolbars (hiển thị các thanh
tin đã được biên dịch), Program Reset (thiết lập lại chương trình)
Debug:Chứa các chức năng gỡ lỗi (debug) cho chương trình như
Debug,Next Step
(chạy đến dòng lệnh tiếp theo),Step Info (chạy lần bước), thực thi tiếp chương trình bỏ
qua bước debug
Tools: Chứa các chức năng tùy chọn cơ bản như tùy chọn biên dịch (Compiler
Options), tùy chọn môi trường (Environment Options), tùy chọn soạn thảo (Editer
Options)