Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4 Giáo trình Cấu trúc dữ liệu và giải thuật 4
Trang 11990 thì việc chuẩn hoá được hoàn thành và được gọi là “C chuẩn” Mọi ngôn ngữ C trước đó được gọi
là C K&R C là một trong những ngôn ngữ được sử dụng rộng rãi nhất hiện nay
Từ “C chuẩn”, các hãng phần mềm phát triển thành các ngôn ngữ C riêng như: Microsoft C, Quick C, Turbo C, Borland C Năm 1983, với sự phát triển của công nghệ phần mềm, từ “lập trình cấu trúc” sang “lập trình hướng đối tượng” thì ngôn ngữ C được phát triển thành C++
1.2 Các thành phần cơ bản trong ngôn ngữ C
1.2.1 Từ khóa
Từ khóa (keyword) là các từ dành riêng của ngôn ngữ C Từ khóa phải được sử dụng đúng cú pháp
và không được định nghĩa lại Dưới đây là một số từ khóa thông dụng:
- Bắt đầu bằng một chữ cái hoặc dấu gạch dưới; tên không được bắt đầu bằng một chữ số
- Tên không được chứa kí tự trống, không được trùng với từ khóa
Trang 2Ví dụ các tên hợp lệ: so_sanh, chuong_trinh, batdau, program12; các tên không hợp lệ: trung binh, 1_bien, char, abc$ten Nên đặt các tên gợi nhớ và có ý nghĩa
1.2.3 Tên chuẩn
Tên chuẩn là tên đã có sẵn của ngôn ngữ C Một số tên chuẩn như: printf, sin, sqrt, M_PI, BLUE
Không cấm việc đặt tên trùng với tên chuẩn nhưng khi đó ý nghĩa của tên chuẩn không còn giá trị nữa
1.2.4 Hằng, biến, biểu thức
Hằng là đại lượng không đổi trong suốt quá trình thực thi của chương trình Hằng có thể là một ký tự, một chuỗi ký tự, một giá trị số xác định Hằng có thể được biểu diễn hay định dạng với nhiều dạng thức khác nhau
Hằng số thực dùng dấu chấm thập phân hoặc dạng khoa học
Hằng ký tự dùng dấu nháy đơn
Hằng chuỗi kí tự dùng dấu nháy kép
“bai toan” là hằng chuỗi kí tự
Biến là đại lượng có thể thay đổi được giá trị trong chương trình Khai báo biến để chương trình dành
riêng vùng nhớ thích hợp cho biến Chương trình truy cập giá trị của biến thông qua tên của biến
Biểu thức là một công thức tính toán để có một giá trị theo một qui tắc toán học nào đó Một biểu
thức bao gồm các toán tử và các toán hạng (có thể là giá trị, biến, hằng số) Khi tính toán thì ưu tiên cho các biểu thức con trong ngoặc đơn
Ví dụ:
(x + y) / z
a > b
1.2.5 Dấu ngăn cách câu lệnh, khoảng trống
Dấu “;” dùng để ngăn cách các lệnh, nghĩa là mỗi lệnh hoặc mỗi khai báo đều phải kết thúc bởi một
dấu chấm phẩy “;” Bản thân “;” là lệnh rỗng
Khoảng trống được trình biên dịch bỏ qua Khoảng trống gồm các ký tự: dấu cách (space bar), dấu tab và dấu sang dòng (Enter)
Trang 31.2.6 Lời chú thích
Khi viết chương trình, nên sử dụng các lời chú thích để làm cho chương trình dễ hiểu Trong chương trình, các lời chú thích được đặt giữa hai dấu “/*” và “*/” Ví dụ:
/* Day la ham so sanh 2 so */
Lời chú thích không được lồng vào nhau Ví dụ chú thích sau có lỗi:
/* Dai hoc Da Nang /* Truong DHBK*/ */
1.3 Kiểu dữ liệu chuẩn
Kiểu dữ liệu là một tập hợp các giá trị và các phép toán thực hiện trên các giá trị đó Các kiểu dữ liệu
có sẵn của ngôn ngữ C gọi là kiểu dữ liệu chuẩn
Có hai kiểu char: signed char và unsinged char
1.3.2 Kiểu số nguyên
(signed) int, short (int) 2 byte -32768 32767 unsigned (int) 2 byte 0 65535
2147483647
Từ khóa short ít dùng vì mặc định của int là short int
Với các kiểu số nguyên thì mặc định là số nguyên có dấu (signed), để chỉ định số nguyên không dấu (không có số âm) thì đặt từ khóa unsigned trước tên kiểu với
Lưu ý: các kiểu kí tự cũng được xem là một dạng của kiểu số nguyên
Các số trong hệ 16 được viết bởi 10 chữ số và 6 chữ cái là: 0 9 và A, B, C, D, E, F
Trang 4Hằng cơ số 16: thêm kí tự 0x hoặc 0X vào trước số nguyên ở hệ 16
Ví dụ: 0x41 có giá trị thập phân là 65
0XF có giá trị thập phân là 15 Hằng cơ số 8: thêm kí tự 0 (số 0) vào trước số nguyên ở hệ 8
Ví dụ: 017 có giá trị thập phân là 15
0101 có giá trị thập phân là 65 Cách biểu diễn số nguyên ở hệ 16 và ở hệ 8 thường được dùng trong lập trình hệ thống
Ngôn ngữ C luôn mặc định kiểu dữ liệu là int Ví dụ: 16/5 có giá trị là 3
Hằng kiểu long thêm L vào sau (chữ cái l thường dễ nhầm với số 1)
Ví dụ: 123456L
1.3.3 Kiểu số thực
long double 10 byte 3.4E-4932 1.1E+4932
Ví dụ:
11.2/5 giống như 11.2/5.0
Với chuyển kiểu tường minh, dùng cú pháp sau:
Trang 5Cú pháp: (kiểu_mới) biểu_thức
hoặc kiểu_mới (biểu_thức)
Trong cú pháp trên, kiểu_mới là kiểu đích chúng ta cần chuyển đến của biểu_thức cần chuyển kiểu
1.4.1 Các phép toán trên số nguyên
Các phép toán trên số nguyên bao gồm:
1.4.2 Các phép toán trên số thực
Các phép toán trên số thực bao gồm: cộng (+), trừ (-), nhân (*), chia (/)
1.4.3 Các phép toán so sánh
Một biểu thức chứa các phép so sánh ==, !=, >, <, >=, <= được gọi là một biểu thức so sánh (hay còn
gọi là biểu thức quan hệ) Các toán hạng của một biểu thức so sánh có thể là số nguyên hoặc số thực, chúng không nhất thiết phải tương thích nhau về kiểu, chương trình tự động chuyển sang kiểu lớn nhất
để so sánh Kết quả của một biểu thức so sánh có giá trị đúng hoặc sai Một biểu thức đúng có giá trị 1;
ngược lại, một biểu thức sai có giá trị 0
Kí hiệu phép toán quan hệ Ý nghĩa
Trang 6! Phép NOT !5 có giá trị sai
Thứ tự ưu tiên của các phép toán logic: !, &&, ||
Ví dụ:
!3 > 5 = 0 > 5 = 0 (sai)
!(3>5) = !0 = 1 (đúng)
!!5 = !0 = 1 (đúng)
1.4.5 Các phép toán trên bit
Ngôn ngữ C còn cung cấp cho chúng ta những toán tử để thao tác trên các bit (0 và 1) Các toán tử này bao gồm:
& Phép AND từng bit
Trang 7Các phép dịch trái (<<) 1 bít tương đương nhân 2, dịch phải (>>) 1 bít tương đương với chia 2
a << n; /*tương đương với a*(2 n
1.5.2 Cấu trúc chương trình
Một chương trình C thường có cấu trúc như sau:
#include < > /* Gọi các tệp tiêu đề trong chương trình */
#define /* Khai báo hằng số hay còn gọi là macro*/
typedef /* Định nghĩa kiểu dữ liệu */
/* Nguyên mẫu các hàm: khai báo tên hàm và các tham số */
/* Khai báo các biến toàn cục */
main()
{
Trang 8/* Khai báo biến */
/* Các câu lệnh */
}
/* Định nghĩa các hàm */
Như vậy, trong một chương trình C, có thể có nhiều phần khác nhau: khai báo, định nghĩa, Tất cả
các phần này đều là tùy chọn (có thể có hoặc không có), trừ định nghĩa hàm main( ) bắt buộc phải có Hàm main( ) là hàm chính trong một chương trình C, định nghĩa hàm main( ) là bắt buộc
Ví dụ: chương trình đơn giản nhất
a) #include Dùng để gọi các tệp tiêu đề vào chương trình, các tệp tiêu đề này chứa các hàm chuẩn
hoặc các hàm do người sử dụng định nghĩa
Cú pháp: #define tên_macro phần_thay_ thế
Khi biên dịch chương trình, nếu gặp tên_macro thì được thay bởi phần_thay_ thế
Ví dụ:
Lưu ý:
- Mỗi chỉ dẫn (#) được viết trên một dòng
- Nếu cuối phần_thay_ thế của macro có dấu “;” thì cũng được xem là một phần của nó
Ví dụ:
Trang 9#define BYE printf(“Tạm biệt”);
- Các từ khóa và hàm chuẩn đều là chữ thường; các macro chuẩn là chữ hoa Ví dụ: sin, log, for, RED, XOR_PUT
- Nên dùng chữ hoa đặt tên macro
c) Khai báo biến
Muốn sử dụng một biến, bắt buộc phải khai báo trước khi sử dụng
Cú pháp: kiểu_dữ_liệu danh_sách _biến;
Ví dụ:
float x, y, so_thuc; /* khai báo 3 biến x, y, so_thuc kiểu số thực*/
Lưu ý, khi khai báo biến chúng ta có thể khởi tạo giá trị cho biến như sau:
int a, b = 100;
b có giá trị đầu 100, a có giá trị đầu là giá trị ngẫu nhiên
d) Khai báo biến hằng
Biến hằng là biến trong bộ nhớ nhưng chương trình không được thay đổi
Cú pháp: const kiểu tên_hằng = giá_trị_hằng ;
- Đặt tên cho các đại lượng nên có tính gợi nhớ, có ý nghĩa
- Nên viết thêm các lời giải thích bên cạnh lệnh cho rõ
Trang 10Ví dụ:
a = 1; /* biến a nhận giá trị 1 */
b = a + 1; /* biến b nhận giá trị biểu thức a + 1 tức là giá trị 2 */
Biểu thức gán có giá trị là giá trị của biến sau khi gán
Ví dụ:
a = b = c = 1; /* gán giá trị 1 cho cả 3 biến a, b, c */
x = a + (y = 3); /* y nhận giá trị 3, sau đó x nhận giá trị của a + y, nghĩa là x = 4 */
i++; /* i = i+1 hoặc i+=1; hoặc ++i; */
Nếu đặt trước biến thì giá trị của biến tăng/giảm trước khi thực hiện lệnh Tương tự, cho đặt sau biến thì giá trị của biến tăng/giảm sau khi thực hiện lệnh
Như vậy, a phải được thực hiện trước, sau đó thực hiện b = 2 + 2 = 4.
Lệnh b = a + a; tương đương với các lệnh: a; b = a + a;
Trang 11Câu hỏi và bài tập chương 1
1 Các tên nào sau đây là hợp lệ?
diemtin, Lop13T, 15X3b, Bach-Khoa, Dai_Hoc, USDto$, La#, diem toan, 3diemtoan,
_diemtoan, -diemtoan, 3a_1, num-odd, int, del ta, f(x)
2 Các khai báo nào sau đây là hợp lệ?
a) int bien n;
b) float x, y;
c) char do, xanh ;
3 Với giá trị ch=‟M‟ Cho biết giá trị của các biểu thức sau:
5 Hãy đặt cặp ngoặc đơn theo thứ tự ưu tiên vào các biểu thức sau:
a) c!=‟$‟ || ch>=‟A‟ && ch<=‟Z‟ || ch>=‟0‟ && ch<=‟9‟
6 Tính giá trị cuối cùng của các biến sau khi thực hiện các lệnh?
a) int a=2, b=3, c; c=a+2*b++; a=5+a ; b=c+++a++;
b) char a=‟A‟, b, c; b=a+2; c=++b-1;
c) int m = -14, n = 6, p; p = m % ++n; n += m++ - p; m <<= (p ^ n) & 3;
7 Viết biểu thức kiểm tra biến chữ cái ch có phải là chữ hoa hay không
8 Giả sử biến chữ cái ch là chữ hoa Viết lệnh đổi ch sang chữ thường
9 Giả sử biến chữ cái ch là chữ thường Viết lệnh đổi ch sang chữ hoa
10 Viết biểu thức kiểm tra biến ký tự ch có phải là chữ cái hay không
Trang 1211 Viết biểu thức kiểm tra biến ký tự num có phải là chữ số hay không
12 Viết biểu thức kiểm tra biến ký tự op có phải là phép toán (+,-,*,/,^,~) hay không
13 Viết biểu thức kiểm tra biến ký tự ch có phải là chữ cái hoặc chữ số hay không
14 Năm nhuận (có ngày 29/2) là năm chia hết cho 4 mà không chia hết cho 100 hoặc chia hết cho
400 Viết biểu thức kiểm tra năm n có phải là năm nhuận hay không
Trang 13In ra màn hình chuỗi_định_dạng cùng các giá trị của danh_sách_biểu_thức đặt tương ứng vào các vị
trí có chỉ định kiểu in ra với ký hiệu “%”
Ví dụ:
printf(“Nghiem cua phuong trinh bac 2 la: x1 = %f, x2 = %f\n”, x1, x2);
Trong đó “%f ” là kí tự định dạng cho phép in ra giá trị của một số thực, “\n” là kí tự điều khiển sang
dòng mới
Dưới dây là một số chuỗi kí tự định dạng thường sử dụng:
%c In ra một kí tự kiểu char
%d, %i In ra số nguyên thập phân kiểu int
%u In ra số nguyên không dấu kiểu unsigned int
%ld In ra số nguyên kiểu long
%lu In ra số nguyên kiểu unsigned long
%f In ra số thực với phần thập phân mặc định có 6 chữ số
%s In ra chuỗi kí tự
%x, %X In ra số nguyên dưới dạng cơ số 16 (hexadecimal)
%o In ra số nguyên dưới dạng cơ số 8 (octal)
%e, %E, %g, %G In ra số thực dạng khoa học
Ví dụ:
In kí tự %c và số nguyên %d:
Trang 14printf(“%c va %c co ma ASCII tuong ung la %d va %d\n”, „a‟, „A‟, „a‟, „A‟);
Kết quả trên màn hình là:
a và A co ma ASCII tuong ung la 97 va 65
Lưu ý: kiểu kí tự char được xem là kiểu số nguyên Tùy vào chuỗi định dạng được sử dụng mà kết
quả in ra là ký tự hay số
In số nguyên dưới dạng biểu diễn cơ số 16 và cơ số 8:
printf(“Số %d có dạng cơ số 16 là %x hoặc %X có dạng cơ số 8 là %o\n”, 90, 90, 90);
Có thể chỉ định canh cột tiếp sau ký tự “%” Nếu số cột canh lề lớn hơn độ dài của biểu thức thì canh
lề phải; là số âm thì canh lề trái; bằng 0 thì không canh lề Để dễ đếm các kí tự, chúng ta sẽ sử dụng kí tự
để chỉ ra ký tự trống
Ví dụ:
printf(“|%5d|%-5c|%s|”, 123, „A‟,”ABC”);
Cho kết quả là: |123|A |ABC|
Với số thực, có thể chỉ định thêm “%n.d” để canh n cột và lấy d chữ số thập phân
Trang 15chuỗi_định_dạng chỉ định kiểu dữ liệu nhập vào cho các biến tương ứng trong danh_sách_địa_chỉ,
dùng ký tự “%” như với lệnh printf Dấu “&” đặt trước một biến để lấy địa chỉ của biến
Nên dùng lệnh printf trước lệnh scanf để hiển thị thông báo thông tin cần nhập
Các giá trị nhập vào cách nhau khoảng trống, nhập xong ấn Enter (ký hiệu được dùng để chỉ ấn Enter)
Ví dụ: Nhập vào 2 số nguyên, tính tổng và tích của chúng
#include <stdio.h>
main()
{
Trang 16đệm bằng cách thêm ký hiệu “%*c” trong chuỗi điều khiển như:
scanf(“%d%d%*c”, &a, &b);
2.3 Một số tệp tiêu đề chuẩn
Trong C có rất nhiều tệp tiêu đề, đây là nơi chứa các khai báo và định nghĩa cho các hàm đã được xây dựng sẵn Các hàm này được gộp lại theo chức năng vào các tệp tiêu đề khác nhau
Hàm chuẩn là một số hàm đã được khai báo và định nghĩa sẵn bởi Ngôn ngữ C mà chúng ta có thể sử
dụng Để sử dụng các hàm chuẩn, thông thường chúng ta phải sử dụng #include để chỉ cho chương trình
biết các hàm chuẩn đó được chứa trong tệp tiêu đề nào
int getch( ); Nhận một kí tự nhập từ bàn phím, không hiện ký tự trên màn hình
int getche( ); Nhận một kí tự nhập từ bàn phím, có hiện ký tự trên màn hình
int kbhit(void); Kiểm tra trạng thái có nhấn phím Nếu có nhấn phím thì trả về 1; ngược lại, trả về 0
void textbackground(int c); Đặt màu nền là màu c Các hằng màu có giá trị 0 15
void textcolor(int c); Đặt màu chữ là màu c
int wherex(void); Lấy hoành độ hiện thời Giá trị trả về trong 1 80
int wherey(void); Lấy tung độ hiện thời Giá trị trả về trong 1 25
void gotoxy(int x, int y); Di chuyển đến toạ độ (x,y) Màn hình mặc định là 80x25
Trang 172.3.3 Tệp tiêu đề stdlib.h
void randomize(); Khởi động bộ tạo số ngẫu nhiên, phải gọi trước hàm rand()
int random(int n); Lấy một số nguyên ngẫu nhiên trong khoảng từ 0 n-1
int rand( ); Lấy một số nguyên ngẫu nhiên trong khoảng từ 0 RAND_MAX -1 RAND_MAX=32767 Giống như gọi random(RAND_MAX);
2.3.4 Tệp tiêu đề math.h
int abs(int x); Hàm trị tuyệt đối số nguyên x kiểu int
double fabs(double x); Hàm trị tuyệt đối số thực x
long labs(long x); Hàm trị tuyệt đối số nguyên x kiểu long
double ceil(double x); Hàm làm tròn trên Lấy giá trị nguyên nhỏ nhất >=x
double floor(double x); Hàm làm tròn dưới Lấy giá trị nguyên lớn nhất <=x
double sqrt(double x); Hàm căn bậc 2 đối số x, ( x)
Các hàm cos(x), sin(x), tg(x), arccos(x), arcsin(x), arctg(x), arctg(
x
y ) là
Trang 18Câu hỏi và bài tập chương 2
1 Nhập vào một số nguyên n (32 n 255) và in ra ký tự có mã ASCII là n
2 Cho biết kết quả in ra màn hình của lện sau :
7 Viết chương trình nhập ba số a, b, c là chiều dài của ba cạnh của một tam giác Tính diện tích
S của tam giác này theo công thức
S= p(pa)(pb)(pc), trong đó p là nửa chu vi hay p=
2
cb
) 1 + x ln(
+ x + x
2
4 5
3 2
b) g(x)=
1 + ) 5 - x ( arctg
) 2 +
| 3 - x (|
log + x
2 5 3
9 Viết chương trình nhập hai số thực x, y và tính giá trị các hàm hai biến sau:
a) f(x,y)=
2
π + ) y + x ( tg
) 1 + y + x ( log y + x
2
4 2 5
3 2 2
b) g(x,y)=
3 + ) x sin(
y + x cos(
-) 5 +
| y - x ln(|
+
ex+y 2
10 Viết chương trình nhập đáy trên a, đáy dưới b và chiều cao h của một hình thang Tính diện
tích và chu vi của hình thang này
Trang 19Chương 3 Lệnh điều kiện
Ý nghĩa của câu lệnh
Nếu biểu_thức đúng (có giá trị khác không) thì lệnh_1 được thực hiện; nếu biểu_thức sai (có giá trị bằng không) thì lệnh_2 được thực hiện
Trường hợp biểu_thức sai và không có lệnh_2 thì câu lệnh không làm gì
Sơ đồ khối biểu diễn câu lệnh
Hình 1 Lưu đồ thuật toán lệnh if
Ví dụ 1: Tính giá trị lớn nhất của hai số nguyên a và b
/* Chuong trinh tinh gia tri lon nhat cua hai so nguyen a va b */
Sai Bắt đầu
Bắt đầu
Trang 20printf(“Gia tri nhap vao la so am.\n”);
printf(“Ket thuc chuong trinh\n”);
Lưu ý:
Cặp ngoặc đơn sau if là bắt buộc
Cần phân biệt phép so sánh “= =” với phép gán “=” Ví dụ:
Kết quả là: not zero
Trong biểu thức ở ví dụ trên, sau if, (a=0) sẽ gán giá trị 0 cho a và biểu thức (a=0) có giá trị 0 là sai
nên lệnh printf(“not zero”); được thực hiện
3.2 Khối lệnh
Khối lệnh là một nhóm các lệnh được thực hiện cùng nhau ứng với một điều kiện cho trướng Trong ngôn ngữ C, các lệnh của khối lệnh được đặt trong cặp ngoặc móc, “{” và “}”
Trang 21Ví dụ 3: Câu lệnh sau cho phép tính giá trị max và min của hai biến a và b
Một vài lưu ý khi sử dụng câu lệnh if:
- Biểu thức điều kiện cần phải đặt trong dấu ngoặc
- Biểu thức điều kiện là đúng nếu nó có giá trị khác không, và là sai nếu nó có giá trị bằng không
- Điều kiện có thể là số nguyên hoặc thực
- Có thể sử dụng nhiều điều kiện bằng cách sử dụng các toán tử && và ||
Ví dụ, câu lệnh sau kiểm tra nếu cả hai điều kiện đều đúng:
if ((điều kiện 1) && (điều kiện 2))
Như thế, việc kết hợp các toán tử “&&” và “||” sẽ cho phép chúng ta xây dựng những biểu thức điều kiện phức tạp hơn
Ví dụ: viết câu lệnh kiểm tra ba số thực a, b, và c là ba cạnh của tam giác
if ((a > 0) && (b >0) && (c >0) && (a < b + c) && (b < a + c) && (c < a + b))
Nếu sau if hoặc else là một dãy các câu lệnh, thì các câu lệnh này phải được đặt trong dấu ngoặc
(xem ví dụ 3 ở trên), nếu chỉ là một câu lệnh thì các dấu ngoặc là không cần thiết (xem ví dụ 1 và 2 ở trên)
Lệnh điều kiện lồng nhau
Trong cú pháp, toàn bộ lệnh if … else … là một lệnh Vì vậy trong các lệnh (lệnh_1, lệnh_2) có thể là
lệnh điều kiện khác Nghĩa là lệnh điều kiện có thể lồng vào nhau
Ví dụ 4: Chương trình sau tính nghiệm của phương trình “ax + b = 0”
Trang 22Lệnh điều kiện trong chương trình trên có thể viết thành các trường hợp riêng biệt như sau:
if (a == 0 && b == 0) printf(“Phuong trinh co vo so nghiem\n”);
if (a == 0 && b != 0) printf(“Phuong trinh vo nghiem\n”);
Ví dụ 5: Chương trình xếp loại kết quả học tập của một sinh viên
printf(“Xep loai: gioi”);
else printf(“Xep loai: xuat sac”);
Có thể viết lại đoạn lệnh điều kiện như sau:
if (diem < 5) printf(“Xep loai: kem”);
if (diem >= 5 && diem < 7) printf(“Xep loai: trung binh”);
if (diem >= 7 && diem < 8) printf(“Xep loai: kha”);
if (diem >= 8 && diem < 9) printf(“Xep loai: gioi”);
Trang 23if (diem >= 9) printf(“Xep loai: xuat sac”);
3.3 Biểu thức “? :” (hay còn gọi là toán tử điều kiện)
Biểu thức
(biểu_thức_điều_kiện) ? biểu_thức_1 : biểu_thức_2
có giá trị là biểu_thức_1 nếu biểu_thức_điều_kiện là đúng; ngược lại, có giá trị là biểu_thức_2 Đây
có thể xem là cách viết gọn của câu lệnh if
Ý nghĩa của câu lệnh
Chương trình duyệt từ trên xuống để tìm giá trị hằng phù hợp với biểu_thức_nguyên để thực hiện các lệnh cho đến hết khối lệnh Nếu không có giá trị hằng nào phù hợp thì thực hiện Các_lệnh_n+1 Nếu không có Các_lệnh_n+1 và không có giá trị hằng nào phù hợp thì câu lệnh được bỏ qua
Để chỉ thực hiện các lệnh tương ứng trong từng trường hợp của biểu_thức_nguyên, chúng ta phải
dùng lệnh “break;”
Trang 24Ví dụ 6: Sử dụng lệnh switch không có break
Trang 25switch(n)
{
case 1: printf("Mùa xuân\n"); break;
case 2: printf("Mùa xuân\n"); break;
case 3: printf("Mùa xuân\n"); break;
case 4: case 5: case 6: printf("Mùa hè\n"); break;
case 7: case 8: case 9: printf("Mùa thu\n"); break;
case 10: case 11: case 12: printf("Mùa đông\n"); break;
default: printf(“Không có tháng %d!\n”, n);
}
Trang 26Câu hỏi và bài tập chương 3
1 Viết lại các lệnh sau bằng cách dùng lệnh if tương đương (có cùng kết quả)
a) m=(a<b&&a<c)? a: b<c?b:c;
b) printf(“%s”, diem>=8?”Gioi”: diem>=7?”Kha”: “trung binh”);
2 Viết lại các lệnh sau bằng cách dùng biểu thức điều kiện (“? :”) tương đương
a) if (x>y) max=x; else max=y;
) y x ( log y
) y x cos(
) y x ln(
Có kiểm tra lỗi khi hàm không xác định
5 Viết chương trình giải phương trình bậc 2 (ax2 + bx + c = 0, a0)
6 Viết chương trình giải phương trình bậc bốn trùng phương (ax4 + bx2 + c = 0, a0) Có đếm số nghiệm khác nhau của phương trình
7 Viết chương trình giải hệ phương trình gồm hai phương trình và hai ẩn x, y với các hệ số nhập
từ bàn phím
8 Viết chương trình giải hệ phương trình gồm ba phương trình và ba ẩn x, y, z với các hệ số nhập
từ bàn phím
9 Viết chương trình nhập ngày d, tháng m và năm y và thứ dow hiện tại Tính ngày, tháng này
của năm sau là thứ mấy
10 Thứ trong tuần được đánh số từ 0 đến 6: 0 là thứ Hai, 1 là thứ Ba, , 6 là Chủ nhật Công thức
tính thứ i trong tuần cho ngày D, tháng M, năm Y như sau:
i = (D + 2*M + 3*(M+1)/ 5 + Y + Y/4 - Y/100 + Y/400) % 7
Tháng 1 và 2 được tính là tháng 13 và 14 của năm trước
Viết chương trình nhập ngày D, tháng M, năm Y và in ra màn hình là thứ mấy
11 Viết chương trình mô phỏng cách gọi menu Chẳng hạn, nếu nhập vào chữ f hay F thì in ra là
bạn chọn menu File; nếu nhập vào chữ h hay H thì in ra là bạn chọn menu Help
Trang 27Ban đầu, vòng lặp thực hiện danh sách biểu thức đầu bieu_thuc_dau Trong khi biểu thức kiểm tra
b_thuc_k_tra còn đúng thì còn thực hiện lệnh và thực hiện danh sách biểu thức tăng giảm
bieu_thuc_tang_giam
Lưu ý:
- Bản chất của vòng lặp for là vòng lặp while (được bày trong phần sau), nhưng thường dùng với
vòng lặp xác định, nghĩa là biết trước số lần thực hiện/lần lặp
- Ba thành phần trong cặp ngoặc đơn là tùy chọn, nếu không có biểu thức kiểm tra b_thuc_k_tra
thì nó được xem là luôn đúng
Ví dụ: lệnh sau thực hiện lặp mãi mãi
Trang 28Hình 2 Lưu đồ thuật toán lênh for
Ví dụ 1: Chương trình sau in ra màn hình bộ ký tự ASCII
Lưu ý: nếu n có ước số là p với p> n , n=p.q, thì đã có ước số q< n Vì vậy, chỉ cần kiểm tra k=2
n Có thể thay biểu thức kiểm tra k<n bởi k*k<=n Hơn nữa, khi n có ước rồi thì không cần kiểm tra tiếp nữa, Có thể thay biểu thức kiểm tra bởi biểu thức nt && k*k<=n
Ví dụ 3: Chương trình sau giải bài toán cổ “3n+1” Nhập số nguyên dương n và thay đổi giá trị n theo quy tắc sau: nếu n lẻ thì nhân 3 cộng 1; ngược lại, n chẵn thi chia đôi n Lặp việc thay đổi giá trị n cho đến khi n=1
Trang 29printf("%d\n", n);
} }
Có thể chương trình chạy mãi mãi
Ví dụ 4: Chương trình sau nhập số nguyên n và nhập n số nguyên, tính trung bình cộng n số nguyên
Trang 304.2 Vòng lặp while
Cú pháp:
while (biểu_thức)
lệnh;
Ý nghĩa của câu lệnh:
Trong khi biểu thức có giá trị đúng (khác 0) thì lệnh được thực hiện
Sơ đồ khối biểu diễn vòng lặp while
Hình 3 Lưu đồ thuật toán lệnh while
Đây là vòng lặp không xác định số lần lặp và kiểm tra biểu thức ngay từ đầu, trước khi thực hiện lệnh
Nếu ngay từ đầu biểu_thức sai thì rơi vào trường hợp vòng lặp rỗng Ngược lại, biểu_thức luôn luôn
đúng thì rơi vào trường hợp vòng lặp vĩnh cữu
Ví dụ 6: Chương trình sau nhập số nguyên dương n và kiểm tra n có phải là số nguyên tố không
if (k*k>n) printf("%d la so nguyen to.", n);
else printf("%d la hop so.", n);
Trang 31!11
3 2
n
x x
x x e
Chương trình có gọi hàm chuẩn exp(x) để so sánh
#define EPS 1e-6
Thực hiện lệnh trong khi biểu thức còn có giá trị đúng (khác 0) Khác với vòng lặp while, vòng lặp
do while kiểm tra điều kiện sau, nên nếu biểu thức có giá trị bằng không ngay từ ban đầu thì lệnh vẫn
được thực hiện một lần
Trang 32Sơ đồ khối biểu diễn vòng lặp do while
Hình 4 Lưu đồ thuật toán lệnh do…while
Ví dụ 8: Hãy đọc một số cho đến khi số đó là số dương
Ví dụ 9: Hãy đọc kí tự vào chừng nào kí tự đó không phải là kí tự '*'
Cách viết như sau là sai:
Kết thúc
Trang 33c=getchar() while (c !='*');
Vì thiếu dấu “;” kết thúc lệnh getchar( )
Ví dụ 10: Đưa các lệnh trong các chương trình trên vào vòng lặp do…while để chạy nhiều lần:
do {
… printf(“Tiep tuc(T/K)?”); tiep=getchar( );
} while (tiep==‟t‟|| tiep==‟T‟);
Lưu ý: Dẫu một lệnh cũng nên dùng cặp ngoặc móc và while đặt cùng dòng với “}” để khỏi nhầm với
vòng lặp while
Có thể sử dụng vòng lặp do…while thay cho vòng lặp while Vòng lặp while:
while (điều kiện) lệnh;
được chuyển sang vòng lặp do…while như sau:
Trang 34Chương trình sẽ cho kết quả như sau:
Bắt đầu 1
Trang 36Câu hỏi và bài tập chương 4
1 Hãy cho biết đoạn chương trình sau làm gì ?
1 k) 1 (
= 2
1-1+
3
1
4
-1+ +
n
1n)1(
2
x
+ +
!n
n
x
với số nguyên dương n và số thực x nhập từ bàn phím
Trang 379 Giả sử thủ quỹ chỉ có các loại giấy bạc 50 nghìn, 20 nghìn, 5 nghìn và 1 nghìn đồng Viết chương
trình in ra màn hình tất cả các cách có thể nhận được n nghìn đồng với các loại tiền trên
10 Số hoàn hảo là số nguyên dương bằng tổng các ước thực sự của nó Ví dụ: 6=1+2+3 Viết chương trình in ra tất cả các số hoàn hảo nhỏ hơn 1000
11 Viết chương trình in ra tất cả các số nguyên tố từ 2 đến 1000000
12 Viết chương trình in ra màn hình bảng chân trị của các phép toán logic: AND, OR, NOT Ví dụ, với phép OR thì có kết quả in ra là
0 0 1
Dùng các phép logic tương ứng là: &&, ||, !
13 Viết chương trình giải bài toán “trâu-cỏ” như sau:
100 con trâu ăn trăm bó cỏ
Trâu đứng ăn 5, trâu nằm ăn 3
Lụ khụ trâu già, 3 con một bó
Hỏi có bao nhiêu con trâu mỗi loại?
Lưu ý: Đây là bài toán tìm các giá trị nguyên
14 Viết chương trình tính sin(x) triển khai theo chuỗi sau:
sin(x) = x/1! – x3/3! + + (-1)n.x2n+1/(2n+1)!
số phần tử được chọn cho tới khi đạt độ chính xác: |x2n+1
/(2n+1)!| < EPS=10-6 (dùng hàm fabs trong
với n nhập từ bàn phím
16 Viết chương trình nhập số nguyên dương a và kiểm tra a có phải là số tự đối xứng không?
Chẳng hạn 5, 232, 5775 tự đối xứng, nhưng 2342 thì không tự đối xứng
Trang 38Chương 5 Hàm
5.1 Giới thiệu
Một chương trình viết bằng ngôn ngữ C là một dãy các hàm, trong đó có một hàm chính (hàm
main( )) Hàm main( ) chúng ta đã gặp trong phần trước khi nói về cấu trúc của một chương trình C
Thứ tự của các hàm trong chương trình là bất kì, nhưng chương trình bao giờ cũng thực hiện từ hàm
main( )
Trước khi đi vào trình bày các chi tiết về hàm, chúng ta xem xét một ví dụ sử dụng hàm Bài toán đặt
ra là rất đơn giản: xây dựng hàm tìm giá trị lớn nhất của hai số
scanf(“%d%d”, &x, &y);
printf(“Giá trị lớn nhất của %d và %d là ”, x, y, max2so(x, y));
- Kiểu giá trị trả về của hàm
- Đối số hay tham số hình thức
- Thân hàm
- Khai báo hàm (nguyên mẫu hàm)
Trang 39Nguyên mẫu hàm được khai báo như sau:
kiểu_của_hàm tên_hàm ([danh_sách_tham_số]);
Định nghĩa một hàm như sau:
kiểu_của_hàm tên_hàm ([danh_sách_tham_số])
Trong khai báo trên:
- Kiểu của hàm là kiểu của giá trị trả về của hàm, có thể là các kiểu dữ liệu chuẩn hoặc các kiểu dữ
liệu do người dùng định nghĩa Nếu hàm không trả về giá trị thì được khai báo là kiểu void (mặc
định là int, chẳng hạn như hàm main( )) Hàm main( ) có thể khai báo kiểu void
- Muốn truyền các giá trị khác nhau cho hàm thì khai báo hàm phải có tham số để truyền Khai báo tham số như khai báo biến, nhưng không được khai báo trùng với khai báo biến Nếu hàm không
có tham số thì có thể khai báo là void hoặc bỏ trống
- Các biến khai báo bên ngoài các hàm gọi là biến toàn cục hay biến ngoại, có thể dùng ở các hàm định nghĩa sau nó Ngược lại, các biến khai báo bên trong hàm gọi là biến cục bộ hay biến nội, biến địa phương, chỉ có thể dùng ở bên trong hàm khai báo nó Trường hợp biến cục bộ trùng tên
với biến toàn cục thì lệnh trong hàm ưu tiên biến cục bộ
- Khi hàm được gọi thì các lệnh trong hàm được thực hiện cho đến khi gặp lệnh return hoặc cho đến hết hàm nếu không có lệnh return Nếu hàm không trả về giá trị, thì có thể dùng lệnh
“return;” hoặc bỏ qua
Trang 40Các hàm có thể được gọi bởi hàm main( ) và chúng có thể gọi lẫn nhau
Lệnh gọi hàm bằng tên hàm cùng các giá trị truyền cho các tham số Các giá trị truyền cho các tham
số phải truyền đúng kiểu và đúng số tham số Giá trị truyền cho tham số có thể là hằng hay là giá trị của biến, của biểu thức
Một giá trị nguyên có thể truyền cho tham số thực, hàm tự chuyển kiểu; nhưng ngược lại không thể truyền giá trị thực cho tham số nguyên
Trong các định nghĩa hàm như trên, trong hàm main( ) có thể có các lệnh sau: