8 BÀI 1: CÁC THÀNH PHẦN CƠ BẢN CỦA NGÔN NGỮ LẬP TRÌNH MỤC TIÊU Học xong bài này sinh viên có khả năng: o Trình bày được cấu trúc chung của một chương trình và các thành phần cơ bản c
Trang 1KHOA CÔNG NGHỆ THÔNG TIN
ĐỀ CƯƠNG
CƠ SỞ KỸ THUẬT LẬP TRÌNH
HƯNG YÊN – 2015
Trang 2MỤC LỤC 2
BÀI 1: CÁC THÀNH PHẦN CƠ BẢN CỦA NGÔN NGỮ LẬP TRÌNH 8
1.1 Cấu trúc chung của một chương trình 8
1.1.1 Cấu trúc của một chương trình 8
1.1.2 Các bước để tạo và thực hiện một chương trình 9
1.1.3 Một số quy tắc cần nhớ khi viết chương trình 11
1.2 Các thành phần cơ bản của một ngôn ngữ lập trình 12
1.2.1 Bảng chữ cái 12
1.2.2 Từ khóa 12
1.2.3 Tên (định danh) 13
1.3 Các kiểu dữ liệu cơ bản 14
1.3.1 Kiểu ký tự 15
1.3.2 Kiểu số nguyên 16
1.3.3 Kiểu dấu phẩy động 16
1.4 Biến, hằng và cách khai báo 17
1.4.1 Biến và cách khai báo 17
1.4.2 Hằng và cách khai báo 18
BÀI 2: BIỂU THỨC, CÁC PHÉP TOÁN VÀ VẤN ĐỀ NHẬP XUẤT 22
2.1 Biểu thức 22
2.2 Câu lệnh, khối lệnh 22
2.2.1 Câu lệnh 22
2.2.2 Các câu lệnh và các khoảng trắng 23
2.2.3 Khối lệnh 24
2.3 Các phép toán 24
Trang 33
2.3.1 Các phép toán số học 24
2.3.2 Phép toán so sánh 25
2.3.3 Phép toán logic 25
2.3.4 Phép gán 26
2.3.5 Thứ tự ưu tiên các phép toán 26
2.3.6 Phép chuyển đối kiểu 27
2.4 Nhập/xuất dữ liệu 30
2.4.1 Xuất dữ liệu 30
2.4.2 Nhập dữ liệu 32
2.5 Bài tập 33
BÀI 3: CẤU TRÚC ĐIỀU KHIỂN 35
3.1 Giới thiệu về cấu trúc điều khiển 35
3.2 Cấu trúc điều khiển rẽ nhánh if 35
3.2.1 Cấu trúc rẽ nhánh dạng khuyết 35
3.2.2 Cấu trúc rẽ nhánh dạng đủ 36
3.3 Cấu trúc điều khiển rẽ nhánh swicth 38
3.4 Bài tập 41
BÀI 4: CẤU TRÚC LẶP 43
4.1 Giới thiệu về cấu trúc lặp 43
4.2 Cấu trúc lặp xác định 43
4.2.1 Cấu trúc lặp For 43
4.1.2 Ví dụ áp dụng 45
4.3 Cấu trúc lặp không xác định 46
4.3.1 Cấu trúc lặp while 46
Trang 44
4.3.2 Cấu trúc lặp do while 49
4.4 Các câu lệnh đặc biệt 52
4.4.1 Câu lệnh break 52
4.4.2 Câu lệnh continue 53
4.5 Bài tập 53
BÀI 5: THẢO LUẬN/BÀI TẬP VỀ CÁC CẤU TRÚC LẶP VÀ CẤU TRÚC ĐIỀU KHIỂN 55 BÀI 6: MẢNG MỘT CHIỀU 59
6.1 Giới thiệu về mảng một chiều 59
6.1.1 Khái niệm về mảng một chiều 60
6.1.2 Cách khai báo 60
6.1.3 Đặc điểm của mảng một chiều 61
6.1.4 Cách khởi tạo phần tử cho mảng 62
6.2 Truy xuất các phần tử trong mảng 62
6.3 Các thao tác với mảng một chiều 63
6.3.1 Nhập mảng 63
6.3.2 Hiện mảng 64
6.2 Ví dụ áp dụng 65
BÀI 7: THỰC HÀNH VỀ CẤU TRÚC ĐIỀU KHIỂN VÀ CẤU TRÚC LẶP 72 BÀI 8: MẢNG HAI CHIỀU 73
8.1 Giới thiệu về mảng hai chiều 73
8.1.1 Định nghĩa 73
8.1.2 Các cách khai báo 74
8.2 Truy xuất các phần tử trong mảng hai chiều 75
8.3 Các thao tác với mảng hai chiều 76
Trang 55
8.3.1 Nhập mảng 76
8.3.2 Hiện mảng 77
8.4 Một số ví dụ về mảng hai chiều 79
BÀI 9: THỰC HÀNH VỀ MẢNG (BUỔI 1) 82
BÀI 10: THẢO LUẬN/BÀI TẬP VỀ MẢNG 83
BÀI 11: THỰC HÀNH VỀ MẢNG (BUỔI 2) 86
BÀI 12: THAO TÁC VỚI KÝ TỰ VÀ XÂU KÝ TỰ 87
12.1 Giới thiệu về ký tự và xâu ký tự 87
12.1.1 Sử dụng các biến ký tự 88
12.1.2 Mảng của các ký tự 89
12.1.3 Khởi tạo các mảng ký tự 90
12.2 Các thao tác trên xâu 90
12.2.1 Nhập xâu 90
12.2.2 Hiển thị xâu và các ký tự 93
12.2.3 Một số thư viện hàm sử dụng trên xâu 95
12.3 Bài tập 96
BÀI 13: THỰC HÀNH VỀ XỬ LÝ CHUỖI KÝ TỰ 98
BÀI 14: KIỂU CẤU TRÚC VÀ TỆP 100
14.1 Giới thiệu về kiểu cấu trúc 100
14.2 Các thao tác trên biến cấu trúc 101
14.3 Mảng cấu trúc 102
14.4 Vấn đề vào/ra dữ liệu với tệp 102
14.4.1 Khai báo sử dụng tệp: 103
14.4.2 Mở tệp - hàm fopen 103
Trang 66
14.4.3 Đóng tệp - hàm fclose 104
14.4.4 Làm sạch vùng đệm - hàm fflush 105
14.4.5 Đọc/ghi tệp tin – hàm fprintf() và fscanf() 105
14.5 Bài tập 106
BÀI 15: THẢO LUẬN/ BÀI TẬP VỀ KIỂU CẤU TRÚC VÀ TỆP 108
BÀI 16: THỰC HÀNH VỀ KIỂU CẤU TRÚC VÀ TỆP 111
BÀI 17: HÀM (2 BUỔI) 112
17.1 Giới thiệu chung về hàm 112
17.2 Cơ bản về hàm 114
17.2.1 Định nghĩa 114
17.2.2 Cấu trúc của một hàm tự xây dựng như sau: 115
17.2.3 Nguyên tắc xây dựng một hàm 119
17.3 Các khái niệm 120
17.3.1 Biến cục bộ 120
17.3.2 Biến toàn cục 120
17.3.3 Tham số hình thức 120
17.3.4 Tham số thực thụ 121
17.4 Cách gọi hàm 121
17.4.1 Lời gọi hàm 121
17.4.2 Truyền tham số cho hàm 122
17.4.3 Đệ qui 122
17.5 Nguyên tắc hoạt động của hàm 124
17.6 Cấu trúc của một chương trình có nhiều hàm 124
17.7 Bài tập về hàm 125
Trang 77
BÀI 18: THẢO LUẬN/BÀI TẬP VỀ HÀM 127
BÀI 19: THỰC HÀNH VỀ HÀM 129
BÀI 20: CON TRỎ VÀ ỨNG DỤNG 130
20.1 Giới thiệu về con trỏ 130
20.2 Khai báo và sử dụng con trỏ 130
20.2.1 Khai báo con trỏ 130
20.2.2 Sử dụng con trỏ 131
20.3 Một số ứng dụng của con trỏ 133
20.3.1 Con trỏ và mảng một chiều 133
20.3.2 Con trỏ và mảng hai chiều 135
20.3.3 Con trỏ và xâu ký tự 136
BÀI 21: THỰC HÀNH VỀ CON TRỎ 137
BÀI 22: THẢO LUẬN/BÀI TẬP VỀ CON TRỎ 138
BÀI 23: KIỂM TRA THỰC HÀNH 145
Trang 88
BÀI 1: CÁC THÀNH PHẦN CƠ BẢN CỦA NGÔN
NGỮ LẬP TRÌNH
MỤC TIÊU
Học xong bài này sinh viên có khả năng:
o Trình bày được cấu trúc chung của một chương trình và các thành phần cơ bản của ngôn ngữ lập trình;
o Trình bày được đặc điểm, cách sử dụng của các kiểu dữ liệu;
o Trình bày được quy tắc khai báo biến, hằng;
o Sử dụng được các phép toán cơ bản vào bài toán cụ thể;
o Rèn luyện tính tư duy, logic trong lập trình
1.1 Cấu trúc chung của một chương trình
Ngôn ngữ lập trình là một hệ thống được ký hiệu hóa để miêu tả những tính toán (qua máy tính) dưới dạng mà cả con người và máy đều có thể đọc và hiểu được
Như vậy, theo định nghĩa ở trên thì một ngôn ngữ lập trình phải thỏa mãn được hai điều kiện cơ bản sau:
- Dễ hiểu và dễ sử dụng đối với người lập trình, để có thể dùng để giải quyết nhiều bài toán khác nhau
- Miêu tả một cách đầy đủ và rõ ràng các tiến trình, để chạy được trên các hệ máy tính khác nhau
Một tập hợp các chỉ thị được biểu thị qua ngôn ngữ lập trình nhằm mục đích thực hiện các thao tác nào đó được gọi là một chương trình Khái niệm này còn có những tên khác như chương trình máy tính hay chương trình điện toán
1.1.1 Cấu trúc của một chương trình
Cấu trúc chung của một chương trình gồm những thành phần chính như sau:
Trang 99
Để có cái nhìn tổng quan về cấu trúc của một chương trình, hãy xét ví dụ về chương trình hiện lên dòng chữ “Hello World” trên màn hình Trong giới lập trình, chương trình “Hello World” không quá xa lạ gì, vì đó được xem là một chương trình đầu tiên và chuẩn nhất cho cái nhìn bao quát về một ngôn ngữ nào đó được đề cập đến Nhưng nếu bạn chưa biết gì về lập trình thì cũng nên biết về chương trình này, và sau này nếu có muốn học một ngôn ngữ khác thì bạn vẫn có thể tìm kiếm một “Hello World” khác để biết ngôn ngữ đó khai báo như thế nào? bắt đầu ra sao? có khác gì so với ngôn ngữ mà mình đã biết hay không Và để có câu trả lời, hãy cùng theo dõi ví dụ sau Ví dụ được minh họa trên ngôn ngữ lập trình C:
1.1.2 Các bước để tạo và thực hiện một chương trình
Trước khi viết và chạy một chương trình thông thường chúng ta cần:
1 Xác định yêu cầu của chương trình: Nghĩa là xác định dữ liệu đầu vào (input) cung cấp cho chương trình và tập các dữ liệu cần đạt được - tức đầu ra (output) Các tập hợp dữ liệu này ngoài các tên gọi còn cần xác định kiểu của nó Ví dụ để giải một
#include <stdio.h> /* Lời gọi thư viện Nhập xuất */
#include <conio.h> /* Lời gọi thư viện xử lý màn hình */
int main() /* Hàm chính(bắt buộc có) của chương trình*/ {
printf("Hello World!"); /* Xuất ra màn hình dòng chữ Hello World!*/
getch(); /* Đợi người dùng nhập vào 1 phím bất
kỳ rồi mới tiếp tục… */
return 0; /* Kết thúc hàm*/
}
1 Lời gọi các thư viện sẽ sử dụng trong chương trình
2 Khai báo hằng, biến toàn cục
3 Khai báo chương trình con
4 Chương trình chính
Trang 1010
phương trình bậc 2 dạng: ax2
+ bx + c = 0, cần báo cho chương trình biết dữ liệu đầu vào là a, b, c và đầu ra là nghiệm x1 và x2 của phương trình Kiểu của a, b, c, x1, x2 là các số thực
2 Xác định thuật toán giải
3 Cụ thể hoá các khai báo kiểu và thuật toán thành dãy các lệnh, tức viết thành chương trình thông thường là trên giấy, sau đó bắt đầu soạn thảo vào trong máy Quá trình này được gọi là soạn thảo chương trình nguồn
4 Dịch chương trình nguồn để tìm và sửa các lỗi gọi là lỗi cú pháp
5 Chạy chương trình, kiểm tra kết quả in ra trên màn hình Nếu sai, sửa lại chương trình, dịch và chạy lại để kiểm tra Quá trình này được thực hiện lặp đi lặp lại cho đến khi chương trình chạy tốt theo yêu cầu đề ra của lập trình
Soạn thảo chương trình nguồn là một công việc đơn giản: gõ nội dung của chương trình (đã viết ra giấy) vào trong máy và lưu lại nó lên đĩa Thông thường khi
đã lưu lại chương trình lên đĩa lần sau sẽ không cần phải gõ lại Mục đích của soạn thảo là tạo ra một văn bản chương trình và đưa vào bộ nhớ của máy Văn bản chương trình cần được trình bày sáng sủa, rõ ràng Các câu lệnh cần gióng thẳng cột theo cấu trúc của lệnh (các lệnh chứa trong một lệnh cấu trúc được trình bày thụt vào trong so với điểm bắt đầu của lệnh) Các chú thích nên ghi ngắn gọn, rõ nghĩa và phù hợp
Sau khi đã soạn thảo xong chương trình nguồn, bước tiếp theo thường là dịch (trong C ấn phím F11 hoặc chọn Build/ compile) để tìm và sửa các lỗi gọi là lỗi cú pháp Trong khi dịch chương trình sẽ đưa ra thông báo lỗi và chỉ ra nơi gây lỗi Để chương trình có thể chạy được thì người lập trình phải sửa hết những lỗi đó Quá trình dịch và sửa lỗi cứ diễn ra cho đến khi nào chương trình không còn lỗi và đưa ra thông báo dịch thành công Sản phẩm sau khi dịch là một tệp mới gọi là chương trình đích có đuôi EXE tức là tệp mã máy để thực hiện Tệp này có thể lưu tạm thời trong bộ nhớ phục vụ cho quá trình chạy chương trình hoặc lưu lại trên đĩa tuỳ theo tuỳ chọn khi dịch của lập trình
Trang 1111
Để chạy chương trình, trong C ấn phím F5 hoặc chọn Build/ Run, nếu chương trình chưa dịch sang mã máy, máy sẽ tự động dịch lại trước khi chạy Kết quả của chương trình sẽ hiện ra trong một cửa sổ kết quả để người lập trình kiểm tra Nếu kết quả chưa được như mong muốn thì quay lại văn bản để sửa và lại chạy lại chương trình Quá trình này được lặp lại cho đến khi chương trình chạy đúng như yêu cầu đã
đề ra Khi chương trình chạy, cửa sổ kết quả sẽ hiện ra tạm thời che khuất cửa sổ soạn thảo Sau khi kết thúc chạy chương trình cửa sổ soạn thảo sẽ tự động hiện ra trở lại và che khuất cửa sổ kết quả
1.1.3 Một số quy tắc cần nhớ khi viết chương trình
Mỗi câu lệnh có thể viết trên một hay nhiều dòng nhưng phải kết thúc bằng dấu chấm phẩy (;)
Có 2 cách ghi chú thích trong chương trình:
- Cách 1: Các lời giải thích cần đặt giữa các dấu /* và */ và có thể được viết:
Trên một dòng
Trên nhiều dòng
Trên phần còn lại của dòng
- Cách 2: Các lời chú thích đặt sau dấu // thường được dùng khi lời chú thích được viết trên 1 dòng
Trong chương trình, khi ta sử dụng các hàm chuẩn, ví dụ như getch() mà hàm này lại được chứa trong file conio.h trong thư mục của C, vì vậy ở đầu chương trình ta phải khai báo sử dụng:
#include <conio.h>
Trang 1226 chứ cái hoa: A, B, C,….Z
26 chữ cái thường: a,b,c,….z
10 chữ số: 0,1,2…0
Các ký hiệu toán học như: + - * / = ( )
Ký tự gạch nối: _ (chú ý phân biệt với dấu - )
Các ký hiệu đặc biệt khác như: , ; [] {} ? ! \ & | % # $ …
Dấu cách (space) thực sự là một khoảng trống để tách các từ Ví dụ HUNG YEN gồm 8 ký tự, còn HUNGYEN gồm 7 ký tự
Chú ý: Khi viết chương trình ta không được sử dụng bất kỳ ký hiệu nào khác ngoài
Trang 1313
dùng trong các kiểu dữ liệu cơ bản hay trong các dòng điều khiển Ví dụ một số từ khóa thường sử dụng trong ngôn ngữ C:
static struct switch typedef unsigned
void while
Ý nghĩa và cách sử dụng của chúng sẽ được lần lượt giới thiệu ở các mục sau Ở đây ta chỉ cần nhớ hai trường hợp:
- Không được dùng từ khóa để đặt tên cho các hằng, biến, mảng, hàm,…
- Từ khóa phải được viết bằng chữ thường Chẳng hạn, không được viết
BREAK mà phải viết là break
1.2.3 Tên (định danh)
Tên (định danh) được dùng để xác định các đối tượng khác nhau trong một chương trình Chúng ta có tên hằng, tên biến, tên mảng, tên con trỏ, tên tệp, tên nhãn,…
Trong ngôn ngữ C, khi đặt tên phải tuân thủ theo quy tắc sau:
- Không chứa dấu cách
- Không bắt đầu bằng số
- Không chứa các ký tự đặc biệt (như: % ? / + =,…)
- Không trùng với từ khóa, kiểu dữ liệu
Trang 1414
f(x); //sử dụng các dấu ngoặc tròn
int; //trùng với từ khóa
del ta; //sử dụng khoảng trống
A-1; //sử dụng dấu gạch ngang
Chú ý: Trong C, với các tên thì chữ hoa và chữ thường được xem là khác nhau,
như vậy tên HocSinh và hocsinh là khác nhau Thường dùng chữ hoa để đặt tên cho
các hằng và dùng chữ thường để đặt tên cho hầu hết các đối tượng khác như biến, hằng, mảng, hàm, cấu trúc Tuy nhiên, đây không phải là điều bắt buộc
1.3 Các kiểu dữ liệu cơ bản
Thông thường, dữ liệu hay dùng là số và chữ Tuy nhiên việc phân chia chỉ 2 loại
dữ liệu là không đủ Để dễ dàng hơn cho việc lập trình, hầu hết các ngôn ngữ lập trình đều phân chia dữ liệu thành nhiều kiểu khác nhau được gọi là các kiểu cơ bản hay chuẩn Trên cơ sở kết hợp các kiểu dữ liệu chuẩn, người sử dụng có thể tự đặt ra các kiểu dữ liệu mới để phục vụ cho chương trình giải quyết bài toán của mình Có nghĩa lúc đó mỗi đối tượng được quản lý trong chương trình sẽ là một tập hợp nhiều thông tin hơn và được tạo thành từ nhiều loại (kiểu) dữ liệu khác nhau
Tất cả các biến cần phải được khai báo trước khi sử dụng và kiểu của chúng phải được mô tả ngay khi khai báo Việc khai báo này sẽ làm chương trình quản lý các biến
dễ dàng hơn như trong việc phân bố bộ nhớ cũng như quản lý các tính toán trên biến theo nguyên tắc: chỉ có các dữ liệu cùng kiểu với nhau mới được phép làm toán với nhau Do đó, khi đề cập đến một kiểu chuẩn của một ngôn ngữ lập trình, thông thường chúng ta sẽ xét đến các yếu tố sau:
- Tên kiểu: là một từ dành riêng để chỉ định kiểu của dữ liệu
- Số byte trong bộ nhớ để lưu trữ một đơn vị dữ liệu thuộc kiểu này: Thông thường số byte này phụ thuộc vào các trình biên dịch và hệ thống máy khác nhau, ở đây ta chỉ xét đến hệ thống máy PC thông dụng hiện nay
- Miền giá trị của kiểu: Cho biết một đơn vị dữ liệu thuộc kiểu này sẽ có thể lấy giá trị trong miền nào, ví dụ nhỏ nhất và lớn nhất là bao nhiêu Hiển nhiên các giá trị này phụ thuộc vào số byte mà hệ thống máy qui định cho từng kiểu
Trang 15Trong C, có hai kiểu ký tự là signed char và unsigned char Kiểu thứ nhất biểu
diễn một số nguyên từ -128 đến 127, kiểu thứ hai có giá trị từ 0 đến 255 Bảng dưới đây cho kích cỡ và phạm vi biểu diễn của giá trị kiểu char
Kiểu Phạm vi biểu diễn Số ký tự Kích thước (byte)
- Nhóm thứ hai là các ký tự văn bản có mã từ 32 đến 126 Các ký tự này có thể đưa ra màn hình và máy in
Trang 1616
- Nhóm thứ ba là các ký tự đồ họa có mã từ 127 đến 255 Các ký tự này có thể đưa ra màn hình nhưng không in được
1.3.2 Kiểu số nguyên
Kiểu số nguyên là kiểu dữ liệu dùng để lưu các giá trị nguyên hay còn gọi là kiểu đếm được Kiểu số nguyên trong C được chia thành các kiểu dữ liệu con, mỗi kiểu có một miền giá trị khác nhau
Trong C cho phép sử dụng: số nguyên (int), số nguyên dài (long) và số nguyên không dấu (unsigned) Kích cỡ và phạm vi biểu diễn của chúng được chỉ ra trong bảng dưới đây:
Kiểu Phạm vi biểu diễn Kích thước (byte)
Có thế kết hợp nhiều tiền tố với một kiểu dữ liệu cơ sở, chẳng hạn unsigned long
int viết gọn thành unsigned long
1.3.3 Kiểu dấu phẩy động
Kiểu dấu phẩy động biểu diễn cho các số thập phân có dấu
Trong C cho phép sử dụng 3 loại giá trị dấu phẩy động là float, double và long double Kích cỡ và phạm vi biểu diễn của chúng được chỉ ra trong bảng dưới đây:
Kiểu Phạm vi biểu diễn Kích thước (byte)
float 3.4E-38 -> 3.4E+38 4
double 1.7E-308 -> 1.7E+308 8
long double 3.4E4932 -> 3.4E+4932 10
Trang 1717
Máy tính có thể lưu trữ được số kiểu float có giá trị tuyệt đối từ 3.4E-38 đến 3.4E+38 Số có giá trị tuyệt đối nhỏ hơn 3.4E-38 được xem bằng 0 Phạm vi biểu diễn của số double cũng được hiểu theo nghĩa tương tự
1.4 Biến, hằng và cách khai báo
1.4.1 Biến và cách khai báo
Một biến là một tên gọi cho một đại lượng hoặc một đối tượng nào đó Mỗi biến đều được phân bổ một địa chỉ trong bộ nhớ dùng để lưu giữ giá trị của biến Giá trị này
có thể thay đổi trong khi chương trình thực hiện Trong C, một biến chỉ có thể được sử dụng sau khi đã được khai báo Một khai báo biến cho chương trình dịch biết tên của biến và kiểu của dữ liệu mà nó lưu giữ
Khi khai báo biến, giá trị của nó mặc nhiên là không xác định Nhưng có thể bạn
sẽ muốn nó mang một giá trị xác định khi được khai báo Để làm điều đó, bạn chỉ cần
int a; /* Khai báo biến a kiểu int */
long ax, bx, cx; /* Khai báo ba biến kiểu long */
char beta, alpha; /* Khai báo hai biến kiểu char */
float x,y; /* Khai báo hai biến kiểu float */
double x,y; /* Khai báo hai biến kiểu double */
Trang 18 Vừa khai báo, vừa gán giá trị
Kiểu_dữ_liệu Tên_biến = Giá_trị_khởi_tạo;
Ví dụ 1.6:
1.4.2 Hằng và cách khai báo
Hằng cũng là một biến nhưng giá trị của hằng không thay đổi Tuy nhiên khi làm việc với một giá trị được định nghĩa là không thay đổi, ta phải đảm bảo giá trị của nó không được thay đổi trong suốt chương trình nên khi đó sử dụng biến sẽ không thích hợp Chẳng hạn, khi lập một chương trình thí nghiệm hóa học liên quan đến nhiệt độ sôi hay nhiệt độ đông của nước, chương trình cần khai báo hai biến là DoSoi và DoDong, nhưng không cho phép giá trị của hai biến này bị thay đổi hay bị gán Để ngăn việc gán giá trị khác, ta phải sử dụng biến kiểu hằng
Hằng có thể định nghĩa bằng hai cách:
Cách 1: Dùng toán tử #define nhằm định nghĩa một hằng, ký hiệu
#define <Tenhang> <Xaukytu>
int a,b,c; /* Khai báo các biến a,b,c kiểu int */
char ch; /* Khai báo biến ch kiểu char */
a=0; b=15; c=21; ch=’A’; /* Khởi tạo giá trị cho các biến */
int a=0,b=15,c=21; /* Khai báo, đồng thời khởi tạo giá trị cho các biến */
char ch=’A’;
Trang 1919
Cấu trúc này định nghĩa một hằng ký hiệu có tên <Tenhang> bằng <Xaukytu> Khi biên dịch chương trình, chương trình dịch thay thế các lần xuất hiện của
<Tenhang> bằng xâu ký tự tương ứng, ví dụ: #define MAX 100
Cách 2: const kieu_du_kieu ten_hang = gia_tri_hang;
Chú ý: Nếu là hằng kiểu long thì thêm l (hay L) vào đuôi, ví dụ: 123L, 858L
Một hằng số nguyên có giá trị vượt ra ngoài phạm vi cho phép được ngầm hiểu là hằng long
Hằng số thực
Được viết theo hai cách sau:
- Dạng thập phân gồm: Phần nguyên, dấu chấm thập phân, phần thập phân, ví dụ: 34.2 -344.122
Chú ý: Phần nguyên hay phần thập phân có thể vắng mặt nhưng dấu chấm thập
phân không được thiếu, ví dụ: 343 454
Trang 2020
Chú ý: Hằng ký tự biểu thị mã của ký tự đó trong bảng mã ASCII Do vậy một
hằng ký tự cũng có thể tham gia vào các phép toán, ví dụ: „A‟+10 có giá trị (65+10=75)
Hằng ký tự còn có thể được viết theo cách: „\c1c2c3‟
Trong đó, c1c2c3 là một số hệ 8 mà giá trị của nó chính là mã ASCII của ký tự cần biểu diễn, ví dụ: „a‟ hay „\141‟
Một số ký tự đặc biệt:
\‟ „ Dấu nháy đơn
- Là một dãy các ký tự đặt trong hay dấu nháy “ ”
- Xâu ký được lưu trữ trong một mảng ô nhớ liền nhau song còn thêm ô nhớ cuối cùng chứa mã là 0 (ký hiệu là „\0‟ )
Ví dụ 1.6: Xâu ký tự: “Nguyen Van Anh”
Được tổ chức trong bộ nhớ như sau:
N g u y e n V a n A n h \0
Chú ý: Chúng ta cần phân biệt “A” và „A‟ Trong đó “A” được chứa trong 2 byte,
còn „A‟ chỉ mất 1 byte và nó có thể tham gia tính toán trong các biểu thức
Trang 2121
TÓM TẮT
Cấu trúc chung của một chương trình
Các thành phần cơ bản của một ngôn ngữ lập trình: Bảng chữ cái, từ khóa, tên
Các kiểu dữ liệu cơ bản
Biến, hằng và cách khai báo
Trang 2222
BÀI 2: BIỂU THỨC, CÁC PHÉP TOÁN VÀ VẤN ĐỀ
NHẬP XUẤT
MỤC TIÊU
Học xong bài này sinh viên có khả năng:
o Phân biệt được câu lệnh và khối lệnh
o Sử dụng được các phép toán cơ bản trong C vào bài toán cụ thể
o Viết được câu lệnh nhập/xuất dữ liệu
o Rèn luyện tính cẩn thận và tư duy sáng tạo trong lập trình
2.1 Biểu thức
Biểu thức là một sự kết hợp giữa các phép toán và các toán hạng để diễn đạt một công thức nào đó Các toán hạng có thể là một đại lượng nào đó có giá trị như: hằng, biến hay một biểu thức con Mỗi biểu thức có một giá trị, tùy theo giá trị của biểu thức
mà có các biểu thức nguyên hay biểu thức thực Các mệnh đề logic có giá trị nguyên trong đó có giá trị khác 0 tương ứng mệnh đề đúng, còn giá trị 0 tương ứng mệnh đề sai Biểu thức được sử dụng trong: Vế phải của lệnh gán; làm tham số thực của các hàm; làm chỉ số; các câu lệnh if, for, while, do while; các biểu thức lớn hơn của các hàm; làm chỉ số; các câu lệnh if, for, while, do while; các biểu thức lớn hơn
Trong C, một biểu thức là một mệnh đề dùng để tính ra một giá trị nào đó Các biểu thức C có thể có độ phức tạp tùy ý
2.2 Câu lệnh, khối lệnh
2.2.1 Câu lệnh
Một câu lệnh là một phương hướng hành động hướng dẫn cho máy tính thực hiện một nhiệm vụ nào đó Mỗi câu lệnh được viết trên một dòng, nhưng cũng có những câu lệnh phải viết trên nhiều dòng Mỗi câu lệnh được kết thúc bằng dấu chấm phẩy (;) (trừ các chỉ thị, chẳng hạn như #include và #define) Ngăn cách này chỉ đơn giản
Trang 2323
là chỉ cho ngôn ngữ lập trình biết rằng, đã kết thúc một câu lệnh và có thể chuyển qua câu lệnh mới
Ví dụ 2.1:
char ten[30];// đây là một câu lệnh
printf(“Nhap vao ten cua ban:”);
scanf(“%s”, ten);
printf(“Chao ban%s”, ten);
2.2.2 Các câu lệnh và các khoảng trắng
Thuật ngữ khoảng trắng (whitespace) là để chỉ các dấu cách, tabs và các dòng
rỗng trong chương trình gốc Chương trình dịch C không xét đến các khoảng trắng Khi chương trình dịch đọc một câu lệnh trong một chương trình gốc, nó sẽ đọc tất cả các ký tự trong câu lệnh này cho đến khi gặp dấu chấm phẩy nhưng bỏ qua tất cả các khoảng trắng Vì vậy, câu lệnh x=2+3; trên đây là hoàn toàn tương đương với
Tuy nhiên, trong một xâu các ký tự thì các dấu cách và các dấu tabs lại không bị
bỏ qua, chúng được coi là một bộ phận của xâu ký tự này Một xâu là một dãy các ký
tự Các hằng ký tự thực sự là các xâu được đặt trong các dấu nháy và được chương trình dịch xử lý từng ký tự một
Trang 24printf(“Chao ban %s”, ten);
} // đây là cuối khối lệnh
Trang 2525
2.3.2 Phép toán so sánh
Phép toán so sánh được dùng để so sánh giữa hai giá trị, và sau đó trả về kết quả
là một giá trị kiểu bool (true hay false) Ví dụ toán tử so sánh lớn hơn (>) trả về giá trị
là true nếu giá trị bên trái của toán tử lớn hơn giá trị bên phải của toán tử Do vậy 5 > 2 trả về một giá trị là true, trong khi 2 > 5 trả về giá trị false
Các phép toán logic cũng trả ra giá trị kiểu bool (true hay false)
1 ! Phép phủ định một ngôi (not) !(3>1) false
2 &&
Liên kết hai biểu thức logic Phép và (and) Giá trị bằng 1 khi cả 2 toán hạng có giá trị 1
(2>1)&&(5=2) false
3 ||
Liên kết hai biểu thức logic
Phép hoặc (or) Giá trị biểu thức bằng 1 khi một trong hai toán hạng bằng 1
(4>3)||(1>8) true
Bảng giá trị của các phép toán logic:
true true true true false
true false false true false
false true false true true
Trang 26thì không có nghĩa là "x bằng y", mà là "gán giá trị của y cho x." Trong một câu
lệnh gán, vế phải có thể là một biểu thức bất kỳ còn vế trái phải là một tên biến Vì vậy, dạng của câu lệnh gán là:
tenbien = bieuthuc;
Khi được thực hiện, bieuthuc được ước lượng và giá trị của kết qủa được gán cho tenbien
2.3.5 Thứ tự ƣu tiên các phép toán
Các phép toán có độ ưu tiên khác nhau, điều này có nghĩa là trong cùng một biểu thức, một số phép toán này được thực hiện trước một số phép toán khác Việc xác định thứ tự ưu tiên của các phép toán ảnh hưởng rất lớn đến kết quả của một phép toán Sau đây là bảng liệt kê thứ tự ưu tiên của các phép toán:
Trang 2727
Các phép toán được liệt kê cùng loại sẽ có thứ tự theo mục thứ thự của bảng: thứ
tự trái tức là độ ưu tiên của các phép toán từ bên trái sang, thứ tự phải thì các phép toán có độ ưu tiên từ bên phải qua trái Các toán tử khác loại thì có độ ưu tiên từ trên xuống dưới, do vậy các toán tử loại cơ bản sẽ có độ ưu tiên cao nhất và phép toán gán
sẽ có độ ưu tiên thấp nhất trong các toán tử
2.3.6 Phép chuyển đối kiểu
Khi tính toán một biểu thức phần lớn các phép toán đều yêu cầu các toán hạng phải cùng kiểu Ví dụ để phép gán thực hiện được thì giá trị của biểu thức phải có cùng kiểu với biến Trong trường hợp kiểu của giá trị biểu thức khác với kiểu của phép gán thì hoặc là chương trình sẽ tự động chuyển kiểu giá trị biểu thức về thành kiểu của biến được gán (nếu được) hoặc sẽ báo lỗi Do vậy khi cần thiết người lập trình phải sử dụng các câu lệnh để chuyển kiểu của biểu thức cho phù hợp với kiểu của biến
Về mặt nguyên tắc, khi cần thiết các kiểu có giá trị thấp sẽ được chương trình tự động chuyển lên kiểu cao hơn cho phù hợp với phép toán Cụ thể phép chuyển kiểu có thể được thực hiện theo sơ đồ như sau:
char ↔ int → long int → float → double
Ví dụ 2.3:
int i = 3;
float f ;
f = i + 2;
Trong ví dụ trên i có kiểu nguyên và vì vậy i+2 cũng có kiểu nguyên, trong khi f
có kiểu thực Tuy vậy phép toán gán này là hợp lệ vì chương trình sẽ tự động chuyển kiểu của i+2 (bằng 5) sang kiểu thực (bằng 5.0) rồi mới gán cho f
Trang 2828
Trong chuyển kiểu tự động, chương trình chuyển các kiểu từ thấp đến cao, tuy nhiên chiều ngược lại không thể thực hiện được vì nó có thể gây mất dữ liệu Do đó, nếu cần thiết người lập trình phải ra lệnh cho chương trình
Ví dụ 2.4:
int i; float f = 3 ; // tự động chuyển 3 thành 3.0
và gán cho i = f + 2 ; // sai vì mặc dù f + 2 = 5 nhưng không gán được cho i Trong ví dụ trên để câu lệnh i = f+2 thực hiện được ta phải ép kiểu của biểu thức f+2
về thành kiểu nguyên
Cú pháp tổng quát như sau:
(tên_kiểu)biểu_thức;
trong đó, tên_kiểu là kiểu cần được chuyển sang
Như vậy câu lệnh trên phải được viết lại:
i = int(f + 2) ; Khi đó f+2 (bằng 5.0) được chuyển thành 5 và gán cho i
Dưới đây ta sẽ xét một số ví dụ về lợi ích của việc ép kiểu
Phép ép kiểu từ một số thực về số nguyên sẽ cắt bỏ tất cả phần thập phân của số thực, chỉ để lại phần nguyên Như vậy để tính phần nguyên của một số thực x ta chỉ cần ép kiểu của x về thành kiểu nguyên, có nghĩa int(x)
là phần nguyên của số thực x bất kỳ Ví dụ để kiểm tra một số nguyên n có phải là số chính phương, ta cần tính căn bậc hai của n Nếu căn bậc hai x của n là số nguyên thì n là số chính phương, tức nếu int(x) = x thì x nguyên
và n là chính phương
Ví dụ 2.5:
int n = 10 ;
Trang 29printf("n khong chinh phuong");
Để biết mã ASCII của một kí tự ta chỉ cần chuyển kí tự đó sang kiểu nguyên char c ;
printf("Hay nhap vao 1 ky tu bat ky: ");
Trong ví dụ này mặc dù x được khai báo là thực nhưng kết quả in ra sẽ là 0 thay
vì 6 như mong muốn Lý do là vì phép chia giữa 2 số nguyên i và j sẽ cho lại số nguyên, tức i/j = 3/5 = 0 Từ đó x = 0*10 = 0 Để phép chia ra kết quả thực ta cần phải
ép kiểu hoặc i hoặc j hoặc cả 2 thành số thực, khi đó phép chia sẽ cho kết quả thực và
x được tính đúng giá trị Cụ thể câu lệnh x = i/j*10 được đổi thành:
x = float(i) / j * 10 ; // đúng
x = i / float(j) * 10 ; // đúng
x = float(i) / float(j) * 10 ; // đúng
Trang 30Để đưa dữ liệu ra màn hình, trong lập trình C sử dụng hàm printf, cú pháp để
xuất dữ liệu như sau:
printf(“Chuỗi định dạng”[đối mục 1, đối mục 2,…]);
Chú ý: Để sử dụng được hàm printf cần phải khai báo thư viện #include
<stdio.h>
Trong đó:
- printf là tên hàm, phải viết bằng chữ thường
- Đối mục 1,…: Là các mục dữ kiện cần in ra màn hình Các đối mục này có thể là biến, hằng hoặc biểu thức phải được định trị trước khi in ra
- Chuỗi định dạng: Được đặt trong cặp nháy kép (“ ”), gồm 3 loại:
o Đối với chuỗi ký tự ghi như thế nào thì in ra màn hình giống như vậy
o Đối với những kí tự chuyển đổi dạng thức cho phép kết xuất giá trị của các đối mục ra màn hình tạm gọi là mã định dạng Sau đây là các dấu
Trang 31\n \n Nhảy xuống dòng kế tiếp và canh về cột đầu tiên
\t Canh cột tab ngang
\r Nhảy về đầu hàng, không xuống hàng
\a Tiếng kêu bip
In ra màn hình tổng của hai số nguyên
//Chương trình in ra tổng hai số nguyên
Trang 3232
#include <stdio.h> //Khai báo thư viện nhập xuất
#include <conio.h> //Khai báo thư viện xử lý màn hình
int main()
{
int a = 7, b = 5; // Khai báo và khởi tạo giá trị cho biến
printf(“tong cua hai so %d và %d la %d”, a, b, a+b); //In ra màn hình
scanf(“chuỗi định dạng”[đối mục 1, đối mục 2,…]);
Chú ý: Để sử dụng được hàm nhập, xuất dữ liệu thì đều cần phải khai báo thư
viện #include <stdio.h>
Trong đó:
- scanf: Tên hàm, phải viết bằng chữ thường
- Chuỗi định dạng: được đặt trong cặp nháy kép (“ ”) là hình ảnh dạng dữ liệu nhập vào
- Đối mục 1,….: mỗi đối mục sẽ tiếp nhận giá trị nhập vào
Ví dụ 2.8
scanf(“%d”, &i); //%d : định dạng dữ liệu kiểu int
Trang 3333
//&i: đối mục i
Kết quả: Nếu nhập vào 31xyz thì biến i chỉ nhận giá trị 31, còn nếu nhập 3.1 thì biến i chỉ nhận giá trị 3
Ví dụ 2.9 Nhập vào hai số nguyên a, b rồi tính tổng của hai số nguyên đó
//Chương trình tính tổng hai số nguyên
#include <stdio.h> // Khai báo thư viện để sử dụng hàm nhập xuất
#include <conio.h> // Thư viện xử lý màn hình
int main()
{
int a,b; // Khai báo 2 biến nguyên
printf(“Nhap gia tri cho bien a = ”); scanf(“%d”,&a);
printf(“Nhap gia tri cho bien b = ”); scanf(“%d”,&b);
printf(“Tong cua %d va %d la %d”,a,b,a+b); /*in ra tổng của hai số*/
Bài tập 2.1: Hãy nhập và dịch chương trình sau đây Chương trình này làm việc gì?
Giải thích từng dòng lệnh? (không viết các số hiệu dòng khi soạn chương trình)
7: dientich = 3.14159 * bankinh * bankinh;
8: printf( "\n\nDiện tích = %f", dientich );
Trang 3434
9: return 0;
10:
Bài tập 2.2: Chương trình sau đây đang có lỗi Hãy nhập và dịch nó Các dòng nào
sinh ra thông báo lỗi?
Bài tập 2.3: Viết chương trình định dạng và in ra một bài thơ nào đó
Bài tập 2.4: Viết chương trình nhập vào điểm của ba môn toán, lý, hóa của một học
sinh rồi in ra điểm trung bình của học sinh đó với hai số lẻ thập phân
Bài tập 2.5: Viết chương trình nhập vào ngày, tháng, năm In ra ngày tháng năm theo
định dạng dd/mm/yy (dd: ngày, mm: thang, yy: năm; ví dụ 02/01/15)
TÓM TẮT
Cấu trúc chung của một chương trình
Các thành phần cơ bản của một ngôn ngữ lập trình: Bảng chữ cái, từ khóa, tên
Các kiểu dữ liệu cơ bản
Biến, hằng và cách khai báo
Trang 3535
BÀI 3: CẤU TRÚC ĐIỀU KHIỂN
MỤC TIÊU
Học xong bài này sinh viên có thể:
o Hiểu và giải thích được cú pháp của các cấu trúc điều khiển
o Vận dụng được các điều khiển if, if…then, switch…case vào từng bài toán cụ
thể
o So sánh được đặc điểm của các cấu trúc điều khiển
o Rèn luyện tính cẩn thận, tư duy trong lập trình
3.1 Giới thiệu về cấu trúc điều khiển
Cấu trúc lệnh điều khiển hay còn gọi là câu lệnh rẽ nhánh, là một phần không thể thiếu trong bất cứ ngôn ngữ lập trình cấp cao, có tác dụng chia chương trình ra nhiều hướng xử lý khác nhau trong một số trường hợp xác định
3.2 Cấu trúc điều khiển rẽ nhánh if
- bieu_thuc là biểu thức điều kiện
- Cong_viec là một lệnh hoặc một khối lệnh
Bước 1: Xác định giá trị của bieu_thuc
Trang 3636
Bước 2: Tùy thuộc vào giá trị của bieu_thuc mà máy sẽ tiến hành lựa chọn một
trong hai nhánh:
- Nếu bieu_thuc trả ra giá trị True thì máy sẽ tiến hành thực hiện Công_việc
- Nếu bieu_thuc trả ra giá trị False thì máy sẽ bỏ qua Công_việc trong câu lệnh
if mà tiến hành thực hiện các câu lệnh sau câu lệnh if
- if, else là từ khóa
- bieu_thuc là biểu thức điều kiện
- Cong_viec_1, Cong_viec_2 là một lệnh hoặc một khối lệnh
Bước 1: Xác định giá trị của biểu thức điều kiện
Bước 2: Tùy vào giá trị của bieu_thuc mà máy sẽ tiến hành lựa chọn một trong
hai nhánh:
- Nếu bieu_thuc trả ra giá trị True thì máy sẽ tiến hành thực hiện Cong_viec_1;
- Ngược lại, nếu bieu_thuc trả ra giá trị False thì máy sẽ tiến hành thực hiện Cong_viec_2;
Ví dụ 3.2
Trang 3737
Viết chương trình nhập vào tổng điểm của 3 môn toán, lý, hóa
Nếu tổng điểm 3 môn >=15 thì in ra màn hình: “Đạt”
Ngược lại thì in ra màn hình: “Không đạt”
Chương trình minh họa:
// Chương trình nhập và kiểm tra giá trị
#include <stdio.h> // Khai báo thư viện nhập xuất
#include <conio.h> // Khai báo thư viện xử lý màn hình
int main() // Chương trình chính
{
float tong; // Khai báo biến
// Nhap gia tri cho bien
printf(“Nhap vao tong diem cua 3 mon: ”); scanf(“%f”,&tong);
Trang 38case gt2: Khối_lệnh_2; [break;]
- switch, case, default là các từ khóa
- bieu_thuc là một biểu thức nguyen bất kỳ
- gti là giá trị mà bieu_thuc có thể nhận được Có thể là kiểu chả vì nó có thể chuyển đổi thành kiểu int
- Những phần đặt trong hai dấu [ và ] có thể có hoặc không
Sự hoạt động của cấu trúc điều khiển switch phụ thuộc vào giá trị của bieu_thuc
- Bước 1: Tính giá trị của bieu_thuc
- Bước 2: Tùy thuộc vào giá trị của bieu_thuc mà máy sẽ thực hiện những công
viêc khác nhau, cụ thể:
Trang 39o Khi giá trị của bieu_thuc khác tất cả các giá trị gti thì cách làm việc của máy lại phụ thuộc vào sự có mặt hay không có mặt của default
Khi có default máy nhảy tới câu lệnh có nhãn default Khi không có default máy tiến hành thực hiện các câu lệnh sau cấu trúc này
Ví dụ 3.3
Viết chương trình nhập vào một số nguyên từ 2 đến 8 và in ra thứ tương ứng
Hướng dẫn:
Input: Một số nguyên a trong khoảng 2 đến 8
Output: Thứ tương ứng với giá trị vừa nhập
- Bước 1: Nhập vào một số bất kỳ trong đoạn từ 28 (giả sử đặt là a có kiểu
dữ liệu là int)
- Bước 2: Kiểm tra xem số vừa nhập vào tương ứng với ngày nào trong tuần sử
dụng cấu trúc rẽ nhánh switch
Nếu giá trị nhập vào không nằm trong khoảng từ 2 đến 8 thì in ra thông báo:
“Giá trị bạn vừa nhập không hợp lệ!”
- Bước 3: Kết thúc chương trình
Chương trình minh họa
/* chương trình hiển thị thứ trong tuần tương ứng với giá trị nhập vào từ bàn phím*/
Trang 40int a; //Khai báo biến nguyên nhận giá trị nhập vào
printf("\nHay nhap mot so nguyen tu 2 den 8: "); scanf(“%d”, &a);
//Kiểm tra giá trị nhập vào rồi in ra thứ tương ứng
switch(a)
{
case 2: printf("\nThu hai"); break;
case 3: printf("\nThu ba"); break;
case 4: printf("\nThu tu"); break;
case 5: printf("\nThu nam"); break;
case 6: printf("\nThu sau"); break;
case 7: printf("\nThu bay"); break;
case 8: printf("\nChu nhat"); break;
default: printf("\nGia tri ban nhap khong hop le"); }
getch();
return 0;
}
Kết quả