+ Số bước cần thực hiện trong thuật toán là hữu hạn để sau một số lần lặp nhất định ta phải được nghiệm của bài toán + Tính tối ưu: thông thường đối với một bài toán có nhiều phương pháp
Trang 1I.2 Ưu điểm của ngôn ngữ C:
Hiện nay có rất nhiều ngôn ngữ lập trình khác nhau như PASCAL, JAVA, DELPHI, BASIC, Mỗi ngôn ngữ có một số điểm mạnh riêng tuy nhiên ngôn ngữ C được sử dụng rộng rãi nhờ những ưu điểm sau:
• C là ngôn ngữ mạnh và mềm dẻo (linh động) C có thể được sử dụng để viết hệ điều hành, trình biên dịch của ngôn ngữ khác, trình điều khiển, soạn thảo văn bản, đồ hoạ, bảng tính,
• Ngôn ngữ C được sử dụng rộng rãi bởi các nhà lập trình chuyên nghiệp và nhờ có chuẩn ANSI C nên có tính khả chuyển cao : chương trình viết cho máy tính IBM-PC có thể được biên dịch và chạy trên hệ thống máy tính khác như VAX
• Chương trình dịch có hiệu quả cao : đến 80% tính năng của chương trình đó viết trên mã máy Ngôn ngữ C có thể sử dụng khá nhiều chương trình dịch và các thư viện tiện ích
• C có ít từ khoá nên súc tích và cô đọng
• C là ngôn ngữ có cấu trúc modul thông qua việc sử dụng các hàm
I.3 Nhược điểm của ngôn ngữ C:
Tuy nhiên C cũng có một số nhược điểm sau :
• Ngôn ngữ C có cú pháp lạ và khó học Những người đã từng viết ngôn ngữ khác có thể vượt qua được khó khăn này
• Một số kí hiệu có ý nghĩa khác nhau tuỳ thuộc vào ngữ cảnh sử dụng
• C quá mềm dẻo có thể làm cho chương trình có vẻ bất ổn
I.4 Thuật toán (Algorithm):
Thuật toán là một chuỗi các chỉ dẫn chính xác đem đến một lời giải cho một bài toán Khi xây dựng thuật toán ta chú ý nó phải thoả mãn các điều kiện sau :
+ Tính khả thi: thuật toán phải thực hiện được khi xây dựng chương trình để chạy được trên máy tính
Trang 2+ Số bước cần thực hiện trong thuật toán là hữu hạn để sau một số lần lặp nhất định ta phải được nghiệm của bài toán
+ Tính tối ưu: thông thường đối với một bài toán có nhiều phương pháp giải khác nhau
ta phải chọn ra trong số đó phương pháp giải tối ưu nhất về thời gian thực hiện, cho kết quả chính xác nhất, khối lượng tính toán ít nhất và đơn giản khi viết chương trình
• Lấy danh sách lớp
• Lấy tên cần kiểm tra : Xuân
• Xóa bộ đếm về 0
• Lần lượt đối với từng tên trong danh sách : So sánh với tên cần kiểm tra, nếu đúng thì cộng 1 vào bộ đếm
• Thông báo giá trị bộ đếm ( số sinh viên có tên Xuân )
I.5 Lưu đồ :
Sai
Begin
End
Tùy thuộc vào trạng thái đúng
sai của biểu thức B mà rẽ
nhánh thích hợp
Bắt đầu và kết thúc một thuật toán
Trang 3I.6 Các bước cơ bản khi viết chương trình C:
• Thiết kế chương trình :
Xác định đầu vào, đầu ra của bài toán
Xây dựng thuật toán để giải quyết bài toán
• Soạn thảo :
Sử dụng chương trình soạn thảo TURBO C hoặc BORLAND C hoặc C++, sau đó lưu lại file đó với tên là *.c ( đối với C++ là *.cpp )
• Dịch :
Chương trình soạn thảo cũng là trình biên dịch
Trình biên dịch sẽ có nhiệm vụ dịch chương trình nguồn sang mã máy qua 2 gian đoạn: dịch ra tập tin *.obj và liên kết các file *.obj lại với nhau qua trình liên kết Nếu có lỗi thì ta quay trở lại bước soạn thảo để sữa chữa
• Chạy chương trình
Nếu có lỗi thì ta phải kiểm tra lại thuật toán, lỗi logic, đến khi cho kết quả đúng
II Các phần tử cơ bản của ngôn ngữ C:
II.1 Bộ kí tự của C:
Ngôn ngữ C được xây dựng trên bộ kí tự sau :
• Các chữ cái hoa A Z, các chữ cái thường a z
• Các chữ số 0 9
• Dấu chấm câu : , ; ?
• Các kí tự đặc biệt như []{}!@#$%^&*()-=\+|
• Các kí tự không nhìn thấy như khoảng trắng, dấu tab, ký tự xuống dòng
• Kí tự gạch dưới _
Đây chỉ là tập con của Bảng mã ASCII
Ta không được phép sử dụng các kí tự ngoài bộ kí tự trên
II.2 Các từ khoá (keyword):
Từ khoá là từ dùng riêng, không thể định nghĩa lại, mỗi từ khoá có một ý nghĩa riêng
Ta không được sử dụng từ khoá vào mục đích khác như đặt tên cho biến, hằng, mảng; cần phải viết chính xác từ khoá
Trang 4II.3 Tên và cách đặt tên:
Chương trình sử dụng rất nhiều tên: tên biến, tên hằng, tên hàm,
Các tên phải được khai báo trước khi sử dụng
• C phân biệt chữ hoa và chữ thường : bien,Bien và BIEN là các tên khác nhau
• Không được sử dụng từ khóa để đặt tên
• Tên có thể dài tới 31 kí tự, tuy nhiên không nên đặt tên quá dài
• Tên biến, tên hằng nên phản ánh cái mà nó lưu trữ
• Tên hàm nên phản ánh công việc mà nó làm
Ví dụ : bien_dem, nghiem1, hoan_vi, : đúng
1st, bien dem, registry là các ví dụ sai Chú ý : + C có phân biệt chữ hoa và chữ thường
+ Tất cả các từ khoá và hàm chuẩn đều là chữ thường, các macro chuẩn đều là chữ hoa
II.4 Lời chú giải:
Lời chú giải trong chương trình có mục đích làm cho người đọc dễ hiểu, chương trình sáng sủa, thuận lợi trong việc tìm kiếm, sữa chữa, gỡ rối, nhất là đối với chương trình lớn, phức tạp Ta cần có thói quen sử dụng các câu chú thích Không sử dụng chú thích với những lệnh đã quá rõ ràng
Lời chú giải không có tác dụng tạo ra mã chương trình Trình biên dịch sẽ bỏ qua tất cả các câu ghi chú Ta không sử dụng các câu chú thích lồng vào nhau
Lời chú giải ở bất kỳ đâu trong chương trình, được đặt giữa cặp kí hiệu /* và */ , chú giải có thể nằm trên nhiều dòng
Ví dụ : /* đây là hàm hoán vị
hàm này sử dụng con trỏ */
Trong C++, sau mỗi dòng, lời chú giải có thể nằm sau kí hiệu // Mỗi kí hiệu // chỉ có tác dụng trên dòng đó
Ví dụ : int dem=0; // dem là biến đếm
II.5 Câu lệnh và dấu chấm câu:
Mỗi câu lệnh được kết thúc bằng dấu chấm phẩy ;
Những dòng không phải là câu lệnh thì kết thúc không có dấu chấm câu
Các câu lệnh cùng nhóm nên đặt thẳng cột
Mỗi câu lệnh nên viết trên một dòng (nếu có thể )
Trang 5III Cấu trúc chung của chương trình :
Chương trình C là một tập hợp nhiều hàm trong đó phải có 1 hàm chính gọi là main() Hàm là đoạn mã lệnh độc lập được đặt tên và thực hiện một công việc xác định khi được gọi đến Một hàm có thể gọi đến nhiều hàm khác
Hàm main() là hàm được máy tính thực hiện trước tiên trong một chương trình
void ham1(void) {
}
void ham2(void) {
}
main() {
Trang 6Một chương trình C thường có cấu trúc như sau :
/* Các chỉ thị tiền xử lí */
#include
#define
typedef /* định nghĩa các kiểu dữ liệu */
/* khai báo nguyên mẫu các hàm*/
#include <stdio.h> // chỉ thị tiền xử lí
printf(“\nNhap chieu dai:”);scanf(“%d”,&x); // hàm đọc từ bàn phím
printf(“\nNhap chieu rong:”);scanf(“%d”,&y);
printf(“\nDien tich hinh chu nhat: %d”,tich(x,y)); // hàm in ra màn hình
Trang 7Ví dụ : tính diện tích hình chữ nhật biết chiều dài và chiều rộng không dùng hàm
printf(“\nNhap chieu dai:”);scanf(“%d”,&x);
printf(“\nNhap chieu rong:”);scanf(“%d”,&y);
printf(“\nDien tich hinh chu nhat: %d”,x*y);
2 Tính chu vi, diện tích của hình tròn biết bán kính r = 3 cm
3 Đưa ra màn hình dòng chữ : “ Môn học ngôn ngữ lập trình C “
Trang 8Ch−¬ng II KIỂU DỮ LIỆU, BIẾN VÀ HẰNG
I Kiểu dữ liệu:
Kiểu dữ liệu là tập hợp các giá trị mà các biến thuộc kiểu đó có thể nhận được
Mỗi kiểu dữ liệu có một số phép toán tương ứng
Các kiểu dữ liệu được phân loại như sau :
II Biến và hằng, các phép gán cơ bản:
Biến dùng để lưu dữ liệu có thể thay đổi giá trị được
Hằng dùng để lưu dữ liệu không thể thay đổi
Biến và hằng là vùng nhớ lưu trữ dữ liệu được đặt tên cho dễ truy cập (không phải dùng địa chỉ)
Trước khi sử dụng biến và hằng ta cần khai báo trước
II.1 Khai báo và khởi tạo biến:
Khai báo biến : kiểu_dữ_liệu danh_sách_các_tên_biến
Ta có thể khai báo nhiều biến cùng kiểu cùng một lúc, các biến cách nhau dấu phẩy
Ví dụ : int dem, tam, x, y;
float tr_binh;
Khởi tạo biến : biến = biểu thức
Ví dụ : int x ;
x = 10;
hoặc : int x =10 ;
Ta cần chú ý x = y không phải là x bằng y mà là gán giá trị của y vào x
Ví dụ : int x,y;
y=x;
kiểu số nguyên kiểu số thực kiểu kí tự kiểu logic kiểu cơ sở
kiểu vô hướng tự định nghĩa kiểu liệt kê
kiểu vô hướng đơn giản
kiểu dữ liệu có
kiểu array kiểu struct
kiểu con trỏ
Kiểu
dữ
liệu
Trang 9Ta nên nhớ rằng bộ nhớ máy tính không rỗng khi máy tính làm việc Các khối nhớ cấp phát cho biến có thể đã có giá trị trước đó Ta chưa khởi tạo x nên ta không biết được giá trị x
II.2 Khai báo và khởi tạo hằng:
Khai báo hằng : const kiểu_dữ_liệu tên_hằng = giá trị hằng
Ví dụ : const int so_luong = 50 ;
const float sai_so = 0.5 ;
II.3 Phép gán:
Biến nhận giá trị qua phép gán với dấu bằng : tên_biến = biểu thức
Ví dụ : a = 5; // gán cho a giá trị là 5
b = a - 4; // tính giá trị a - 4 rồi gán giá trị đó cho b Phép gán kép :
Ví dụ : a = b = c = 7 ;
a = (b = 4 ) + ( c = 5 ) ; Khi ta sử dụng phép gán kép, câu lệnh sẽ ngắn hơn tuy nhiên không nên lạm dụng
III Kiểu số nguyên:
Các kiểu số nguyên là những tập hợp con của tập Z, không phải là toàn bộ tập Z
• Các kiểu số nguyên của C với các dải giá trị khác nhau :
Unsigned long integer unsigned long 4 0 ÷ 4294967295
Với tất cả các kiểu, ta chỉ nên gán cho biến các giá trị nằm trong dải giá trị của kiểu đó, nếu không ta sẽ nhận được kết quả không mong muốn mặc dù C không thông báo lỗi
Kiểu int là kiểu thông dụng nhất Kiểu char thực ra là kiểu kí tự nhưng C cho phép sử dụng kiểu char như là kiểu nguyên: trong biểu thức số học thì char được hiểu là kiểu nguyên
• Các phép tính số học đối với số nguyên :
Trang 10Ví dụ : số 53 ở dạng nhị phân là 110101, ở dạng Hexa là 35
Số nguyên được biểu diễn dưới dạng Hexa : 0xgiá_trị_Hexa hoặc 0Xgiá_trị_Hexa
Ví dụ : 0x12 (=18) ; 0X12 (=18)
Đối với số hệ 8 ta viết thêm số 0 vào trước : 0giá_trị_Oct
Ví dụ : 0123 (=83)
• Biểu diễn số âm trong máy tính:
Số âm : Ví dụ : int x= - 21 ;
Số bù 1 : 1111 1111 1110 1010 Số bù 2 : 1111 1111 1110 1011
• Hiện tượng tràn số :
Hiện tượng này xảy ra khi kết quả dự kiến của phép tính số học vượt ra khỏi dải giá trị có thể biễu diễn được của kiểu dữ liệu đó Lúc đó kết quả thực tế sẽ là kết quả sai
Ví dụ : 32767 + 1 sẽ có kết quả -32768
Để khắc phục ta chuyển sang sử dụng các kiểu dữ liệu có dải giá trị cho phép rộng hơn Chúng ta nên khai báo với kiểu dữ liệu tối ưu để vừa có kết quả mong muốn vừa tiết kiệm bộ nhớ
Nếu chúng ta đặt một số âm vào biến không dấu hoặc đặt một số vào kiểu dữ liệu có dải giá trị nhỏ hơn số đó thì trình biên dịch sẽ không báo lỗi nhưng ta sẽ có kết quả không mong muốn
• Hằng số nguyên có kiểu định trước :
Đôi khi chúng ta muốn ghi các hằng số với kiểu định trước một cách tường minh để đảm bảo độ chính xác : ghi thêm 1 kí tự vào cuối số đó
Ví dụ : U : unsigned int
UL : unsigned long int 0x123L: hằng số nguyên dưới dạng Hexa kiểu long
Ví dụ : signed char ch= 0xFF;
int x= 0xFFFF;
unsigned int y= 0xFFFFu;
printf("\n The decimal of signed 0xFF is %d", ch); -1 printf("\n The decimal of signed 0xFFFF is %d", x); -1 printf("\n The decimal of unsigned 0xFFFFu is %u", y); 65535 printf("\n The hex of decimal 12 is %#X ", 12); 0XC printf("\n The hex of decimal -12 is %#X ", -12); 0XFFF4
Trang 11IV Kiểu số thực:
• Các kiểu số thực của C :
Số thực có độ chính xác kép độ dài lớn long double 10 3.4E-4932 ÷ 3.4E4932
Biểu diễn số thực ở dạng thập phân :
Ví dụ : 3.14 ; 2.718281828
Biểu diễn số thực ở dạng khoa học :
Ví dụ : 6.023e23=6.023E23 (= 6.023 * 1023)
Trong ví dụ trên, phần định trị là 6.023, phần mũ là 23
Phần định trị và phần mũ có thể có dấu đi kèm, chúng được viết liền nhau không có dấu ngăn cách Ví dụ : -12.23e-23
Phần nguyên hay phần thập phân có thể không có nhưng dấu chấm không thể thiếu
Ví dụ : 3 14
Ta để ý : 3 là số nguyên nhưng 3 là số thực
• Biểu diễn số thập phân trong máy tính:
Số thập phân : Ví dụ : 12.5 : 1100.1
Quy trình chuyển đổi
• Hằng số thực có kiểu định trước :
Tương tự như số nguyên :
F : kiểu float
L : kiểu long
• Các phép toán với kiểu số thực :
Phép cộng ( + ) , trừ ( - ) , nhân ( * ) , chia ( / ) , phép tăng giảm
Phép chia (/) đối với số thực sẽ cho kết quả là số thực Số thực không có phép % Khai báo và khởi tạo số thực : tương tự như số nguyên :
Trang 12Các toán tử với kiểu Boolean :
Các phép toán quan hệ :
VI Kiểu kí tự (character):
Mỗi giá trị kiểu char chiếm 1 byte và được biểu diễn thông qua bảng mã ASCII Các kiểu kí tự trong C :
Phân loại :
• Các kí tự văn bản có mã từ 32 đến 126, có thể đưa ra màn hình và máy in Các
kí tự này gồm các kí tự ! ” # $ % & , các con số, các chữ cái thường và hoa,
• Các kí tự điều khiển có mã từ 0 đến 31, nói chung các kí tự này không thể đưa
ra màn hình Một số kí tự điều khiển :
Ta cần phân biệt hai kí tự ‘0’ và ‘\0’ : Kí tự ‘0’ là số 0 có mã 48, còn kí tự ‘\0’ là kí tự NULL có mã 0
Trang 13Ví dụ : Để in ra một dòng với tiếng chuông trước và sau dòng chữ :
printf(“\aHello%c”,7);
• Các kí tự đồ họa có mã số từ 127 đến 255 Các kí tự này có thể đưa ra màn hình nhưng không thể đưa ra máy in nhờ các lệnh DOS
Hằng kí tự được biểu diễn nằm giữa 2 dấu nháy đơn : ‘a’,’7’,
Kí tự được biểu diễn dưới dạng Hexa : \xHHH
Kí tự được biểu diễn dưới dạng Octal : \DDD
Ví dụ : ‘A’ có thể viết như sau : \x41 hoặc \101
Một số hàm xử lí kí tự : (được cung cấp trong thư viện ctype.h)
int toascii(int c) chuyển c thành mã ASCII int tolower(int c) chuyển c thành chữ thường int toupper(int c) chuyển c thành chữ hoa
Ví dụ : Nhập chữ thường từ bàn phím và chuyển thành chữ hoa:
Trang 14Hàm toascii xóa tất cả các bit ngoại trừ 7 bit cuối -> kết quả thuộc [0,127]
Sự khác nhau giữa ‘Z’ và “Z” :
- ‘Z’ gồm 1 byte, “Z” gồm 2 byte lưu trong bộ nhớ
- ‘Z’ có thể được sử dụng trong biểu thức toán học, còn “Z” thì không
VII Khai báo bằng các hằng tượng trưng:
Mẫu khai báo :
#define tênbanđầu dãy_ thay_thế
trong đó dãy_ thay_thế có thể là hằng số, hằng xâu kí tự, hằng logic
Trình biên dịch sẽ thay thế tất cả tênbanđầu trong chương trình bằng dãy_thay_thế
Chú ý: Không có dấu = và dấu ; ở cuối câu vì đây không phải là lệnh
VIII Các kiểu dữ liệu tự định nghĩa:
VIII.1 Kiểu liệt kê :
Khi muốn định nghĩa 1 kiểu dữ liệu bằng cách liệt kê tất cả các tên, các giá trị mà ta muốn có, ta sử dụng từ khóa enum như sau :
enum tên_kiểu {pt1,pt2, } biến_1,biến_2;
enum tên_kiểu {pt1,pt2, };
enum {pt1,pt2, } biến_1,biến_2;
enum {pt1,pt2, };
Ví dụ :
enum colors {BLUE,GREEN,RED};
enum colors color ;
color = RED ;
Dãy các phần tử được liệt kê tương ứng với dãy số tự nhiên bắt đầu từ 0
Ví dụ : theo ví dụ trên :
printf(“%d%d”,BLUE,RED);
sẽ có kết quả là 02
Để phần tử bắt đầu có giá trị khác 0, ta định nghĩa như sau :
Trang 15enum thu {hai=2,ba,tu,nam,sau,bay,cn};
VIII.2 Kiểu typedef:
Từ khóa typedef không tạo ra kiểu dữ liệu mới mà nó đặt tên mới cho kiểu dữ liệu đã tồn tại
Mẫu : typedef tên_kiểu_cũ tên_kiểu_mới
Ví dụ :
typedef int nguyen;
typedef float thuc;
sau đó ta khai báo biến :
nguyen a,b;
typedef còn có tác dụng mạnh hơn:
char line1[81], line2[81], line3[81];
Ta có thể định nghĩa lại :
typedef char line[81];
printf(“\n x+y = %#x\n x-y = %#x”, x+y, x-y );
3 Biểu diễn các số sau dưới dạng nhị phân :
127, -129, 12.12
4 Chuyển đổi giữa các cơ số 2, 8, 10, 16 :
1234.1234(10), 11001011.10110011(2), 1234.5671(8), ABC.1234(16)
5 Biểu diễn các số sau dưới dạng khoa học :
1234567890; -123.456; -0.00123 ( 1.23456789E9 ; -1.23456E2 ; -1.23E-3 )
6 Đối với các dữ liệu sau, ta dùng kiểu dữ liệu nào cho hợp lý :
Ngày, tháng, năm sinh ; điểm trung bình môn học
7 Viết chương trình nhập số giây, xuất ra dưới dạng giờ : phút : giây
8 Viết chương trình nhập giờ : phút : giây, xuất ra số giây
9 Viết chương trình nhập giờ1 : phút1 : giây1 và giờ2 : phút2 : giây2, xuất ra tổng
10 Tính :
(4<5) || (5<4)
!(4-4) && (2+3)
11 Nếu ta gán một số có dấu chấm thập phân vào số nguyên thì sao ?
TL: giá trị được gán vào sẽ bị cắt mất phần thập phân ví dụ : 3.14 thì chỉ còn lại 3
12 Số nguyên âm là TRUE hay FALSE ?
Trang 16Ch−¬ng III CÂU LỆNH, BIỂU THỨC, VÀ TOÁN TỬ
Khoảng trắng chỉ có ý nghĩa trong xâu kí tự như “Dai hoc Da Nang”
Với xâu kí tự để có thể viết trên các dòng khác nhau thì ta phải dùng kí tự \
Ví dụ : int x,\
Khối lệnh là một nhóm câu lệnh được bao bởi cặp dấu ngoặc {}
Ví dụ : { câu lệnh 1;
câu lệnh 2;
câu lệnh n;
} Những nơi có thể đặt một lệnh đơn thì có thể đặt 1 khối lệnh Bên trong khối lệnh có thể có khối lệnh khác
III Biểu thức:
Biểu thức bao gồm các toán hạng và toán tử
Toán hạng có thể là biến, hằng, hàm
Toán tử là + - * / % & |
Ví dụ : biểu thức tan(x)*y - 2 gồm các toán hạng là hàm tan của x, biến y và hằng 2; các toán hạng là *, -
• Biểu thức số học là biểu thức có kết quả là giá trị số học
• Biểu thức logic là biểu thức có kết quả là TRUE hoặc FALSE ( thông qua 0 và 1)
• Biểu thức quan hệ là các biểu thức logic đơn giản, chứa các toán tử quan hệ như
>,<,>=,<=,==,!= Các toán hạng trong biểu thức này không nhất thiết phải tương thích với nhau về kiểu
Trang 17IV Toán tử:
Toán tử là một kí hiệu nhằm thực hiện các tính toán trên 1 hay nhiều số hạng
IV.1 Phép tính theo bit:
Không áp dụng cho kiểu float và double
& phép AND theo từng bit
| phép OR theo từng bit
^ phép XOR theo từng bit
~ phép đảo từng bit
Ta dùng các phép tính theo bit để xoá hoặc lập các bit trong các số nhị phân
Ví dụ : để lập bit thứ 0 và bit thứ 3 của số nguyên x, ta dùng lệnh x = x | 0x9;
để xoá bit thứ 1 và bit thứ 2 của số nguyên x, ta dùng lệnh x = x & 0xF9;
• Phép dịch số học >> và << :
I<<M : dịch số nguyên I sang trái đi M bit, tương đương với I*2M
I>>M : dịch số nguyên I sang phải đi M bit, tương đương với I/2M
Ví dụ : để tính I*20 ta viết (I<<4) + (I<<2) vì 20 = 24 + 22
Ví dụ : int i=0x123;
i=i>>3;
printf(“\n i=%#x”,i); 0x24 printf(“\n i=%#o”,i); 044 Chú ý :
1 int i=0xFFFF;
printf("\ni=%d",i) ; -1 i=i<<2;
3 I>>M tương đương với I/2M khi I > 0
Ví dụ: int i=-15;
clrscr();
printf("\ni=%d",i) ; -15 i=i>>3;
printf("\ni=%d",i) ; -2
Trang 18IV.2 Phép gán mở rộng :
Chú ý : a = a*b+c; không tương đương với a*=b+c;
Vì a*=b+c; tương đương với a=a*(b+c);
Việc dùng phép gán mở rộng có thể gây khó hiểu nhưng nhiều bộ biên dịch tạo ra mã hiệu quả hơn nếu ta dùng nó
IV.3 Phép tăng / giảm giá trị 1 đơn vị (dùng với các biến):
i=i+1 <=> i++ hoặc ++i
i=i-1 <=> i hoặc i
Sự khác nhau giữa 2 lệnh gán a= ++i và a= i++ :
++i : tăng i lên 1 đơn vị, sau đó mới gán
i++ : gán trước, sau đó mới tăng i lên 1 đơn vị
Ví dụ : x=0;a=x++; // a=x; x++; : a=0, x=1;
x=0;a=++x; // x++; a=x; : a=1,x=1;
IV.4 Toán tử quan hệ :
== toán hạng 1 có bằng toán hạng 2 không ?
> toán hạng 1 có lớn hơn toán hạng 2 không ?
< toán hạng 1 có nhỏ hơn toán hạng 2 không ?
>= toán hạng 1 có lớn hơn hoặc bằng toán hạng 2 không ?
<= toán hạng 1 có nhỏ hơn hoặc bằng toán hạng 2 không ?
!= toán hạng 1 có khác toán hạng 2 không ?
Ta cần phải phân biệt toán tử quan hệ == và toán tử gán =
IV.5 Toán tử sizeof():
Toán tử sizeof(x) trả lại số byte mà x chiếm
Ta còn có thể viết sizeof(kiểu_dữ_liệu)
Ví dụ : float x;
printf(“\n Kích thước của kiểu số thực là : %d”, sizeof(x));
printf(“\n Kích thước của kiểu số nguyên là : %d”, sizeof(int));
Trang 19IV.6 Toán tử điều kiện :
biểu_thức1 ? biểu_thức2 : biểu_thức3;
Nếu biểu_thức1 là đúng (khác 0) thì giá trị của biểu thức trên là biểu_thức2, nếu biểu_thức1 là sai (bằng 0) thì giá trị của biểu thức trên là biểu_thức3
Ví dụ : Giả sử ta muốn tìm giá trị lớn nhất max của 2 số a và b Ta có thể viết như sau : max = a > b ? a : b
Nếu a > b là TRUE thì max được gán bằng a, nếu không thì được gán bằng b
Ví dụ: printf(“There %s %d fish”, (n>1) ? ”are”:”is”, n);
printf("There %s %d dog%s", (n>1)?"are":"is", n, (n>1)?"s":"");
V Thứ tự ưu tiên giữa các phép toán:
Nếu không nhớ thứ tự thì ta có thể dùng các dấu ngoặc đơn ()
Nếu các toán tử cùng cấp thì làm theo chiều tính toán
Ta không nên viết : x = f ( ) + g ( ); nếu 1 trong 2 hàm f và/hoặc g có thể làm thay đổi giá trị của các biến truyền cho hàm còn lại C không chỉ rõ hàm nào sẽ được thực hiện trước
Tương tự : * printf("%d %d\n", ++n, power(2, n)); /* sai */
* a[i] = i++;
VI Sự hiệu chỉnh khi tính toán :
Ngôn ngữ C cho phép sự trộn lẫn các toán hạng thuộc các kiểu khác nhau
VI.1 Sự chuyển đổi số học :
Trang 20Việc chuyển đổi kiểu giá trị xảy ra tự động khi trong biểu thức có các toán hạng khác kiểu Việc chuyển đổi kiểu giá trị cũng xảy ra khi gán giá trị kiểu này cho biến (hoặc phần tử mảng) kiểu kia, khi truyền giá trị các đối số cho các tham số, trong câu lệnh return
int → long → float → double → long double
Khi chuyển đổi theo chiều ngược lại thì sẽ bị mất mát thông tin, có thể có cảnh báo nhưng không có lỗi
Ví dụ: int n;
VI.2 Sự ưu tiên cho kiểu số :
Các phép tính số học không định nghĩa cho kiểu char và short C tự động hiệu chỉnh kiểu char và kiểu short thành kiểu int
VI.3 Chuyển đổi đối với kiểu kí tự char:
Kiểu kí tự char khi ở trong biểu thức số học sẽ được chuyển đổi thành kiểu int dựa vào bảng mã ASCII
Ví dụ : char ch;
ch = ‘A’ + 1; // ‘A’=65 nên ‘A’+1=66 từ đó ch=’B’
VII Cố ý chuyển đổi kiểu giá trị:
Để nhận được kết quả mong muốn đôi khi ta phải chuyển đổi kiểu của giá trị
Ở đây (float)m có nghĩa là chuyển đổi n sang kiểu số thực
Khi đó (float)m/n là phép chia giữa 2 số thực
Ta có thể viết (float)(m) hoặc (float)m
Trang 21VIII Các hàm số học chuẩn:
Các hàm số học chuẩn nhận các đối số là các số nguyên hoặc số thực, các hàm này nằm trong file math.h Vì vậy trước khi sử dụng ta cần khai báo #include <math.h>
int abs(int i) trả lại giá trị tuyệt đối của số nguyên i
double fabs(double d) trả lại giá trị tuyệt đối của số thực d
double sin(double d) trả lại hàm sin
double cos(double d) trả lại hàm cos
double cosh(double d) trả lại hàm ch (hyberbolic)
double tan(double d) trả lại hàm tg
double exp(double d) trả lại giá trị e mũ d
double log(double d) trả lại hàm loga cơ số e
double log10(double d) trả lại hàm loga cơ số 10
double pow(double d1, double d2) trả lại giá trị d1 mũ d2
double floor(double d) trả lại hàm cắt tròn số
double ceil(double d) trả lại hàm làm tròn số
double fmod(double d1, double d2) trả lại hàm phần dư của phép chia d1/d2 double sqrt(double d) trả lại hàm căn bậc hai
void srand(double d) khởi tạo bộ số ngẫu nhiên
Trang 225 Ban đầu 4 số x,y,z,t đều bằng 5 Thực hiện các lệnh :
e
7 Viết chương trình nhập 4 số nguyên, tính tổng 2 số nguyên ở giữa
Ví dụ : nhập 4 số a <= b <= c <= d , xuất ra b + c
8 Viết đoạn lệnh tính hàm dấu như sau :
0
n nếu0
0
n nếu
1
1)(nsign
Lời giải: Cách 1: sign = n > 0 ? 1 : 0 ;
sign = n < 0 ? -1: sign ; Cách 2: sign = n > 0 ? 1 : ( n == 0 ? 0 : -1 ) ; Hoặc sign = n > 0 ? 1 : ( n < 0 ? -1 : 0 ) ;
Trang 23Ch−¬ng IV NHẬP XUẤT DỮ LIỆU
I.2 Xâu định dạng : bao gồm :
• Các kí tự điều khiển :
- \n : sang dòng
- \f : sang trang
- \b : xóa lùi một kí tự
- \t : tab (tương ứng với 8 khoảng trắng)
• Các mã định dạng (%) cho các biểu thức tương ứng
• Các kí tự hiển thị: Ngoài những kí tự bình thường, để đưa ra những kí tự đặc biệt,
ta phải viết như sau :
- Canh trái các giá trị xuất (mặc định là canh phải)
+ Hiển thị dấu của các số ( + hoặc - )
‘ ‘ Các số không dấu được bắt đầu bằng khoảng trắng, số âm bắt đầu bằng dấu -
# In các số có kí hiệu của hệ thống số (chỉ dùng với các kí tự chuyển dạng x, X hoặc o) :
in 0x hoặc 0X trước số thập lục phân, in 0 trước số bát phân
- Khi không có dấu trừ thì kết quả được dồn về phía bên phải nếu độ dài thực tế của nó nhỏ hơn độ dài của khuôn in dành cho nó Các vị trí dư thừa sẽ được lấp bằng các khoảng trống Nếu dãy số fw bắt đầu bằng số 0 thì các vị trí dư thừa sẽ được lấp đầy bằng số 0
- Khi có dấu trừ thì kết quả được dồn về phía bên trái và các vị trí dư thừa luôn được lấp bằng các khoảng trống
Trang 24• fw : là dãy số nguyên xác định độ rộng tối thiểu dành cho trường ra :
- Khi fw lớn hơn độ dài thực tế của trường ra thì các vị trí dư thừa sẽ được lấp đầy bởi các khoảng trắng hoặc các số 0 tùy thuộc vào sự có mặt của số 0 Nội dung trường ra được đẩy sang bên trái hay phải tùy thuộc vào sự có mặt của dấu trừ
- Khi không có fw hoặc fw lớn hơn độ dài thực tế của trường ra thì độ rộng dành cho trường sẽ bằng độ dài thực tế của trường ra
Ví dụ : để đưa ra dòng 123^^^^^^000123123^^^ ta viết như sau :
printf(“%-9d%06d%-6d”,123,123,123);
• pp : pp là số nguyên có chức năng :
- Đối với số nguyên thì in ra ít nhất pp chữ số (nếu thiếu thì chèn các số 0) Đối với phần thập phân, nếu không có pp thì độ chính xác mặc định là 6 Nếu pp lớn hơn độ dài thực của trường ra thì nó chèn các số 0 vào, nếu nhỏ hơn thì nó sẽ cắt bớt
- Đối với xâu kí tự : Nếu pp nhỏ hơn độ dài xâu thì chỉ có pp kí tự đầu tiên của xâu được đưa ra Nếu không có pp hoặc pp lớn hơn độ dài xâu thì toàn bộ xâu được đưa ra
Ví dụ : printf(“%-10.2f”,-123.456); sẽ cho kết quả -123.46^^^
Tại vị trí fw và pp ta có thể đặt dấu *, khi đó chúng được xác định bởi biểu thức tương ứng: Ví dụ : int n=8;
float y=4.5;
printf(“\n%*.2f”,n,y);
sẽ cho kết quả ^^^^4.50
• Kí tự định dạng : là kí hiệu xác định quy tắc định dạng và dạng in ra của biểu thức
Kí tự định dạng Ý nghĩa
%c In ra kí tự kiểu char, có thể dùng cho short hoặc int
%d, %i In ra số nguyên int, có thể dùng cho char
%u In ra unsigned int, có thể dùng cho unsigned char, unsigned short
%ld In ra số nguyên kiểu long int
%lu In ra số nguyên kiểu unsigned long int
%x,%X In ra số nguyên dạng Hexa (%x: lower case, %X: upper case)
%f In ra số thực ở dạng thường với 6 chữ số thập phân, dùng cho float, double
%e,%E In ra số thực ở dạng mũ e hay E
%g,%G In ra số thực kiểu %f hay %e tùy thuộc vào cái nào ngắn hơn
%s In ra xâu kí tự bằng cách cung cấp địa chỉ của xâu kí tự
Trang 25I.3 Dãy các biểu thức :
Các biểu thức cách nhau dấu phẩy, biểu thức là hằng, biến, hàm, phần tử của mảng hoặc biểu thức cụ thể
I.4 Giá trị của hàm printf():
Khi thực hiện thành công, printf() cho ta số kí tự (kể cả kí tự điều khiển) được đưa ra Khi có lỗi hàm trả về giá trị -1
Ví dụ : m=printf(“\n 123456”); → m=8
Một số lỗi hay mắc phải :
- Mã định dạng không phù hợp với kiểu của biểu thức
- Số mã định dạng không tương ứng với số biểu thức
II Hàm scanf() :
II.1 Mẫu :
int scanf(“xâu định dạng”, dãy địa chỉ các biến)
Ví dụ : int x,y;
scanf(“%d%d”,&x,&y);
Dòng vào : là dãy kí tự liên tiếp nhập từ thiết bị vào, cuối dòng vào là kí tự \n
Trong dòng vào có các khoảng trắng, dấu tab, các thành phần này là dấu phân cách giữa các trường vào
Ở đây có sự tương ứng 1-1 và đúng trình tự giữa các mã định dạng trong xâu định dạng và dãy các địa chỉ các biến
Xâu định dạng : %[*][dd]]kítựđịnhdạng
• Dấu * : Trường vào vẫn đọc bình thường nhưng không được lưu vào bộ nhớ Vì vậy sẽ không có đối tương ứng
• dd : dãy số xác định độ dài trường vào
- Nếu dd vắng mặt hoặc dd lớn hơn độ dài của trường vào thì toàn bộ trường vào được đọc và ghi vào vùng nhớ tương ứng
- Nếu dd nhỏ hơn độ dài của trường vào thì chỉ có phần đầu của trường vào có kích cỡ dd được đọc và ghi vào vùng nhớ tương ứng, phần còn lại được xem xét sau
ch=”456” (có kí tự NULL ở cuối)
ct=”78abcd” (có kí tự NULL ở cuối)
Trang 26• Kí tự định dạng : c,[dãy kí tự],[^dãy kí tự]
Kí tự định dạng Ý nghĩa
%hd Đọc số nguyên kiểu short int
%ld Đọc số nguyên kiểu long int
%lu Đọc số nguyên kiểu unsigned long int
%f Đọc số thực float theo kiểu viết thường hay viết theo số mũ
%e Đọc số thực float viết theo số mũ
%lf hoặc %lu Đọc số thực double
%s Đọc xâu kí tự không chứa dấu cách, dùng địa chỉ của xâu kí tự
Một số lỗi hay mắc phải :
- Mã định dạng không phù hợp với kiểu của biểu thức
- Số mã định dạng không tương ứng với số biểu thức
• Giá trị trả về của hàm :
Hàm trả về số nguyên bằng số các giá trị nhận được (lưu vào bộ nhớ)
Trong ví dụ trên, giá trị trả về của hàm là 2
Trang 27• Dãy các địa chỉ của các biến :
Là các con trỏ chứa địa chỉ của các biến, các địa chỉ này cách nhau dấu phẩy
Ví dụ : int a;
char b;
scanf(“%c%d”,&b,&a);
và ta nhập c^3 thì b=’c’ và a=3
Ví dụ : int a;
char b;
scanf(“%d%c”,a,b);
và ta nhập 3^c thì a=3 và b=’^‘
Ví dụ : int a;
char b;
scanf(“%d %c”,a,b);
và ta nhập 3^c thì a=3 và b=’c‘
Như vậy nếu giữa 2 mã định dạng ta có thêm vào các khoảng trắng thì khi nhập dữ liệu, máy sẽ nhảy qua các khoảng trắng, dấu xuống dòng, dấu tab đến khi gặp kí tự khác
Ví dụ : int a,b;
scanf(“%d%d”,&x,&y);
Nếu ta gõ vào 34^^45 thì x=34,y=45
Nếu ta gõ ^^^34^^45^^^^ hoặc nhập hai số đó trên nhiều dòng thì vẫn có kết quả trên
• Khuôn đọc : khuôn đọc cũng như khuôn in
Ví dụ : scanf(“%3d %3d”,&a,&b);
Ta nhập vào 12^^23 kết quả : a=12;b=23
Trang 28Nhap vao so y : x=23
y=34 Dữ liệu nhập vào từ bàn phím được lưu vào stdin để chờ xử lí chứ không được xử lí trực tiếp từ bàn phím Do dữ liệu đã có sẵn trong stdin nên máy tính đọc luôn số này và gán cho biến tương ứng mà không chờ ta gõ tiếp vào từ bàn phím Trong stdin sẽ còn lại các kí tự
^^^ và kí tự xuống dòng (\n)
III Đưa ra máy in :
Mẫu : fprintf(stdprn,“xâu định dạng”, dãy các biểu thức );
Đối số stdprn xác định thiết bị đưa ra là máy in
Xâu định dạng và dãy các biểu thức giống như hàm printf()
Ví dụ : fprintf(stdprn,”Xin chao cac ban \n”);
IV Luồng dữ liệu :
Có nhiều thiết bị vào ra như bàn phím, màn hình, máy in, tập tin dữ liệu trên đĩa Dòng dữ liệu là các byte dữ liệu trao đổi giữa các thiết bị
Các dòng dữ liệu liên quan tới các thiết bị vào ra thông dụng :
Stdin bàn phím Stdout màn hình Stderr màn hình Stdprn máy in Stdaux cổng nối tiếp Lệnh printf thực chất là lệnh fprintf(stdout, )
V Dòng vào stdin :
Stdin là dòng vào chuẩn (bàn phím), các hàm scanf, gets, getchar nhận dữ liệu từ đó Nếu stdin có đủ dữ liệu, các hàm trên sẽ nhận phần dữ liệu mà chúng yêu cầu, phần dữ liệu còn lại vẫn ở trên stdin
Nếu stdin chưa có đủ dữ liệu, máy sẽ tạm dừng để người sử dụng nhập thêm dữ liệu từ bàn phím vào stdin (cho đến khi bấm phím Enter )
V.1 Hàm gets:
Hàm này nhập một chuỗi dữ liệu từ stdin Hàm này thuộc tập tin stdio.h
• Mẫu : char *gets(char *s);
Trong đó : s là con trỏ kiểu char tới vùng chứa dãy kí tự nhận được
• Công dụng :
Nhận dãy kí tự từ stdin cho đến khi gặp kí tự \n (tức là chuỗi có thể chứa khoảng trắng) Kí tự \n được loại khỏi stdin và cũng không tồn tại trong chuỗi nhận được Chuỗi được bổ sung thêm kí tự \0 và đặt vào vùng nhớ mà con trỏ s trỏ tới Hàm trả về địa chỉ mà chuỗi nhận được
Trang 29Hàm này nhận một kí tự từ stdin Hàm thuộc tập tin stdio.h
• Mẫu : int getchar(void);
Nếu ta nhấn Enter thì ch=’\n’ và \n không còn trong stdin
2 Hàm scanf cũng để lại kí tự \n Kí tự này sẽ làm trôi các hàm getchar và gets sau đó Để hàm này hoạt động đúng, ta thêm vào %*c ở cuối xâu định dạng
Trang 30printf("\nTen cua ban la : ");
gets(name);
return 0;
}
V.3 Làm sạch stdin :
Ta sử dụng hàm fflush Nhằm xóa các kí tự còn lại trong stdin
y=56
VI Các hàm xuất kí tự puts và putchar:
VI.1 Hàm puts :
• Mẫu : int puts(const char *s);
Trong đó s là con trỏ kiểu char, trỏ tới vùng nhớ chứa chuỗi kí tự cần xuất ra stdout
• Công dụng : đưa chuỗi s và thêm kí tự \n ra màn hình
• Giá trị trả về :
Khi thành công trả về kí tự cuối cùng được xuất (\n) Khi có lỗi trả về EOF
Ví dụ : puts(“Viet nam”);
Lệnh này giống lệnh writeln của PASCAL
VI.2 Hàm putchar :
• Mẫu : int putchar(int ch);
Trong đó ch là là mã của kí tự cần xuất ra stdout
Trang 31• Công dụng : đưa kí tự có mã là ch ra màn hình
• Giá trị trả về :
Khi thành công trả về kí tự được xuất Khi có lỗi trả về EOF
Ví dụ : putchar(‘A’); putchar(65);
VII Các hàm vào ra trên màn hình và bàn phím :
Các hàm này thuộc tập tin conio.h
VII.1 Hàm getch :
• Mẫu : int getch(void);
• Công dụng :
- Nếu có sẵn kí tự trong bộ đệm bàn phím thì hàm nhận luôn kí tự đó
- Nếu bộ đệm rỗng thì chờ gõ một phím mà không cần bấm Enter Kí tự vừa gõ không xuất hiện trên màn hình
• Giá trị trả về : Hàm trả về kí tự nhận được
Ta nên sử dụng hàm getch() ở cuối hàm main() để xem được kết quả trên màn hình trong khi chương trình đang chờ ta gõ vào 1 phím
VII.2 Hàm getche :
• Mẫu : int getche(void);
• Công dụng : như hàm getch nhưng hiển thị kí tự đó trên màn hình
VII.3 Hàm putch :
• Mẫu : int putch(int ch);
Trong đó ch là mã của kí tự cần xuất
• Công dụng : Xuất kí tự có mã ch ra màn hình, kí tự được xuất với màu được xác định trong hàm textcolor Đây là sự khác biệt giữa hàm putch và putchar, hàm putchar luôn xuất kí tự ra màn hình với màu trắng
• Giá trị trả về : Hàm trả về kí tự được hiển thị
VII.4 Hàm khbit :
• Mẫu : int khbit(void);
• Công dụng : Hàm có giá trị khác 0 nếu bộ đệm bàn phím không rỗng, có giá trị 0 nếu bộ đệm bàn phím rỗng
VIII Trình bày màn hình :
Các hàm trình bày màn hình nằm trong tập tin conio.h
VIII.1 Hàm di chuyển con trỏ :
• Mẫu : gotoxy(int x, int y);
• Công dụng : đặt con trỏ màn hình vào tọa độ (x,y) của màn hình x là tọa độ cột có giá trị từ 1 đến 80, y là tọa độ cột có giá trị từ 1 đến 25
Trang 32VIII.2 Hàm xóa màn hình clrscr() : (Clear Screen)
• Mẫu : clrscr();
• Công dụng : xóa toàn bộ màn hình và đặt con trỏ ở vị trí góc trên bên trái
VIII.3 Hàm clreol() : (Clear End of line)
• Mẫu : clreol();
• Công dụng : xóa các kí tự nằm bên phải con trỏ
VIII.4 Hàm delline():
• Mẫu : void delline(void);
• Công dụng : xóa dòng của cửa sổ đang chứa con trỏ
Các hằng màu : được sử dụng với các hàm textcolor() và hàm textbackground()
VIII.5 Hàm textcolor() :
• Mẫu : void textcolor(int newcolor);
• Công dụng : chọn màu kí tự mới
Newcolor có giá trị từ 0 đến 15 tương ứng với các màu ở bảng trên
Để các kí tự nhấp nháy ta cộng thêm 128 vào giá trị màu
Ví dụ : textcolor(WHITE);
hoặc textcolor(15);
Trang 33VIII.6 Hàm textbackground() :
• Mẫu : void textbackground(int color);
• Công dụng: chọn màu nền mới
Color có giá trị từ 0 đến 7 tương ứng với 8 màu ở bảng trên
VIII.7 Hàm highvideo(), lowvideo() và normvideo() :
Các hàm này điều khiển độ sáng của kí tự highvideo() cho độ sáng lớn, lowvideo() cho độ sáng yếu, normvideo() cho độ sáng bình thường
Ví dụ : lowvideo(); printf(“ABC”);
normvideo(); printf(“ABC”);
VIII.8 Hàm textattr() :
• Mẫu : textattr(int newattr);
Trong đó newattr là byte mã hóa thuộc tính màu
4 bit f là màu kí tự (foreground), 3 bit b là màu nền (background) và bit B xác lập nhấp nháy
• Công dụng : xác lập thuộc tính của kí tự trên màn hình
VIII.9 Hàm wherex, wherey :
• Mẫu : int wherex();
int wherey();
• Giá trị trả về : Trả về giá trị là tọa độ hiện thời của con trỏ trên màn hình
Trang 34VIII.10 Hàm printf, scanf, cprintf, cscanf :
Chức năng cprintf, cscanf gần giống như printf, scanf nhưng với các hàm cprintf, cscanf các kí tự hiện trên màn hình sẽ ảnh hưởng bởi câu lệnh textcolor, còn printf, scanf thì không
VIII.11 Hàm window :
• Mẫu : window(int x1, int y1, int x2, int y2);
• Công dụng : tạo ra cửa sổ văn bản với các tọa độ như trên và đưa con trỏ về góc trên bên trái cửa sổ vừa tạo Các lệnh ghi ra văn bản trên màn hình sẽ nằm trong cửa sổ này
Trang 35Ch−¬ng V CÁC CÂU LỆNH ĐIỀU KHIỂN
Thông thường trong một chương trình, các câu lệnh được thực hiện tuần tự từ trên xuống Tuy nhiên có nhiều khi ta lại muốn thay đổi trật tự trên nhờ sử dụng các câu lệnh điều khiển chương trình Các câu lệnh điều khiển có thể làm cho các câu lệnh được thực hiện nhiều lần hoặc không lần nào cả
Các câu lệnh điều khiển gồm có :
• câu lệnh rẽ nhánh : if else ; switch
• câu lệnh nhảy không điều kiện
• câu lệnh vòng lặp
• câu lệnh hỗ trợ như break, continue
I Câu lệnh if else :
I.1 Các dạng của câu lệnh if :
Dạng 1 : if (biểu thức) /* không có dấu chấm phẩy ở đây*/
lệnh_1;
Dạng 2 : if (biểu thức)
lệnh_1;
else lệnh_2;
biểu thức
khối lệnh 1 T
F
Trang 36Dạng 1 : nếu biểu thức có giá trị khác 0 (TRUE) thì thực hiện khối lệnh 1, nếu bằng 0 (FALSE) thì tiếp tục thực hiện lệnh tiếp theo sau lệnh if
Dạng 2 : nếu biểu thức có giá trị khác 0 (TRUE) thì thực hiện khối lệnh 1, nếu bằng 0 (FALSE) thì thực hiện khối lệnh 2
Biểu thức không nhất thiết phải là biểu thức so sánh mà có thể là biểu thức số học
Ví dụ : tìm số lớn nhất và nhỏ nhất trong 2 số nhập từ bàn phím
printf(“Nhap so thuc thu nhat:”);scanf(“%f”,&x);
printf(“Nhap so thuc thu hai :”);scanf(“%f”,&y);
I.2 Sự lồng nhau giữa các câu lệnh if:
Các câu lệnh if có thể lồng nhau : trong khối lệnh của câu lệnh if này có thể có câu lệnh if khác Để tránh nhầm lẫn ta nên sử dụng dấu đóng mở khối lệnh
khối lệnh 1 T
F
Trang 37Nếu số từ khóa if bằng số từ khóa else thì ta có tương ứng từng cặp if-else
Nếu số từ khóa if nhiều hơn số từ khóa else thì else được gắn với if liền trước nó
Như vậy else sẽ gắn liền với if thứ hai
Để chương trình trong sáng, ta cần tuân thủ :
• Ta nên sử dụng cặp dấu {} để chắc chắn không nhầm lẫn
• Các câu lệnh, khối lệnh nằm trong một câu lệnh if nằm dịch về bên phải
• Các câu lệnh, khối lệnh cùng cấp thì viết thẳng cột
• Điểm đầu và điểm cuối của khối lệnh phải nằm thẳng cột
Đối với câu lệnh này :
• Chỉ có 1 trong n+1 khối lệnh được thực hiện
• Nếu biểu thức i là biểu thức đầu tiên khác 0 (TRUE) thì khối lệnh i được thực hiện
• Nếu cả n biểu thức đều bằng 0 (FALSE) thì khối lệnh n+1 được thực hiện
Ví dụ : giải phương trình bậc 2
Trang 38printf(“\nPhuong trinh dung voi moi x”);
else printf(“\nPhuong trinh vo nghiem!”);
else printf(“\nPhuong trinh co 1 nghiem x: %f”,(-c) / b);
printf(“\nPhuong trinh co mot nghiem kep : x = %f”,-b/(2*a));
else { printf(“\nPhuong trinh co hai nghiem phan biet :”);
II Câu lệnh switch:
Lệnh if chỉ cho phép ta chọn một trong hai phương án tùy theo biểu thức điều kiện Tuy nhiên đôi khi ta cần phải lựa chọn 1 trong nhiều phương án khác nhau Để thuận tiện ta sẽ dùng câu lệnh switch:
biểu thức: là biểu thức nguyên bất kì
Các hằng i phải có giá trị khác nhau
Các khối lệnh i và thành phần default là không bắt buộc
• Sự hoạt động của câu lệnh switch :
Trang 39Máy sẽ so sánh biểu thức với các hằng i theo thứ tự từ trên xuống Khi biểu thức có giá trị bằng hằng i thì khối lệnh i được thực hiện Nếu trong khối lệnh đó không có lệnh nhảy thì sẽ thực hiện tiếp tục các khối lệnh bên dưới mà không cần so sánh tiếp Nếu trong khối lệnh đó có lệnh break thì sẽ thoát ra khỏi câu lệnh switch Khi biểu thức có giá trị khác với tất cả hằng i thì sẽ thực hiện khối lệnh n+1 (nếu có)
Khi biểu thức bằng với hằng i, để sau khi thực hiện xong khối lệnh i chương trình sẽ thoát ra ngoài câu lệnh switch sớm hơn ta có thể dùng lệnh break Ta cũng có thể sử dụng lệnh goto để nhảy ra khỏi câu lệnh switch (ta không nên dùng lệnh goto)
• Nhiều giá trị case trong một trường hợp :
Máy sẽ tiếp tục làm việc khi chưa gặp lệnh thoát, vì vậy ta có thể sắp xếp để có nhiều giá trị case trong một trường hợp
Trang 40switch (n)
{ case 0:
case 8: printf(“loại giỏi”);break;
default: printf(“loại giỏi”);
} getch();
case 5,6: printf(“loại trung bình”);break;
case 7,8: printf(“loại giỏi”);break;
default: printf(“loại giỏi”);
} getch();
return 0;
}
Ta nên sử dụng default cho dù không bao giờ xảy ra trường hợp đó: ta dùng default để kiểm tra xem có thể có lỗi hay không bằng cách đặt một thông báo lỗi ở đó, từ đó ta dễ gỡ rối
III Câu lệnh for:
Để thực hiện các công việc lặp đi lặp lại hay làm việc với các phần tử mảng, nếu ta viết từng lệnh một thì sẽ không hiệu quả
• Dạng :
for([ các biểu thức khởi tạo ] ; [ biểu thức điều kiện ] ; [ biểu thức thay đổi điều kiện ])