You are on page 1of 315

LẬP TRÌNH C CĂN BẢN

Phạm Thế Bảo


Email: ptbao@hcmus.edu.vn
http://www.math.hcmuns.edu.vn/ptbao/c_program
Mục tiêu
• Giải quyết những bài toán cơ bản với chương
trình máy tính.
• Các khái niệm, kiến thức cơ bản về lập trình.
• Các nguyên lý, kỹ thuật lập trình cơ bản.
• Dùng ngôn ngữ lập trình C để viết.
• Cú pháp, ngữ nghĩa ngôn ngữ C/C++.
Nội dung
Ch1- Thuật toán
Ch2- Các khái niệm cơ bản
Ch3- Biến và hằng
Ch4- Phép toán và biểu thức
Ch5- Cấu trúc điều khiển rẽ nhánh, lặp
Ch6- Hàm và mảng một chiều
Tài liệu tham khảo
1. Quách Tuấn Ngọc (1998), Ngôn ngữ lập trình C,
NXB Giáo Dục.
2. Hoàng Kiếm (2001), Giải một bài toán trên máy
tính như thế nào ?, tập 1, NXB Giáo Dục.
3. Brian W.Kernigan & Dennis M.Ritchie (2000),
The C Programming Language.
4. H.M. Deitel and P.J. Deitel (1998), C++ How to
program, 2nd Edition, Prentice Hall.
Đánh giá
ƒ Bài tập trên lớp, BT về nhà, kiểm tra, …, 10%
ƒ KT giữa kì: kiểm tra thực hành trên máy, 20%
ƒ Thi cuối kì: kiểm tra viết trên giấy, 70%
Chương 1
THUẬT TOÁN
Nội dung
1. Vấn đề, bài toán
2. Thuật toán
3. Giải bài toán trên máy tính
1. Vấn đề, bài toán
Vấn đề
) Những vướng mắc, khó khăn trong cuộc sống
mà ta cần giải quyết.
Bài toán
) Một loại vấn đề mà để giải quyết, cần đến tính
toán (phép toán số, luận lí, quan hệ).
Giải quyết vấn đề, bài toán
• Bất kỳ vấn đề, bài toán ngoài đời nào cũng có thể
được chia thành trình tự nhiều công việc nhỏ hơn.
• Trình tự các công việc nhỏ này được gọi là giải
thuật giải quyết công việc ngoài đời.
• Mỗi công việc nhỏ hơn cũng có thể được chia nhỏ
hơn nữa nếu nó còn phức tạp,...
• Vấn đề mấu chốt của việc dùng máy tính giải
quyết công việc ngoài đời là lập trình.
2. Thuật toán
Thuật toán
) Là cách biểu diễn lời giải "bài toán“ rõ ràng,
chi tiết để có thể thực thi được trên máy tính.
) Là một dãy hữu hạn các bước nhằm xác định các thao
tác mà máy tính có thể thực hiện được sao cho sau
khoảng thời gian hữu hạn thì cho ra kết quả.
 Bài toán giải phương trình bậc 1 (1 Nn).
Các đặc trưng của thuật toán (1)

- Tính hữu hạn: có hữu hạn bước và phải dừng.


- Tính xác định: các bước rõ ràng, thực thi được.
- Tính đúng: quá trình thực thi theo các bước đã chỉ
ra phải đi đến kết quả như ý.
Các đặc trưng của thuật toán (2)
- Tính hiệu quả: khối lượng, không gian, thời gian
tính toán không quá “lớn”.
- Tính tổng quát: áp dụng được cho mọi trường hợp
của bài toán.
Phương pháp biểu diễn thuật toán
• Thuật toán thường được biểu diễn bằng
các ngôn ngữ sau:
– Dùng ngôn ngữ tự nhiên (N N TN )
– Dùng mã giả (NNTN + NN LT)
– Dùng lưu đồ - sơ đồ khối
Biểu diễn bằng NNTN
• Dùng ngôn ngữ thường ngày để liệt kê các bước của
thuật toán.
• Không thể hiện rõ cấu trúc của thuật toán
• Dài dòng, có thể gây hiểu lầm hoặc khó hiểu
• Không yêu cầu người viết hay đọc nắm quy tắc.
− Không có một quy tắc cố định
• Tính dễ đọc:
− viết các bước con lùi vào bên phải
− đánh số bước theo quy tắc phân cấp như 1, 1.1, ...
Biểu diễn bằng mã giả (1)
• Vay mượn các cú pháp của một ngôn ngữ lập trình
– dùng một phần ngôn ngữ tự nhiên
– bị phụ thuộc vào ngôn ngữ lập trình.
• Mọi ngôn ngữ lập trình đều có những thao tác cơ
bản
– xử lý, rẽ nhánh và lặp
– tận dụng được các khái niệm trong ngôn ngữ lập trình,
• Dễ dàng nắm bắt nội dung thuật toán
Biểu diễn bằng mã giả (2)
Một đoạn mã giả của thuật toán giải pt bậc hai
if Delta > 0 then begin
x1=(-b-sqrt(delta))/(2*a)
x2=(-b+sqrt(delta))/(2*a)
xuất kết quả : phương trình có hai nghiệm là x1 và x2
end
else
if delta = 0 then
xuất kết quả : phương trình có nghiệm kép là
-b/(2*a)
else {trường hợp delta < 0 }
xuất kết quả : phương trình vô nghiệm
Biểu diễn bằng lưu đồ (1)
Biểu tượng Ý nghĩa
N hập
Xử lý
Xuất
Quyết định
Module – CT con
Terminator
Đường đi
Biểu diễn bằng lưu đồ (2)
• Công cụ trực quan diễn đạt thuật toán.
– Biểu diễn bằng mô hình – hình vẽ
• Theo dõi được:
– sự phân cấp các trường hợp
– quá trình xử lý của thuật toán
• Phân biệt hai loại thao tác:
– Chọn lựa theo một điều kiện nào đó
– Xử lý, hành động
Biểu diễn bằng lưu đồ (3)

• Chọn lựa theo một điều kiện nào đó:


– Biểu diễn bằng một hình thoi, bên trong chứa
biểu thức điều kiện.
– Ví dụ: thao tác "nếu a = b thì thực hiện thao tác
B2, ngược lại thực hiện B4" là thao tác chọn lựa

a=b Δ=0
Biểu diễn bằng lưu đồ (4)
• Thao tác chọn lựa: có thể có hai hướng đi
– một hướng ứng với điều kiện thỏa
– một hướng ứng với điều kiện không thỏa.
– 2 cung có nhãn
• Đ/Đúng,Y/Yes
• S/Sai,N /N o
Biểu diễn bằng lưu đồ (5)

• Xử lý, hành động:


– Biểu diễn bằng một hình chữ nhật, bên trong
chứa nội dung xử lý.
– Ví dụ: "Chọn một môn học và in ra." là một
thao tác thuộc loại hành động.

tăng i lên 1 chọn 1 hộp bất kỳ


Biểu diễn bằng lưu đồ (6)

• Quá trình thực hiện các thao tác:


– Đường đi – route
– Biểu diễn bằng cung có hướng
• nối giữa 2 thao tác: thực hiện lần lượt
Biểu diễn bằng lưu đồ (7)
• Ðiểm cuối (terminator)
– Biểu diễn bằng hình ovan
– Điểm khởi đầu
• chỉ có cung đi ra
• bên trong ovan ghi chữ: bắt đầu/start/begin
– Điểm kết thúc
• Chỉ có cung đi vào
• bên trong ovan ghi chữ: kết thúc/end
• Mỗi lưu đồ chỉ có 1 điểm bắt đầu và 1 điểm kết
thúc.
Phương trình thuật toán giải pt
bậc 2. Đường chấm ứng với
trường hợp nghiệm kép, ví dụ:
a=1,b=2,c=1
Biểu diễn bằng lưu đồ (8)
• Điểm nối (connector)
– N ối các phần khác nhau của một
lưu đồ
– N ối sang trang
– Sử dụng với lưu đồ phức tạp
• Giảm độ rắc rối
• Đặt ký hiệu
liên hệ giữa các
điểm nối
3. Giải bài toán trên máy tính (1)
Các bước giải quyết vấn đề, bài toán bằng máy tính
điện tử (MTĐT):
1) Xác định vấn đề, bài toán: xác định rõ yêu cầu của bài
toán, bài toán cho gì (Input) và yêu cầu tìm gì (Output).
2) Lựa chọn phương pháp giải: Có thể có nhiều cách
khác nhau để giải bài toán. Các phương pháp có thể
khác nhau về thời gian thực hiện, chi phí lưu trữ dữ
liệu, độ chính xác, … => tùy theo nhu cầu cụ thể mà
chọn phương pháp giải thích hợp.
3. Giải bài toán trên máy tính (2)
3) Xây dựng thuật toán: xây dựng mô hình chặt chẽ,
chính xác hơn và chi tiết hơn cho phương pháp giải
đã chọn. Xác định rõ ràng dữ liệu vào, ra cho các
bước thực hiện cơ bản và trật tự thực hiện các bước
đó. N ên áp dụng phương pháp thiết kế có cấu trúc, từ
thiết kế tổng thể tiến hành làm mịn dần từng bước.
4) Cài đặt chương trình: mô tả thuật giải bằng chương
trình. Dựa vào thuật giải đã được xây dựng, căn cứ
quy tắc của một ngôn ngữ lập trình để soạn thảo ra
chương trình thể hiện giải thuật thiết lập ở bước 3.
3. Giải bài toán trên máy tính (3)
5) Hiệu chỉnh chương trình: Cho chương trình
chạy thử để phát hiện và điều chỉnh sai sót nếu
tìm thấy. Có hai loại lỗi: lỗi cú pháp và lỗi ngữ
nghĩa.
6) Thực hiện chương trình: Cho MTĐT thực hiện
chương trình. Tiến hành phân tích kết quả thu
được. Việc phân tích kết quả nhằm khẳng định
kết quả đó có phù hợp hay không. N ếu không,
cần kiểm tra lại toàn bộ các bước một lần nữa.
Bài tập
Một công ty, mỗi giờ làm việc của một công nhân được
trả 10,000 đồng/giờ trong 8 giờ đầu làm việc theo qui
định.

N ếu làm tăng ca (phải làm nhiều hơn 8 giờ qui định),


thì mỗi giờ vượt qui định được trả thêm 30%.

Tính tiền công cho một công nhân tùy theo giờ làm
việc của họ.
CHƯƠNG 2
CÁC KHÁI NIỆM CƠ BẢN
Nội dung
1. Ngôn ngữ lập trình
2. Chương trình dịch
3. Soạn thảo mã nguồn-Biên dịch-Liên kết và
thực thi
4. Ví dụ chương trình C
5. Các thành phần của chương trình C đơn giản
1. Ngôn ngữ lập trình (1)
• Con người liên lạc với nhau dùng:
– ngôn ngữ tự nhiên: các mẫu từ ngữ và âm thanh
• Con người “nói chuyện” với máy tính dùng:
– Ngôn ngữ lập trình: tập từ ngữ và ký hiệu
• Tuân theo các luật được gọi là cú pháp (syntax)
• Có rất nhiều ngôn ngữ lập trình đang được sử
dụng.
1. Ngôn ngữ lập trình (2)
• Dựa vào mức độ chi tiết hóa việc mô tả các thao
tác, người ta chia ngôn ngữ lập trình thành các
lớp:
– Ngôn ngữ máy,
– Hợp ngữ,
– Ngôn ngữ cấp cao.
• Các ngôn ngữ cấp cao gần với ngôn ngữ tự nhiên
nên rất tiện lợi cho việc mô tả các thao tác và dễ
học, dễ nhớ.
1. Ngôn ngữ lập trình (3)
+1300042774
Ngôn ngữ máy +1400593419
+1200274027

LOAD A
Hợp ngữ ADD B
STORE C

Ngôn ngữ cấp cao C=A+B


Ngôn ngữ máy (1)
• Là ngôn ngữ nền tảng của bộ vi xử lý, còn được
gọi là mã máy.
• Tập lệnh của ngôn ngữ máy phụ thuộc vào loại vi
xử lý nên ngôn ngữ máy sẽ khác nhau trên những
máy tính có sử dụng bộ vi xử lý khác nhau.
• Các chương trình được viết bằng các loại ngôn
ngữ khác cuối cùng đều được chuyển thành ngôn
ngữ máy trước khi chương trình đó được thi hành.
Ngôn ngữ máy (2)
• Ưu điểm viết chương trình bằng ngôn ngữ máy:
– điều khiển máy tính trực tiếp
• đạt được chính xác điều mình muốn làm.
• hiệu quả về tốc độ thi hành, kích thước chương trình nhỏ
=> ngôn ngữ máy cho phép khai thác triệt để khả
năng của máy tính.
• Bất lợi của chương trình ngôn ngữ máy
– Tốn rất nhiều thời gian để viết,
– Rất khó đọc, khó theo dõi để tìm lỗi
– Chỉ chạy được trên những máy tính có cùng bộ vi xử lý.
=> ngôn ngữ máy được gọi là ngôn ngữ cấp thấp.
Hợp ngữ
• Tương tự như ngôn ngữ máy nhưng sử dụng các
ký hiệu gợi nhớ để biểu diễn cho mã lệnh của
máy.
• Cho phép định địa chỉ hình thức (dùng tên hoặc ký
hiệu để tham chiếu tới một vị trí bộ nhớ) thay vì
phải sử dụng địa chỉ thực sự (bằng con số nhị
phân) như ngôn ngữ máy.
• Được phát triển nhằm giúp lập trình viên dễ nhớ
các lệnh của chương trình.
• Các chương trình hợp ngữ được chuyển sang mã
máy thông qua trình hợp dịch (assembler).
Ngôn ngữ cấp cao
• Hợp ngữ vẫn còn rất gần với từng thiết kế của máy
tính.
• Cần có những ngôn ngữ lập trình gần với ngôn
ngữ tự nhiên hơn, được gọi là ngôn ngữ cấp cao.
• Ngôn ngữ cấp cao bao gồm: danh từ, động từ, ký
hiệu toán học, liên hệ và thao tác luận lý. Các yếu
tố này có thể được liên kết với nhau tạo thành câu
lệnh.
• Ưu điểm viết chương trình bằng ngôn ngữ cấp
cao:
– Dễ đọc và dễ học
– Không phụ thuộc vào máy tính
VD01

// Chuong trinh tinh bieu thuc y= 3e^cos(t+1)


#include<iostream.h>
#include<math.h>
void main()
{
double t, y;
cout<<”Moi ban nhap 1 so thuc t: ”;
cin>>t;
y= 3*exp(cos(t+1));
cout<<”Gia tri cua bieu thuc can
tinh la: ”<< y;
}
Các thành phần của ngôn ngữ
lập trình
• Mỗi ngôn ngữ lập trình thường có ba thành phần cơ
bản:
– Bảng chữ cái: là tập hợp các kí tự được dùng khi viết
chương trình, ngoài các kí tự này không được phép dùng bất
kì kí tự nào khác.
– Cú pháp: là bộ quy tắc để viết chương trình. Dựa vào
chúng, người lập trình và chương trình dịch biết được tổ
hợp nào của các kí tự trong bảng chữ cái là hợp lệ và tổ hợp
nào là không hợp lệ. Nhờ đó, có thể mô tả chính xác thuật
toán để máy thực hiện.
– Ngữ nghĩa: xác định ý nghĩa thao tác cần phải thực hiện,
ứng với mỗi tổ hợp kí tự và dựa vào ngữ cảnh của nó.
Ví dụ
• Hầu như các ngôn ngữ lập trình đều có kí tự + chỉ
phép cộng. Xét các biểu thức:
A + B (1)
I + J (2)
• Giả thiết A, B là các biến thực và I, J là các biến
nguỵên.
• Khi đó dấu trong biểu thức (1) sẽ được hiểu là cộng
hai số nguyên, dấu + trong biểu thức (2) sẽ được hiểu
là cộng hai số thực.
• Như vậy, cú pháp cho biết cách viết một chương
trình hợp lệ,
• Còn ngữ nghĩa xác định tính chất, thuộc tính của các
tổ hợp kí tự trong chương trình.
2. Chương trình dịch
• Chuyển đổi chương trình từ NN cấp cao
(hợp ngữ) thành NN máy.
• Có hai kỹ thuật chính:
– Trình biên dịch (compiler),
– Trình thông dịch (interpreter).
Trình biên dịch
• Chuyển đổi toàn bộ chương trình sang ngôn ngữ máy
và lưu kết quả vào đĩa để có thể thi hành về sau.
– Chương trình nguồn (source program) là chương trình ngôn
ngữ cấp cao được chuyển đổi.
– Chương trình đối tượng (object program) là chương trình
ngôn ngữ máy được tạo ra.
• Thực hiện
– Duyệt, kiểm tra cú pháp chương trình,
– Kiểm tra logic và đảm bảo các dữ liệu sử dụng được định
nghĩa hợp lý,
– Phát hiện và tạo ra một danh sách lỗi cú pháp của các mệnh
đề (statement).
• Phương pháp dịch này thuận tiện cho các chương
trình ổn định và cần thực hiện nhiều lần.
Trình thông dịch
• Lần lượt dịch và thực hiện từng câu lệnh một.
• Mỗi lần chạy chương trình là mỗi lần chương trình
nguồn được thông dịch sang ngôn ngữ máy.
• Ưu điểm
– Có thể chạy một chương trình vẫn còn lỗi cú pháp.
• Nhược điểm
– Chậm hơn các chương trình được biên dịch.
• Phương pháp dịch này thích hợp cho môi trường đối
thoại giữa người và hệ thống.
• Đa số các ngôn ngữ cấp cao đều dùng trình biên dịch.
3. Soạn thảo mã nguồn – Biên dịch
– Liên kết và thực thi (1)
• Mỗi ngôn ngữ lập trình có một vài môi trường lập
trình tương ứng.
• Ví dụ ngôn ngữ C có các môi trường lập trình
Turbo C, Borland C, Microsoft Visual C++, …
• Môi trường lập trình cung cấp các dịch vụ như:
– Soạn thảo mã nguồn,
– Lưu trữ, tìm kiếm,
– Xác định loại lỗi nếu có, chỉ rõ lỗi ở câu lệnh nào,
– Cho xem các kết quả trung gian,
– …
3. Soạn thảo mã nguồn – Biên dịch
– Liên kết và thực thi (2)
• Các môi trường lập trình khác biệt nhau ở các loại
dịch vụ mà nó có thể cung cấp.
• Đặc biệt là các dịch vụ mở rộng, nâng cấp, tăng
cường các khả năng mới cho ngôn ngữ lập trình.
• Khi biên dịch chương trình nguồn, người lập trình
sẽ phát hiện được các lỗi cú pháp.
• Khi liên kết và thực thi chương trình trên dữ liệu
cụ thể thì mới phát hiện được các lỗi ngữ nghĩa.
3. Soạn thảo mã nguồn – Biên dịch
– Liên kết và thực thi (3)
C libaray

Edit hello.c compile hello.o Link hello

Source File Object File Executable


(High-Level (Machine
Languages) Languages)

Trình biên dịch


4. Ví dụ chương trình C
/* Chương trình tính tổng các số tự nhiên từ 1 đến N */
#include<iostream.h>
int sum(int n); //khai bao ham
void main()
{
int S, n; //biến lưu tổng và số n được cho ban đầu
cout<<”Moi nhap vap so n: ”;
cin>>n;
S = sum(n); //gọi hàm tính tổng
cout<<”Tong cac so tu nhien nho hon ”<<n
<< “ la: ”<< S;
}
int sum(int n) //Dinh nghia ham sum
{
int i, S =0;
for (i=0; i<=n; i++)
S = S+i;
return S;
}
Một số qui tắc khi viết chương trình C
• Mỗi câu lệnh có thể viết trên một hay nhiều dòng
nhưng phải được kết thúc bằng dấu “;”.
• Chú thích có thể được viết trên một dòng, nhiều
dòng hoặc trên phần còn lại của câu lệnh.
• Khi sử dụng một hàm thư viện cần khai báo hàm ở
đầu chương trình bằng cách toán tử #include, ví
dụ: #include<iostream.h>
• Một chương trình chỉ có một hàm chính (main), có
thể có thêm vài hàm khác (gọi là hàm con).
5. Các thành phần của chương trình
C/C++ đơn giản (1)
(1) #include <??>
yêu cầu trình biên dịch đọc tập tin chứa các khai báo như
khai báo hàm thư viện mà chương trình dùng.

VD: iostream.h → cout, cin, ...


stdio.h → printf, scanf, ...
math.h → sqrt, sin, log, pow, ...
conio.h → getch, clrscr, ...
5. Các thành phần của chương trình
C/C++ đơn giản (2)
(2) Hàm chính, là thành phần buộc phải có
trong mọi chương trình C.
Dạng đơn giản:
void main(){ }
int main() { return 0; }
main() { return 0; }
5. Các thành phần của chương trình
C/C++ đơn giản (3)
(3) Định nghĩa dữ liệu và các phát biểu.
- Các phát biểu là phần thực thi của chương trình.
(đọc từ bàn phím, xuất ra màn hình, thực hiện tính toán, gọi hàm,...)

- Các phát biểu được đặt giữa cặp ngoặc { và } của hàm
(main), tạo nên “thân hàm”.
- Mỗi phát biểu đơn (câu lệnh) được kết thúc bởi ‘;’
- Các phát biểu cùng được đặt giữa { và } tạo thành phát
biểu ghép (còn gọi khối lệnh).
5. Các thành phần của chương trình
C/C++ đơn giản (4)
(4) Khai báo hàm và định nghĩa hàm.

Khai báo hàm là đưa ra một “mẫu hàm”, gồm tên


và các tham số của hàm (kết thúc bởi ;).
int sum(int n);

Định nghĩa hàm gồm tên hàm, các tham số và thân


hàm (chứa các phát biểu chương trình), thực thi
một việc cụ thể.
5. Các thành phần của chương trình
C/C++ đơn giản (5)
(5) Các chú thích, được trình biên dịch “bỏ qua”, không
ảnh hưởng đến việc thực thi của chương trình.
Có hai loại chú thích:
• Chú thích khối, chú thích là phần văn bản đặt giữa /* và */
• Chú thích dòng, chú thích là phần văn bản đặt ngay sau cặp kí
tự: //
Xuất dữ liệu (1)
• cout là đối tượng xuất chuNn, xuất dữ liệu ra màn hình.
• Một phát biểu xuất kết quả ra màn hình, bao gồm: cout,
phép toán xuất <<, đối tượng được xuất, và ‘;’.
Xuất dữ liệu (2)

Một đối tượng được xuất có thể là:


─ Số nguyên (số thực) hay biến nguyên (biến thực).
─ Kí tự (một hằng kí tự được đặt giữa cặp dấu ‘ ’) hoặc
biến kiểu kí tự.
─ Thông điệp gồm nhiều kí tự (chuỗi kí tự) được đặt
giữa cặp dấu “ ”.
Định dạng xuất, như: cho phép có bao nhiêu số ở phần
thập phân, canh lề phải dữ liệu xuất...
Xuất dữ liệu (3)
• N hiều phát biểu xuất có thể được nối lại thành một
phát biểu xuất, khi đó cần lưu ý là trước mỗi đối
tượng được xuất là một phép toán xuất và ngược
lại.
• Các đối tượng được xuất ra sẽ liên tiếp nhau trên
cùng một dòng.
• N ếu muốn một đối tượng được xuất ra trên một
dòng mới thì gọi endl hay “\n” trong phát biểu
xuất.
Nhập dữ liệu
• cin là dòng nhập chuNn, đọc dữ liệu được gõ từ bàn
phím.
• Dạng tổng quát: cin>> var;
var là một biến nào đó
• Phát biểu nhập có nhiều đối tượng:
cin>>var1>>var2…>>varN
CHƯƠNG 3

BIẾN VÀ HẰNG
Nội dung
1. Danh hiệu
2. Từ khóa
3. Kiểu dữ liệu
4. Khái niệm biến, vùng nhớ cho biến
5. Các kiểu cơ bản của biến
6. Định nghĩa kiểu với typedef
7. Định nghĩa biến và gán trị cho biến
8. Hằng
1. Danh hiệu (1)
• Danh hiệu: được dùng để xác định các đại lượng khác
nhau trong một chương trình như biến, hằng, hàm,… Là
dãy kí tự liền nhau, gồm:
- kí tự chữ
- kí tự số
- kí tự ‘_’ (underscore character).
• Qui tắc (đặt tên):
- Chỉ có thể bắt đầu với một kí tự chữ hoặc kí tự ‘_’
- Không trùng “từ khóa”.
- Phân biệt chữ in, chữ thường.
1. Danh hiệu (2)

Xét các ví dụ sau:


DiemMon1
Dong$
1HK
_diemTB
123$
int
diem HK
2. Từ khóa (key words)
• Là những “tên” đã được định nghĩa bởi ngôn ngữ,
dùng cho những mục đích khác nhau:

void char if return static


do int else sizeof register
for long switch enum goto
while float case typedef struct
break double default unsigned continue
3. Kiểu dữ liệu
• Xét tập N, Z, Q, R, C ?!
• Kiểu dữ liệu (KDL) được xác định bởi:
– tập giá trị, và
– tập các phép toán tác động lên các phần tử thuộc tập
giá trị ấy.
• Đơn vị lưu trữ là byte. Mỗi giá trị thuộc một KDL
được biểu diễn bởi một số byte nhất định.
=> Các giá trị biểu diễn được là hữu hạn.
4. Khái niệm biến, vùng nhớ cho biến (1)

• Là nơi lưu trữ dữ liệu trong bộ nhớ máy tính,


được đặt bởi một tên.
int a;

• Mỗi biến chỉ có thể lưu một loại giá trị nhất
định, tùy thuộc kiểu biến (KDL).
4. Khái niệm biến, vùng nhớ cho biến (2)
4. Khái niệm biến, vùng nhớ cho biến (3)

• Giá trị của biến có thể thay đổi, nhưng tại mỗi thời
điểm một biến chỉ lưu một giá trị.
5. Các kiểu dữ liệu cơ bản
• Kiểu số nguyên (int)
• Kiểu số thực
– Số dấu phNy động độ chính xác đơn (float)
– Số dấu phNy động độ chính xác kép (double)
• Kiểu ký tự (char)
Kiểu số nguyên (1)
char unsigned char
int unsigned int
long unsigned long

Biểu diễn hằng giá trị:


1234 (kiểu int)
1234U (kiểu unsigned int)
1234L (kiểu long)
1234UL (kiểu unsigned long)
Kết quả
Kiểu số nguyên (2)
Các phép toán trên số nguyên:
+ – * / %
9/4 → 2
1/2 → 0
9%5 → 4
Kết quả
Kiểu số nguyên (3)
Các tiếp đầu ngữ: long, short, signed, unsigned với
kiểu nguyên:
short int → short
signed int ≡ int
unsigned int → unsigned
long int →long
Kiểu số thực (1)
float double
Hai cách biểu diễn số thực:
- Dạng thập phân: phần nguyên & phần phân.
12.345 -0.02468
- Dạng chấm động: phần định trị & phần mũ.
1.2345e+01 -2.468e-02
Biểu diễn hằng giá trị:
12.34 (kiểu double) 1.234e+01
12.34F (kiểu float) 1.234e+01F
Kiểu số thực (2)
• Các phép toán trên số thực:
+ – * /
• Độ chính xác:
float: 7 chữ số thập phân
double: 15 chữ số thập phân
⇒Kiểu double được lưu ý sử dụng:
- Tính toán với số lớn.
- Cần độ chính xác cao.
Kết quả
Kiểu kí tự (1)

Biểu diễn hằng kí tự: ‘a’, ‘4’, ‘@’,...


Tập giá trị (1 byte, mã hoá được 256 kí tự):
Kí tự chữ (‘a’, ‘S’,...)
Kí tự số (‘0’,..,‘9’)
Dấu (‘@’,‘?’,..)
Kí tự điều khiển (‘\n’, ‘\t’,...)
Kí tự đặc biệt.
Kiểu kí tự (2)

Một vài kí tự điều khiển:


\\ backslash
\a alert (bell)

\b backspace \? question mark

\n newline \' single quote

\t horizontal tab \" double quote

\v vertical tab \r carriage return


Kiểu kí tự (3)
• Mỗi kí tự được lưu với một số nguyên, và theo một
thứ tự nhất định gọi là bộ mã.
• Bộ mã được dùng phổ biến là bộ mã ASCII:
‘a’ = 97
‘A’ = 65
‘0’ = 48
‘@’ = 64
...
Bảng mã ASCII
Kết quả
Kiểu kí tự (4)
Các phép toán như đối với trên số nguyên:
+ – * / %
) Thực hiện trên mã ASCII của kí tự tương ứng:
char c= ‘A’; //c= 65
cout<<c+1; → 66
c= c+1; cout<<c; → ‘B’
c= c/2; cout<<c; → ‘!’
cout<<‘a’ – ‘A’; → 32
cout<<‘8’ – ‘3’; → 5
6. Định nghĩa kiểu với typedef

- Một khai báo có thêm tiền tố typedef sẽ định nghĩa


một tên mới cho KDL (đã có).
typedef KDL tenMoi;
- Một tên được định nghĩa theo cách này được gọi là
“định nghĩa kiểu”.
Ví dụ

typedef long SoNg32;


typedef short int SoNg16;
typedef char KITU;
7. Định nghĩa biến và gán trị
• Định nghĩa biến (khai báo biến) là đặt tên và xác định
kiểu biến.
• Mọi biến cần phải được khai báo trong chương trình
trước khi sử dụng.
• Để định nghĩa một biến, dạng khai báo:
KDL tenBien;
• Định nghĩa nhiều biến cùng kiểu:
KDL bien1, bien2, bienN;
• Phép gán “=“ để thay đổi giá trị biến.
tenBien = giatri;
Kết quả
Gán trị cho biến (1)
• Gán liên tiếp là gán cho nhiều biến cùng
lúc sau khi đã khai báo các biến. Ví dụ:
int a, b;
a = b = 6;
b = (a= 3)+2;
• Khởi gán là gán trị cho biến ngay khi khai
báo biến đó. Ví dụ:
double x = 1.1234;
Gán trị cho biến (2)
• Gán kép và khởi gán: int a = b = 6;
• Chú ý phân biệt:
double x= 1.0, y= 2.0, z= 1.5;
int a, b;
a = b = 6;
int a = b = 6;
int m = 3, n = 3;
8. Hằng
•Là đại lượng không đổi trong suốt quá trình thực thi
của chương trình
•Phân biệt:
•Hằng biến
•Hằng thực sự
•Hằng ký hiệu
•Định nghĩa hằng dùng từ khóa:
•const, define, enum
Định nghĩa hằng dùng từ khóa const

const KDL TenHang = giaTriHang;

Ví dụ:
const float PI= 3.1459;
const int DVHT_m1 = 10;
Khi không định kiểu hằng, hằng có kiểu mặc định
là kiểu int
Kết quả
Định nghĩa hằng ký hiệu,
dùng từ khóa define
#define TenHang giaTriHang

Chú ý: Không dùng ‘;’


Không dùng phép gán =
Một định nghĩa chỉ một hằng
Ví dụ:
#define PI 3.1459
#define DVHT_m1 10
#define DVHT_m2 8
Kết quả
Hằng liệt kê, dùng từ khóa enum (1)

enum { hang1, hang2,…, hangN }


• Dùng khi có muốn định nghĩa nhiều hằng nguyên.
• Mặc định các giá trị hằng liên tiếp nhau, bắt đầu là 0.
enum { false, true };

enum { auto, remote, hand };


Kết quả
Hằng liệt kê, dùng từ khóa enum (2)

- Định trị bắt đầu của danh sách hằng:


enum { auto= -1, remote, hand };
enum { Mon= 2, Tue, Wed, Thu,
Fri, Sat, Sun };
Kết quả
Hằng liệt kê, dùng từ khóa enum (3)
- Định trị cho từng tên hằng:
enum { auto=-1, remote= 2, hand= 5 };
enum { start= ‘A’, mid=‘M’, end= ‘Z’ };
Kết quả
Tham chiếu (1)
• Là một tên gọi khác để truy cập đến cùng địa
chỉ (vùng nhớ) với biến đã có.
• Mẫu khai báo:
KDL & ref = var;
Ví dụ: n
int n = 3; r
3
int &r = n;
Tham chiếu (2)

Được sử dụng chính:


- Đối với tham số của hàm.
- Trong kiểu trả về của hàm.
- Cho các phép toán “nạp chồng”.
Kết quả
Kết quả
Kết quả
Tham chiếu (2)
• Không tham chiếu đến biến khác kiểu.
double x;
int &n = x; //???
• Không tham chiếu đến hằng.
const int a = 5;
int &r = a; //???
int &t = 7; //???
Tham chiếu đến biến khác
Kết quả
CHƯƠNG 4
PHÉP TOÁN VÀ BIỂU THỨC
Nội dung
1. Khái niệm biểu thức
2. Phép toán
3. Phép toán số học
4. Phép toán quan hệ
5. Phép toán luận lý
6. Chuyển kiểu
7. Tăng và giảm
8. Phép gán và biểu thức gán
9. Thứ tự thực hiện phép toán
1. Khái niệm biểu thức
• Là sự kết hợp hợp lệ giữa các toán hạng và toán tử để
diễn đạt một công thức toán học nào đó, cho một kết
quả duy nhất sau cùng.
Ví dụ: delta= b*b – 4*a*c;
pi= 4*atan(1.0);
• Biểu thức với toán tử là phép toán số học → biểu thức
số học
• Với phép toán quan hệ & luận lí → biểu thức quan hệ
& luận lí.
2. Phép toán
• Trong C, các phép toán có thể phân ra thành 3 loại
chính: phép toán số học, phép thao tác bit, phép
toán quan hệ và luận lý.
• Phép toán 1 ngôi, còn gọi là phép toán 1 toán hạng.
• Phép toán 2 ngôi, còn gọi là phép toán 2 toán hạng.
• Độ ưu tiên của phép toán qui định trình tự tính toán
trong biểu thức.
Ví dụ:
a = - 9/2*2 - 2 – 7%5;
3. Phép toán số học
• Các phép toán số học 1 ngôi: + -
• Các phép toán số học 2 ngôi: * / % + -
• Phép chia nguyên và chia không nguyên: /
Ví dụ: 11/2 = 5 11/2.0 = 5.5
• Phép toán % cho phần dư của phép chia nguyên.
• Phép toán % không áp dụng được cho các giá trị
kiểu float và double.
4. Phép toán quan hệ
• Phép toán quan hệ: > < <= >=
== !=
• Phép toán quan hệ cho ta hoặc giá trị đúng (1)
hoặc giá trị sai (0).
Ví dụ:
if (a>b)
cout<<a<<” la so lon hon !”;
if (b!=0)
cout<<a/b;
• Các phép toán quan hệ có độ ưu tiên thấp hơn so
với các phép toán số học.
5. Phép toán luận lí
• Phép toán luận lí: && || !
and or not
• Phép toán luận lý cho ta hoặc giá trị đúng (1) hoặc
giá trị sai (0).
Ví dụ: 3 && 7 có giá trị 1
• Các phép toán quan hệ và luận lí được dùng để
thiết lập điều kiện rẽ nhánh trong toán tử if và điều
kiện kết thúc chu trình trong các toán tử for, while
và do-while.
6. Chuyển kiểu (1)
• Trong một biểu thức, các toán hạng khác kiểu sẽ phải
chuyển sang cùng kiểu để tính toán.
• Chuyển kiểu tự động và chuyển kiểu tường minh.
− (1) Việc tự động chuyển kiểu được thực hiện từ
toán hạng có kiểu “hẹp” sang kiểu “rộng” hơn.
Ví dụ:
x = - 9.0/4*2/2 - 2 – 7%5;
y = - 9.0/4*2%2 - 2 – 7%5; //??
6. Chuyển kiểu (2)
• Với phép gán, kết quả của biểu thức bên phải sẽ được
chuyển thành kiểu của biến bên trái.
Ví dụ:
float x;
x = 3/4.0 + 2;
int y;
y = 3/4.0 + 2;
Kết quả
6. Chuyển kiểu (3)

(2) Chuyển kiểu tường minh:


Buộc kiểu của biểu thức chuyển sang kiểu khác.
(KDL)BTh KDL(BTh)
Ví dụ:
long a= 300000 + (long)400000;
double x= double(3)/4*4.0f;
double y= double(1/2)*100; //??
long s= s + long(n)*17000;
???
Kết quả
Kết quả
Kiểu bool (1)

• Kiểu bool được dùng để biểu diễn kết quả của


biểu thức luận lí, cho kết quả là đúng (true) hoặc
sai (false).
• Ngôn ngữ C không định nghĩa tường minh kiểu
bool, được dùng thông qua kiểu số nguyên.
− Kết quả biểu thức là true ⇒ giá trị là 1
− Kết quả biểu thức là false ⇒ giá trị là 0
Kiểu bool (2)
int a, b, c;
cin>>a>>b;
c= a>b; //c= 0 or 1
- Giá trị biểu thức là ≠ 0 ⇒ KQ ứng là true
- Giá trị biểu thức là = 0 ⇒ KQ ứng là false
if (b)
cout<<a/b;
Ví dụ 1
Kiểm tra một năm y có phải là năm nhuận ? Biết năm là
nhuận nếu là năm chia hết cho 400 hoặc chia hết cho 4
nhưng không chia hết cho 100.
int y;
cout<<“Ban hay nhap mot nam: “;
cin>>y;
if ((y%4==0 && y%100!=0)||y%400 == 0)
cout<<y<<“ la nam nhuan !”;
else
cout<<y<<“ khong la nam nhuan !”;
Ví dụ 2
Kiểm tra a, b, c có thể là 3 cạnh của một tam giác ? Tổng
chiều dài của hai cạnh bất kì luôn lớn hơn chiều dài cạnh
còn lại.
int a, b, c;
cout<<“Ban hay nhap 3 so nguyen: “;
cin>>a>>b>>c;
if ( a+b>c && a+c>b && c+b>a )
cout<<“Thoa 3 canh mot tam giac!”;
else
cout<<“Khong thoa ... ”;
⇒ Làm lại cách khác dùng mệnh đề và phép phủ định !!
Ví dụ 3
Tính tổng S = 1+3+5+...n ? (n ≥ 0)

int n, S = 0;
cout<<“Ban hay nhap so nguyen duong: “;
cin>>n;
for (int i= 1; i<n; i=i+2)
S = S+i;
cout<<“Tong so le nho hon n: S =”<<S;
Toán tử sizeof

• Cho biết kích thước (theo byte) của kiểu dữ kiệu


cơ sở (hoặc của một đối tượng cụ thể).
Ví dụ:
int n= sizeof(long); //n= 4
1= sizeof(char) ≤ sizeof(short) ≤
<= sizeof(int) ≤ sizeof(long)
7. Phép tăng và giảm (1)

• Nếu phép tăng (ký hiệu ++) đặt ngay trước tên biến, là
phép toán “tăng trước”.
• Tương tự, phép giảm (ký hiệu --) đặt ngay trước tên
biến, là phép toán “giảm trước”.
• Giá trị của biến được tăng (giảm) 1 đơn vị, sau đó giá
trị mới này được dùng trong biểu thức mà biến xuất
hiện.
int a= 5, b= 6, c;
c= ++a + b; c= a * --b;
7. Phép tăng và giảm (2)
• Nếu phép tăng đặt ngay sau tên biến, là phép toán
“tăng sau”.
• Nếu phép giảm đặt ngay sau tên biến, là phép toán
“giảm sau”.
• Giá trị hiện tại của biến được dùng trong biểu thức mà
nó xuất hiện, sau đó giá trị của biến mới được tăng
(giảm) 1 đơn vị.
int a= 5, b= 6, c;
c= a++ + b; c= a * b--;
8. Phép gán và biểu thức gán (1)
• Phép gán “=“ để thay đổi giá trị biến:
tenBien = giatri;
• Chú ý phân biệt toán tử gán với khái niệm đẳng thức
trong toán học.
• Biểu thức gán là biểu thức có dạng:
v=e
• Trong đó v là một biến, e là một biểu thức.Giá trị của
biểu thức gán là giá trị của e, kiểu của nó là kiểu của
v.
8. Phép gán và biểu thức gán (2)
• Nếu đặt dấu ; vào sau biểu thức gán thì ta được toán tử
gán:
v = e;
• Biểu thức gán có thể sử dụng trong các phép toán và
các câu lệnh như các biểu thức khác. Ví dụ 1:
a = b = 5;
thì điều đó có nghĩa là gán giá trị của biểu thức:
b=5
cho biến a. Kết quả là b = 5 và a = 5.
• Ví dụ 2: Sau khi thực hiện câu lệnh
z = (y = 2)*(x = 6);
thì y có giá trị 2, x có giá trị 6 và z có giá trị 12.
8. Phép gán và biểu thức gán (3)
• Phép toán kết hợp là phép gán cùng với phép toán,
tác động lên chính biến được gán.
+= -= *= /= %=
&= |= ^= <<= >>=
Ví dụ:
i += 2; //⇔ i = i + 2;
a *= b+1 //⇔ a = a*(b + 1);
a <<= 1 //⇔ a = a<<1;
9. Thứ tự thực hiện phép toán
• Khi thực hiện tính toán trong một biểu thức, phép
toán có độ ưu tiên cao hơn sẽ thực hiện trước.
b= (a= 3)+2;
b= a= 3 + 2;
n= 18/4*4;
• Bảng sau cho biết độ ưu tiên phép toán (thứ tự
giảm dần).
• Trừ phép gán và phép 1 toán hạng, các phép cùng
cấp sẽ ưu tiên trái hơn.
Ngoặc đơn ( )

Phép một toán hạng ! ~ ++ -- + -


(←) (type) sizeof

Ưu Cùng cấp phép nhân * / %


tiên
giảm Cùng cấp phép cộng + – >> <<
dần
Phép toán quan hệ < <= > >= == !=

Phép toán luận lí & | ^ && ||

Phép gán (←) = += -= *= /= %=


&= |= ^= <<= >>=
Ví dụ
(3.0/4 < 4.0/5) && (‘a’ < ‘b’)
(3/4 < 4/5) && (‘a’ < ‘b’)
!(48.5+2 < 50) || (2 > 4/2)
!(48.5+2 < 50) && (3> 4/2)
n&1==0
Bài tập
• Giá trị của x là 10, x và a là bao nhiêu sau khi
thực thi:
a = x++;
• Giá trị của x là 10, x và a là bao nhiêu sau khi
thực thi:
a = ++x;
CHƯƠNG 5
CÁC CẤU TRÚC
ĐIỀU KHIỂN CHƯƠNG TRÌNH
Nội dung
1. Phát biểu
2. Phát biểu if
3. Phát biểu switch
4. Phát biểu while
5. Phát biểu for
6. Phát biểu do-while
7. Phát biểu break
8. Phát biểu continue
Cấu trúc điều khiển

• Cấu trúc điều khiển xác định thứ tự các phát


biểu được thực thi.
• Cấu trúc “chọn” (if, switch) biểu diễn các
“quyết định”
• Cấu trúc “lặp” (for, while) cho phép lặp lại
nhiều lần việc thực thi các phát biểu
1. Phát biểu

• Một biểu thức trở thành một phát biểu khi nó được
kết thúc bởi dấu “;”, được gọi là phát biểu đơn.
• Các dấu { và } dùng để nhóm các khai báo và phát
biểu đơn → phát biểu ghép hay phát biểu khối.
• Về mặt cú pháp, phát biểu khối tương đương một
phát biểu đơn.
• Phát biểu khối được dùng trong định nghĩa hàm,
dùng với các phát biểu if, else, while, for,...
2. Phát biểu if (1)

expr S
Đ
statement1
statement2
...

other statements
2. Phát biểu if (2)
Dạng của phát biểu if:

if (expr)
statement;
Chỉ khi kết quả của expr là TRUE
(giá trị của expr ≠ 0),
thì statement được thực thi.
2. Phát biểu if (3)
expr S
Đ
• Phát biểu if có thể có phần else: stat1 stat1b
stat2 stat2b
if (expr) ... ...

statement_1a;
else other stats
statement_1b
• Nếu phát biểu ứng với phần if được thực thi, phần
else của if đó sẽ không được xét đến.
Toán tử điều kiện ? :

expr S

Đ
stat1 stat1b

( expr ? stat1 : stat2 )


• Kết quả biểu thức là stat1 nếu expr có giá trị ≠0
(TRUE), kết quả là stat2 nếu ngược lại.
Toán tử điều kiện ? :

Tìm max{a, b} ?
m = a>b ? a : b;
Tìm |a| ?
m = a>0 ? a : -a;
Toán tử điều kiện ? :

Xét mối tương quan giữa a và b:

cout<< (a>b ? "a la so lon hon !" :


"b la so lon hon !");

a>b ? cout<<a<<" la so lon hon !" :


cout<<b<<" la so lon hon !";
3. Phát biểu switch (1)
Đ stats(1)
expr == val_1
S
Đ stats(2)
expr == val_2
S
...

Đ stats(N)
expr == val_N
S
stats(N+1)
3. Phát biểu switch (2)
switch (expr)
{
case val_1: stats(1);
break;
Các hằng nguyên case val_2: stats(2);
break;
không trùng nhau //...
case val_N: stats(N);
break;
default:
stats(N+1);
}
Ví dụ
3. Phát biểu switch (3)

• switch → chương trình chọn lựa một trong nhiều


phương án khác nhau tùy thuộc kết quả của biểu thức
so sánh bằng.
- Mỗi val_1,..., val_N là một hằng nguyên.
- Các giá trị val_i không trùng nhau.
- Mỗi stats(i) gồm một hay nhiều phát biểu.
- break: kết thúc thực thi và thoát khỏi switch.
Ví dụ
Ví dụ
Ví dụ
Bài tập 1
• Hãy cho biết, khi nào thì phần else trong đoạn
chương trình sau được thực hiện ?

if (n > 0)
for (i = 0; i < n; i++)
if (a[i] > 0)
{
cout<<" !!! ";
return i;
}
else
cout<<”n phai duong !";
Bài tập 2
• Hãy cho cho biết, có lỗi nào trong chương trình sau ?

#include <iostream.h>
void main()
{
int x;
cin>>x;
if( x > 0)
cout<<" x duong !";
else (x < 0)
cout<<" x am !";
else
cout<<” x khong am khong duong !”;
}
Bài tập 3
• Hãy sửa đoạn chương trình sau đây (sửa ít nhất
có thể) sao cho kết quả nhận được là hợp lí ?

#include <iostream.h>
void main()
{
int x= 1:
if( x = 1);
cout<<" x bang 1";
otherwise
cout<<" x khac 1";
}
4. Phát biểu while (1)

expr
S

Đ
statement1
statement2
...

other statements
4. Phát biểu while (2)

Dạng của phát biểu while:

while (expr)
{
//statements;
}
4. Phát biểu while (3)
• Khi while thực thi :
B1. Tính toán biểu thức expr.
B2. Nếu kết quả của expr là TRUE (≠0), thì sang B3.
Nếu kết quả của expr là FALSE (=0), thì sang B4.
B3. Thực thi statement1, statement2,… thân của
while. Quay trở về B1.
B4. Kết thúc while.
(các phát biểu sau while tiếp tục thực thi).
4. Phát biểu while (4)

• Cần xác định các yếu tố:


- Điều kiện lặp = điều kiện “làm”
≠ điều kiện “dừng”.
- Làm những gì ?
- Yếu tố làm expr thay đổi ?
Tính tổng:

Lặp không dừng !!


S = 1 (?!!)
Có bao nhiêu số dương < N chia hết cho 3 ?
Hãy cho biết số nguyên N có bao nhiêu chữ số ?

/10 /10
n = 7023 n = 702 n = 70
(1) (2)
/10 (3)

n=7

/10 (4)

n=0
???
dem = (n==0);
???
5. Phát biểu for (1)
dem = gtbd

S
BThuc

Đ
CacPhatBieu

dem += gtbn

PhatBieuKhac
5. Phát biểu for (2)

• Dạng của phát biểu for:


for ( i = gtbd; BieuThuc; i += gtbn)
{
//Cac phat bieu
}
Tính tổng: S= 1 + +2 + ... + n
Tính tổng:
5. Phát biểu for (3)

Cấu trúc lặp for dựa trên biến đếm với giá trị
khởi đầu, thay đổi biến đếm và biểu thức. Dạng:
for ( gán trị đầu cho biến đếm ;
biểu thức ;
thay đổi giá trị biến đếm theo bước nhảy )
{
//Cac phat bieu
}
5. Phát biểu for (2)
• Khi phát biểu for thực thi:
B1. Gán trị ban đầu: dem = gtbd
B2. Tính toán biểu thức BThuc.
B3. Nếu BThuc là TRUE (≠0), thì sang B4.
Nếu BThuc là FALSE (=0), thì sang B6.
B4. Các phát biểu (CacPhatBieu) thân của for thực thi.
B5. Thay đổi giá trị biến đếm (dem += gtbn).
Quay trở về B2.
B6. Kết thúc for, PhatBieuKhac sau for tiếp tục thực thi
(2)
(1)

(3) (4)

(i>n)
Có bao nhiêu số dương < N chia hết cho 3 ?
(1) (2)

(3) (4)

(i≤n)
Hãy cho biết số nguyên N có bao nhiêu chữ số ?
Không nên !!
6. Phát biểu do-while (1)

statement1
statement2
...

S
expr

other statements
6. Phát biểu do-while (2)
Phát biểu do-while tính biểu thức sau thực thi các phát
biểu trong phần thân. Dạng:
do
{
//statements
}
while ( expr );
6. Phát biểu do-while (3)
• Khi phát biểu do-while thực thi:
B1. Các phát biểu (statements) thân của do-while thực thi.
B2. Tính toán biểu thức expr.
B3. Nếu expr là TRUE (≠0), quay trở về B1.
Nếu expr là FALSE (=0), kết thúc do-while.
(Các phát biểu khác sau while tiếp tục thực thi)

⇒ Như vậy, thân của do-while thực hiện ít nhất 1 lần.


Nhập đến đâu cộng đến đó !?!!
7. Phát biểu break

• Phát biểu break kết thúc cấu trúc lặp gần nhất mà nó
xuất hiện trong đó, không cần biết kết quả của expr

• Được dùng trong trường hợp thoát khỏi vòng lặp mà


không dùng đến điều kiện dừng.

• Phát biểu break thường xuất hiện cùng với phát biểu if.

• break còn được dùng để thoát khỏi switch, nếu các


nhóm lệnh (case i) không được kết thúc bằng break
thì máy có thể đi từ case i sang case i+1.
8. Phát biểu continue
• Phát biểu continue dùng để bắt đầu một lần lặp mới
của cấu trúc lặp gần nhất mà nó xuất hiện trong đó.
Cụ thể:
– Khi gặp continue bên trong phát biểu for, máy sẽ chuyển
tới bước 5 trong “sự hoạt động của for” (slide 63).

– Khi gặp continue bên trong phát biểu while hoặc do-while,
máy sẽ chuyển tới bước tính toán biểu thức (bước 1 trong
while, bước 2 trong do-while).

• Phát biểu continue thường xuất hiện cùng với phát


biểu if.
CHƯƠNG 6

HÀM và
MẢNG MỘT CHIỀU
Nội dung
1. Chương trình con
2. Khai báo hàm và định nghĩa hàm
3. Gọi hàm
4. Truyền tham số
5. Giá trị trả về
6. Phạm vi của biến
7. Biến mảng
8. Biến mảng là tham số của hàm
1. Chương trình con (1)
• Chương trình con: là một phần mã trong một chương
trình lớn hơn, phần mã này thực hiện một tác vụ cụ thể
và tương đối độc lập với phần mã còn lại.
• Một chương trình con thường được viết mã sao cho nó
có thể được gọi nhiều lần từ nhiều nơi trong thời gian
chạy của một chương trình (có thể được gọi bởi chính
nó).
• Các chương trình con thường được tập trung thành các
thư viện, là một cơ chế quan trọng cho việc chia sẻ và
tái sử dụng mã.
1. Chương trình con (2)
• Chương trình con có 2 loại: Thủ tục
(Procedure) và hàm (Function):
– Thủ tục (PROCEDURE): Dùng để thực hiện
một hay nhiều nhiệm vụ nào đó.
– Hàm (FUNCTION): Trả về một giá trị nào đó
(có kiểu vô hướng, kiểu string hoặc kiểu con
trỏ). Hàm có thể sử dụng trong các biểu thức.
1. Chương trình con (3)
• Khi nào thì nên dùng thủ tục/hàm:
– Dùng hàm:
• Kết quả của bài toán trả về 1 giá trị duy nhất (kiểu vô
hướng, kiểu string hoặc kiểu con trỏ).
• Phát biểu gọi CHƯƠNG TRÌNH CON cần nằm trong
các biểu thức tính toán.
– Dùng thủ tục:
• Kết quả của bài toán không trả về giá trị nào hoặc trả về
nhiều giá trị hoặc trả về kiểu dữ liệu có cấu trúc (Array,
Record, File).
• Phát biểu gọi CHƯƠNG TRÌNH CON không nằm trong
các biểu thức tính toán.
1. Chương trình con (4)
• Chương trình con được dùng khi xây dựng các
chương trình lớn nhằm:
– giảm đáng kể kích thước và chi phí của một chương
trình
– làm cho chương trình dễ theo dõi,
– dễ sửa chữa,
– nâng cao độ tin cậy của chương trình.
• Một đặc điểm nổi bật của chương trình con là nó
có tính đệ quy nhờ thế mà nhiều bài toán được giải
quyết dễ dàng.
• Chương trình con trong ngôn ngữ C là hàm.
2. Khai báo hàm, định nghĩa hàm (1)
• Định nghĩa hàm gồm tên hàm, các tham số và thân
hàm (chứa các phát biểu chương trình), thực thi một
việc cụ thể.
• Dạng định nghĩa hàm:
2. Khai báo hàm, định nghĩa hàm (2)
trong đó:
– Kiểu trả về (return_type, còn gọi là kiểu hàm) tương ứng
với kiểu của giá trị mà hàm trả về thông qua phát biểu
return.
– Tên hàm (func_name) được đặt theo nguyên tắc đặt tên,
nhưng nên đặt tên sao cho dễ hiểu.
– ParameterList là danh sách tham số, mỗi tham số được
xác định bởi kiểu dữ liệu và tên. Các tham số phân cách
nhau bởi dấu phẩy. Có thể là danh sách rỗng.
– Phần thân hàm nằm giữa cặp ngoặc { và }.
2. Khai báo hàm, định nghĩa hàm (3)
• Nếu không xác định return_type, mặc định sẽ là
kiểu int.
• Nếu hàm không trả về giá trị, dùng void (thay cho
return_type).
• Không được phép đặt định nghĩa hàm này trong
một hàm khác.
• Các hàm được định nghĩa không phải theo một thứ
tự nào.
• Nếu có phát biểu gọi hàm trước khi hàm được
định nghĩa thì cần có một khai báo hàm trước lời
gọi hàm đó.
2. Khai báo hàm và định nghĩa hàm

• Khai báo hàm là đưa ra một “mẫu hàm”, mô tả tên


hàm, kiểu trả về và danh sách tham số.
• Kết thúc khai báo hàm với dấu chấm phNy “;”.
• Dạng khai báo hàm:
return_type func_name (ParameterList)
• Xét các ví dụ sau:
void f1(int i, int j, float k);
void f2(int a, b, float c); //??
f3();
3. Gọi hàm
• Chỉ với định nghĩa hàm, hàm đó chưa thực thi. Hàm chỉ thực
thi khi nó được gọi.
• Để “yêu cầu” một hàm thực thi, ta “gọi” tên hàm cùng với các
tham số thực sự:
func( arg1, arg2,…); //Lưu ý: không có kiểu dữ liệu
Tham số trong chương trình con
• Chương trình con có thể không cần tham số mà
chỉ có các biến riêng (biến cục bộ).
• Trường hợp cần chuyển các giá trị cho hàm khi
gọi hàm thì cần định nghĩa danh sách tham số của
hàm, còn gọi là các tham số hình thức.
• Mỗi giá trị thực chuyển cho hàm khi gọi hàm được
gọi là đối số (hay tham số thực).
• Mỗi khi gọi hàm, có thể chuyển các đối số khác
nhau.
4. Truyền tham số (1)
• Để một hàm thực thi, cần gọi hàm với tên và
chuyển các đối số tương ứng với danh sách tham
số hình thức cả về kiểu và thứ tự.
• Truyền bằng tham trị:
– Là khi giá trị của đối số được sao chép vào cho tham số
hình thức. N hư vậy, các thay đổi cho tham số hình thức
(trong hàm) không làm thay đổi đối với tham số thực.
– Mặc định, với cách khai báo danh sách tham số với
kiểu và tên, ta có cách chuyển tham trị.
4. Truyền tham số (2)
• Truyền bằng tham chiếu:
– Khi muốn tham số hình thức và tham số thực cùng
địa chỉ (bản chất là cùng ô nhớ nhưng khác tên), ta
dùng cách chuyển tham chiếu cho hàm.
– Khai báo tham số của hàm với kí tự ‘&’ ngay trước
tên (giữa KDL và tên).
– N hư vậy, mọi thay đổi đối với tham số hình thức
cũng làm thay đổi tham số thực.
– Có thể dùng chuyển tham chiếu để trả về giá trị cho
nơi gọi hàm.
Ví dụ
• So sánh 2 hàm hoán vị sau đây, dùng chuyển tham
chiếu và tham trị:

void hoanVi_1(int a, int b) void main()


{ {
int t= a; int x= 3, y= 4;
a= b, cout<<x<<’ ‘<<y<<endl;
b= t; hoanVi_1(x, y);
} cout<<x<<’ ‘<<y<<endl;
void hoanVi_2(int &a, int &b) hoanVi_2(x, y);
{ cout<<x<<’ ‘<<y<<endl;
int t= a; }
a= b, //Nhận xét các giá trị được in ra
b= t;
}
5. Giá trị trả về
• Một hàm không trả về giá trị khi hàm được khai báo
có kiểu là void.
• N gược lại, hàm phải trả về giá trị có kiểu cùng với
kiểu trả về đã khai báo.
• Phát biểu return nhằm dừng thực thi hàm, trở về
nơi gọi nó; và còn được dùng để trả giá trị (tính toán
được) về cho nơi gọi hàm.
• Trong một hàm, có thể có nhiều phát biểu return,
nhưng chỉ 1 phát biểu return được thực thi.
• Trong một phát biểu return chỉ có 1 giá trị được trả
về.
Ví dụ:
• Trong các định nghĩa hàm sau đây, có những định
nghĩa hàm không hợp lệ.
int f1() {} //? void f4() { return;}
void f2() { return 0;} int f5() { return 0;}
//? int f6(){ return 0.5;} //?
int f3() { return ; }
//?
int IsPrime(int n) void main()
{ {
if (n <= 1) int n;
return 0; cout<<”Hay nhap 1 so nguyen:”;
for (int i= 2; i<n; i++) cin>>n;
if (n%i == 0) if (IsPrime(n) == 1)
return 0; cout<<n<<”la so nguyen to”;
return 1; else
} cout<<n<<”KHONG la so nguyen to”;
}
6. Phạm vi của biến
• Có 3 nơi cơ bản mà biến được khai báo:
– trong một hàm,
– trong định nghĩa danh sách tham số của hàm,
– ngoài tất cả các hàm.
• Tương ứng với vị trí xuất hiện của biến, có:
– Biến địa phương
– Tham số hình thức
– Biến toàn cục
Biến địa phương
• Các biến (hằng) được khai báo trong một hàm
được gọi là các biến địa phương.
• Biến có thể được khai báo bất kì đâu trong hàm,
chỉ các phát biểu trong cùng khối mới có thể truy
xuất.
• Biến địa phương chỉ tồn tại (thời gian sống) trong
khi khối lệnh có chứa khai báo biến đó thực thi.
• Khối lệnh hoặc hàm khác không thể truy xuất
chúng.
Tham số hình thức
• Dùng tham số hình thức để chuyển các giá
trị cho hàm.
• Các tham số hình thức được dùng như
biến địa phương.N ghĩa là:
– biến chỉ được sinh ra khi hàm được gọi thực
thi và bị hủy khi hàm thực thi xong.
– Chỉ được truy xuất bởi các phát biểu trong
hàm đó.
Biến toàn cục
• Để tạo biến (hằng) toàn cục, khai báo biến
(hằng) ngoài tất cả các hàm.
• Biến toàn cục có thể được truy xuất bởi các
phát biểu ở bất kì đâu trong chương trình kể
từ sau khi nó được định nghĩa (khai báo).
• Thời gian sống của biến toàn cục là suốt quá
trình chương trình thực thi.
Ví dụ
#include<iostream.h> void main()
double a = 3.0, r = 0.0; {
double f1(){ cout<<f1();
r = 2*a; cout<<f2();
return r; cout<<r;
} }
double f2(){
return (a*a);
}
Trường hợp trùng tên biến
• Không thể định nghĩa hai biến trùng tên
trong cùng khối.
• N ếu có biến địa phương trong hàm trùng tên
với biến toàn cục, thì trong hàm đó, mặc
định sẽ truy xuất đến biến địa phương.
• Để truy xuất đến biến toàn cục, ta dùng
phép toán phân định phạm vi, là dấu hai
chấm kép [::] ngay trước tên biến.
Ví dụ
#include<iostream.h> //Chú ý trường hợp:
double a = 3.0, r = 0.0;
double f1(double a) int f3(int a)
{ {
double r = 2*a; int b = a;
return r; if (a<0)
} int b = -a;
double f2(double r) return b;
{ }
::r = r*r; //Chạy chương trình bằng “tay”
return ::r; xem thử !
}
void main()
{
cout<<f1(a);
cout<<f2(a);
cout<<r;
}
7. Biến mảng
• Mảng là một nhóm các biến có cùng tên, cùng
kiểu dữ liệu.
• Mảng có thể là một hoặc nhiều chiều.
• Mỗi phần tử (mỗi biến) của mảng được truy xuất
thông qua chỉ số
a n=4
-3 2 8 5

• Mảng một chiều a có 8 phần tử, hiện có 4 phần tử


đã được gán giá trị.
Ví dụ: a
3 -2 4

7 -8 6

) Mảng 2 chiều a có 4×5=20 phần tử, hiện có


2×3=6 phần tử đã được gán giá trị.
Định nghĩa mảng một chiều (1-D)

Mẫu khai báo: <kiểu dữ liệu> TenBien[MAX] ;


• TenBien: theo nguyên tắc đặt tên,
• MAX: phải là hằng (hằng khai báo, hằng giá trị,…)
Ví dụ:
#define MAX 20
int a[10];
int b[MAX]
double m[MAX]
Định nghĩa mảng một chiều (2)

Với khai báo trên:


• Là ta đã định nghĩa một mảng có MAX phần tử
(= đã định nghĩa MAX biến)
• Tất cả phần tử (biến) này có cùng kiểu dữ liệu.
• Mỗi phần tử của mảng có chỉ số từ
[0]→[MAX–1].
Định nghĩa mảng một chiều (3)
Ví dụ:
char s[50]; ⇒ định nghĩa 50 biến kiểu char
gồm: s[0], s[1], s[2],… s[49].
s[0] = ‘H’, s[1]=‘e’, s[2]=‘l’;

s[0]
s[1] s[2] s[3] s[48] s[49]

‘H’ ‘e’ ‘l’ …


Định nghĩa mảng một chiều (3)

Ví dụ:
int F[7]; ⇒ định nghĩa 7 biến kiểu int gồm:
F[0], F[1],f[2],… F[6].
F[0]=-2, F[1]=5, F[2]=1;

F[0] F[3] F[5]


F[1] F[2] F[4] F[6]

-2 5 1
Định nghĩa mảng một chiều (4)

Ví dụ:
double x[12];⇒định nghĩa 12 biến kiểu double
gồm: x[0], x[1], x[2],… x[11].
x[0]=1.2, x[1]=3.1;
x[0] x[10]
x[1] x[2] x[11]

1.2 3.1 …
Định nghĩa mảng một chiều (5)

Ví dụ:
- Để khai báo mảng số nguyên có 25 phần tử với tên là
mg,
= Khai báo 25 biến có tên chung là mg:
int mg[25];
hay:
#define MAX 25
int mg[MAX];
Lưu trữ

Khi mảng được định nghĩa,


- Vùng nhớ cho các phần tử của mảng được cấp
phát là các ô nhớ liền nhau.
- Mỗi phần tử chiếm số bytes tùy thuộc kiểu dữ
liệu.
- sizeof(<tên biến mảng>); → cho biết tổng
số bytes của mảng.
Lưu trữ
Ví dụ:
double x[25];
⇒ sizeof(x) ≡ 200
⇒ sizeof(x[0]) ≡ sizeof(x[1]) ≡ …≡ 8

long a[20];
⇒ sizeof(a) ≡ 80
⇒ sizeof(a[0]) ≡ sizeof(a[1]) ≡ …≡ 4
Lưu ý (1)
Không thể dùng biến mảng như thông thường.
int a[6];
a = -2; //err
cout<<a; //err
Mà phải dùng từng phần tử trong chúng.
Mỗi phần tử được dùng như một biến đơn.
int a[6];
a[1] = -2;
cin>>a[0];
cout<<a[0]*a[1];
Lưu ý (2)

- Ta thường dùng phát biểu lặp để truy xuất các


phần tử của mảng.
- Đồng thời dùng thêm một biến kiểu nguyên,
cho biết số phần tử của mảng thực sự đang được
dùng.
Vd01
Khởi tạo

Một số cách mà ngôn ngữ C cho phép khởi tạo giá


trị của mảng:
(1) Số phần tử = số giá trị
double x[3]= {1.0, 2.71828, 3.14159};
⇔ x[0]= 1.0, x[1]= 2.71828,...

⇒ Cấp phát 3 ô nhớ kiểu double, gán 3 giá trị cho


chúng.
Khởi tạo

(2) Số phần tử > số giá trị


char s[10]= {‘c’,’h’,’a’,’o’,’e’,’m’};

⇔ s[0]= ‘c’, s[1]= ‘h’,…,s[5]=‘m’;

⇒ Cấp phát 10 ô nhớ kiểu char, lần lượt gán 6 giá trị
cho 6 ô nhớ đầu
Khởi tạo

(3) Không định số phần tử


int SoNgay[]= {31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};

⇔ Cấp phát số phần tử = số giá trị được gán.


⇒ Cấp phát 12 ô nhớ kiểu int, lần lượt gán 12 giá
trị cho chúng.
Vd02
8. Biến mảng là tham số của hàm
- Tham số được khai báo như khai báo biến mảng.
- Có thể không cần xác định số phần tử của mảng
- Mảng được chuyển tham chiếu
Vd: Hàm xuất nội dung một mảng các số nguyên:
void xuatMang(int a[], int N);
Vd: Hàm nhập nội dung một mảng các số nguyên:
void nhapMang(int a[], int &N);
// lưu ý khi nhập N trong hàm
Vd03
- Tham số được khai báo như khai báo biến mảng.
- Có thể không cần xác định số phần tử của mảng
- Mảng được chuyển tham chiếu

Vd: Hàm tính tổng các phần tử của mảng nguyên


(vd: a = [3 7 4 9] → S= 23)
int tinhTong(int a[], int N);
Vd04
8. Biến mảng là tham số của hàm

Vd1: Đảo ngược nội dung của mảng. Ví dụ:


a= [3 7 4 9] → a = [9 4 7 3]

void daoMang(int a[], int N)


{
for (int i= 0; i<N/2; i++)
HoanVi(a[i], a[n-i-1]);
}
i=0 ai an-1

i=1 ai an-i-1
i=2 ai an-i-1
a0 a1 a2 a3 a4 a5 a6

a= 3 7 6 9 2 1 8
n=7
Vd05
Vd2: Hàm sắp xếp tăng các phần tử của mảng. Ví dụ:
a= [3 7 4 9] → a = [3 4 7 9]
Vd06
Vd3: Tìm xem một giá trị x có trong mảng ? Ví dụ:
a= [3 7 4 9], x= 4
→ x nằm ở vị trí 2 trong mảng a
x= 3

n=7
a= 6 7 3 2 9 2 8

k=2
x= 4

a= 6 7 3 2 9 2 8

n=7
k=-1 (khong co x
trong mang)
Vd07
Vd07b
Vd4: Xóa phần tử x khỏi mảng (nếu có). Ví dụ:
a= [6 7 3 2 9 2 8],n=7
x= 3 → a= [6 7 2 9 2 8], n= 6
x= 2 → a= [6 7 9 8], n= 4
x= 3

n=6 n=7
a= 6 7 3 2 9 2 8

k=2
Xóa phần tử x khỏi mảng (nếu có).
Vd08a
Xóa tất cả phần tử x khỏi mảng (nếu có).
Vd08b
Bài tập nhập môn lập trình
Phần 1: Các bài tập không dùng cấu trúc điều khiển
1. Viết chương trình nhập 2 số. In ra cho biết giá trị của số lớn.
2. Viết chương trình nhập số nguyên N, in ra cho biết góc có số đo N0 thuộc cung phần tư số
mấy của đường tròn lượng giác. Biết: góc có số đo [0..90): cung phần tư số 1, [90..180):
cung phần tư số 2, [180.. 270): cung phần tư số 3, [270..360): cung phần tư số 4.
3. Viết chương trình nhập 2 số nguyên a, b. In ra cho biết chu vi, diện tích của hình chữ nhật có
độ dài 2 cạnh là a, b.
4. Viết chương trình nhập vào 1 ký tự, in ra ký tự in hoa tương ứng.
5. Viết chương trình nhập vào 1 số nguyên, in ra ký tự tương ứng và ngược lại, nhập một ký tự,
in ra mã ASCII của ký tự đó.
Phần 2: Cấu trúc điều khiển: rẽ nhánh, lặp, hàm
1. Viết chương trình nhập vào 2 số a, b. Giải và biện luận phương trình bậc nhất ax + b = 0
2. Viết chương trình nhập vào 3 số a, b, c. Giải và biện luận phương trình trùng phương ax4 +
bx2 + c = 0
3. Viết chương trình nhập vào 3 số a, b, c. Xác định xem a, b, c có phải là độ dài 3 cạnh một
tam giác hay không. Nếu phải thì đó là tam giác gì trong các loại: tam giác vuông, tam giác
tù, tam giác nhọn.
4. Viết chương trình nhập số nguyên không âm N (N < 1000). In ra cách đọc N bằng tiếp Việt
không dấu.
5. Viết chương trình nhập 2 số nguyên d, m. In ra cho biết ngày d/m/2004 là ngày thứ mấy
trong tuần. Biết ngày 1/1/2004 là ngày thứ 5. Nếu dữ liệu nhập vào không hợp lệ, hãy thông
báo.
6. Viết chương trình nhập vào 3 số nguyên không âm d, m, y. In ra cho biết ngày d/m/y là ngày
thứ mấy trong tuần. Các dữ liệu nhập vào luôn hợp lệ, chỉ xét các năm trong hạn 1..3000.
(Nhắc lại: năm nhuận là năm chia hết cho 400 hoặc chia hết cho 4 và không chia hết cho
100).
7. Viết chương trình nhập số nguyên dương H. Dùng các ký tự * vẽ quạt 4 cánh có tâm ở giữa
màn hình. Mỗi cánh quạt là tam giác vuông cân đặc có độ rộng cạnh góc vuông là H.
Ví dụ với H = 3 ta sẽ có cánh quạt như sau ở giữa màn hình
* * * *
* * * *
* * * *
* * * *
* * * *
* * * *
8. Viết chương trình nhập số nguyên không âm N. Hãy tính và in ra giá trị của các các biểu
thức sau:
1 1 1
a. 1 + + + ... +
2 3 N
1 1 1
b. 1 + + + ... +
2! 3! N!
1 1
c. 1 − + + ... +
(− 1)
N −1

2! 3! N!
d. N!
⎧1x3x5x...xN N%2!= 0
e. N!! .Nhắc lại: N !!= ⎨
⎩2 x 4 x6 x...xN N%2 == 0
9. Viết chương trình nhập số nguyên N (kiểu char). In ra cho biết biểu diễn nhị phân của N.
10. Viết chương trình nhập số nguyên không âm N. In ra dãy Fibonaci với các số hạn F0, F1, …,
FN
11. Viết chương trình nhập số nguyên dương N. In ra màn hình cách phân tích N thành thừa số
nguyên tố.
12. Viết chương trình nhập 4 số a, b, c, d. Giải phương trình bậc 3: ax3 + bx2 + cx + d = 0 bằng
phương pháp lặp nhị phân. Sai số cho phép 0.0000001.
13. Viết chương trình nhập số nguyên dương N (N ≤ 2 tỉ), kiểm tra xem N có phải là số đối
xứng hay không. (Số đối xứng là số có giá trị không đổi nếu đọc các chữ số từ phải qua trái).
14. Viết chương trình nhập 2 số nguyên không âm K, N (K ≤ N). Tính và in ra:
N!
C NK =
K !( N − K )!
15. Viết chương trình nhập số nguyên dương N (N≤1000). In ra N số nguyên tố đầu tiên.
a c
16. Viết chương trình nhập 2 phân số và . Tính và in ra phân số tổng ở dạng phân số tối
b d
giản.
17. Viết chương trình nhập số nguyên dương N, kiểm tra xem N có phải là số hạnh phúc hay
không. (Số hạnh phúc là số có 2K chữ số và tổng K chữ số đầu tiên bằng tổng K chữ số cuối
cùng)
Phần 3: Mảng 1 chiều - Chuỗi ký tự
18. Viết chương trình nhập số nguyên dương N (N ≤ 100) thực hiện:
a. Nhập N số nguyên vào dãy a0, a1, a2, ..
b. Xuất dãy vừa nhập ra màn hình.
c. Đếm xem dãy vừa nhập có bao nhiêu số nguyên tố, in các số nguyên tố đó ra màn
hình.
d. Nhập số nguyên X, tìm vị trí xuất hiện của X trên dãy vừa nhập.
e. Nhập số nguyên Y, xóa một số có giá trị Y ra khỏi dãy vừa nhập.
f. Nhập số nguyên Z, tìm vị trí xuất hiện của số trên dãy có giá trị gần với Z nhất.
19. Viết chương trình nhập số nguyên dương N (N ≤ 100) thực hiện:
a. Nhập N số nguyên vào dãy a0, a1, a2, ..
b. Xuất dãy vừa nhập ra màn hình.
c. Kiểm tra xem dãy vừa nhập có phải là dãy tăng dần hay không.
d. Nếu dãy không tăng dần, hãy sắp xếp lại, xuất dãy ra màn hình.
e. Nhập số nguyên X, chèn X vào dãy đang có sao cho dãy vẫn được sắp xếp tăng dần,
xuất dãy kết quả ra màn hình.
20. Viết chương trình nhập số nguyên dương N (N ≤ 100) thực hiện:
a. Nhập N số nguyên vào dãy a0, a1, a2, ..
b. Tìm vị trí của số bé nhất trong dãy.
c. Tìm vị trí của số âm lớn nhất trong dãy.
d. Tìm tất cả các vị trí của dãy mà số tại đó bé hơn 2 số kề bên. Các số ở biên chỉ cần
xét với 1 số kề bên.
e. Tìm tất cả bộ ba số i, j, k thỏa ai, aj, ak là bộ 3 số pitago.
21. Viết chương trình nhập chuỗi ký S:
a. Đếm và cho biết số lượng khoảng trắng, số lượng ký số, số lượng chữ cái latin, số
lượng các ký tự khác.
b. Đếm và cho biết số lượng từ của chuỗi – các từ cách nhau bởi khoảng trắng.
c. Biến đổi chuỗi sao cho các ký tự đầu mỗi từ là ký tự in hoa, các ký tự khác in
thường.
22. Viết chương trình nhập chuỗi ký S, đếm và in cho biết số lượng của mỗi chữ cái latin trong
chuỗi (không phân biệt chữ in hoa và chữ in thường).
23. Viết chương trình nhập 3 chuỗi ký tự S, S1, S2. Hãy tìm trên chuỗi S tất cả những lần xuất
hiện của S1 và thay bằng S2.
Phần 4: Struct
24. Viết chương trình nhập thông tin của một sinh viên, xuất thông tin sinh viên vừa nhập ra
màn hình. Thông tin một sinh viên gồm: Mã sinh viên (chuỗi 8 ký tự), họ và tên sinh viên
(chuỗi 30 ký tự), giới tính (nam/nữ), địa chỉ liên hệ (chuỗi 50 ký tự), điểm 6 môn học
25. Viết chương trình quản lý một lớp học gồm tối đa 150 sinh viên, mỗi sinh viên có các thông
tin như bài trước. Chương trình phải đảm bảo một số tính năng:
a. Nhập mới một danh sách sinh viên.
b. Tìm một sinh viên trong danh sách theo mã sinh viên.
c. Thêm một sinh viên vào danh sách.
d. Hủy một sinh viên ra khỏi danh sách.
e. Xuất danh sách sinh viên ra màn hình.
f. Xuất danh sách các sinh viên còn nợ điểm (điểm < 5) của ít nhất một môn học.

You might also like