Đọc một ký tự từ file và lưu vào biến :
getc(biênfile);
fgetc(str,biênfile);
fscanf();
Hàm feof(biến con trỏ) cho biết đã gặp ký tự kết thúc file hay chưa? Nếu trả về 0 thì chưa, còn trả
về giá trị khác 0 (≠0) thì có nghĩa đã kết thúc file
Hàm với file văn bản:
fprintf, fscanf, fgets, fputs
fprintf(biếncontrỏ, chuỗi điều khiển, danh sách các tham số);
giống như printf nhưng đưa dữ liệu ra file.
fscanf(biếncontrỏ, chuỗi các đặc tả, danh sách địa chỉ các biến);
giống như scanf nhưng dữ liệu nhận từ file.
Con trỏ tập tin: khi một tập tin được mở ra để làm việc, tại mỗi thời điểm sẽ có một vị trí của
tập tin mà tại đó việc đọc/ghi thông tin sẽ xảy ra (có nghĩa là có một con trỏ đang chỉ đến vị
tríđó và đặt tên nó là con trỏ tập tin)
49 trang |
Chia sẻ: aloso | Lượt xem: 3021 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Giáo trình thực hành Kỹ thuật lập trình C, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
để sử dụng được chuỗi ký tự
(tức là một biến nhận giá trị chứa nhiều hơn một ký tự, ví dụ như biến hoten thường nhận giá trị là
‘Nguyen Van A’ hoặc ‘Le Thi B’) thì cần phải khai báo biến đó có kiểu dữ liệu char và độ dài của
nó.
Ví dụ: giả sử chương trình yêu cầu khai một biến hoten để nhận giá trị của một chuỗi ký tự nhập
vào như ‘Nguyen Thi Ha Quyen’ thì cần khai báo như sau:
char hoten[30];
Con số 30 cho biết biến họ tên này chỉ nhận chuỗi ký tự có chiều dài không nhiều hơn 30 ký tự.
8) Chuyển chế độ viết đè sang chế độ chèn
Con trỏ nhấp nháy trong C thông thường có dạng là một dấu gạch ngang. Tuy nhiên, nếu vô tình
chúng ta ấn vào phím Insert trên bàn phím thì con nháy sẽ biến thành dạng hình chữ nhật tô màu
vàng, và lúc này chúng ta không thể ấn Enter để xuống dòng cũng như chế độ soạn thảo trong C
chuyển sang chế độ viết đè.
Khắc phục lỗi này bằng cách ấn phím Insert một lần nữa, con trỏ nhấp nháy sẽ trở về dạng
dấu gạch ngang như bình thường.
9) Các câu lệnh đơn trong C thường dùng
Một câu lệnh (statement) xác định một công việc mà chương trình phải thực hiện để xử lý dữ
liệu đã được mô tả và khai báo. Các câu lệnh được ngăn cách với nhau bởi dấu chấm phẩy (;).
Phân loại: có hai loại lệnh, đó là lệnh đơn và lệnh có cấu trúc.
Sử dụng phần mềm C
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 10
Lệnh đơn là một lệnh không chứa các lệnh khác. Các lệnh đơn gồm: lệnh gán, các câu lệnh
nhập xuất dữ liệu…
Lệnh có cấu trúc là lệnh trong đó chứa các lệnh khác. Lệnh có cấu trúc bao gồm: cấu trúc điều
kiện rẽ nhánh, cấu trúc điều kiện lựa chọn, cấu trúc lặp và cấu trúc lệnh hợp thành. Lệnh hợp
thành (khối lệnh) là một nhóm bao gồm nhiều khai báo biến và các lệnh được gom vào trong
cặp dấu {}.
a) Lệnh gán
Lệnh gán (assignment statement) dùng để gán giá trị của một biểu thức cho một biến.
Cú pháp: =
Ví dụ:
int main()
{
int x,y;
x =10; /*Gán hằng số 10 cho biến x*/
y = 2*x; /*Gán giá trị 2*x=2*10=20 cho x*/
return 0;
}
Nguyên tắc khi dùng lệnh gán là kiểu của biến và kiểu của biểu thức phải giống nhau, gọi là có sự
tương thích giữa các kiểu dữ liệu. Chẳng hạn ví dụ sau cho thấy một sự không tương thích về kiểu:
int main()
{
int x,y;
x = 10; /*Gán hằng số 10 cho biến x*/
y = “Xin chao”;
/*y có kiểu int, còn “Xin chao” có kiểu char* */
return 0;
}
Khi biên dịch chương trình này, C sẽ báo lỗi "Cannot convert ‘char *’ to ‘int’" tức là C không thể tự
động chuyển đổi kiểu từ char * (chuỗi ký tự) sang int.
Tuy nhiên trong đa số trường hợp sự tự động biến đổi kiểu để sự tương thích về kiểu sẽ được thực
hiện.
Ví dụ:
int main()
{
int x,y;
float r;
char ch;
r = 9000;
Sử dụng phần mềm C
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 11
x = 10; /* Gán hằng số 10 cho biến x */
y = 'd'; /* y có kiểu int, còn ‘d’ có kiểu char*/
r = 'e'; /* r có kiểu float, ‘e’ có kiểu char*/
ch = 65.7; /* ch có kiểu char, còn 65.7 có kiểu float*/
return 0;
}
Trong nhiều trường hợp để tạo ra sự tương thích về kiểu, ta phải sử dụng đến cách thức chuyển đổi
kiểu một cách tường minh.
Cú pháp của phép toán này như sau: (Tên kiểu)
Chuyển đổi kiểu của thành kiểu mới . Chẳng hạn như:
float f;
f = (float) 10 / 4; /* f lúc này là 2.5*/
Chú ý:
Khi một biểu thức được gán cho một biến thì giá trị của nó sẽ thay thế giá trị cũ mà biến đã
lưu giữ trước đó.
Trong câu lệnh gán, dấu = là một toán tử; do đó nó có thể được sử dụng là một thành phần
của biểu thức. Trong trường hợp này giá trị của biểu thức gán chính là giá trị của biến.
Ví dụ:
int x, y;
y = x = 3; /* y lúc này cùng bằng 3*/
Ta có thể gán trị cho biến lúc biến được khai báo theo cách thức sau:
= ;
Ví dụ: int x = 10, y=x;
b) Lệnh nhập giá trị từ bàn phím cho biến (hàm scanf)
Hàm scanf là hàm cho phép đọc dữ liệu từ bàn phím và gán cho các biến trong chương trình khi
chương trình thực thi. Trong ngôn ngữ C, đó là hàm scanf nằm trong thư viện stdio.h.
Cú pháp: scanf(“Chuỗi định dạng”, địa chỉ của các biến);
Giải thích:
Chuỗi định dạng: dùng để qui định kiểu dữ liệu, cách biểu diễn, độ rộng, số chữ số thập
phân... Một số định dạng khi nhập kiểu số nguyên, số thực, ký tự.
Định dạng Ý nghĩa
%[số ký số]d Nhập số nguyên có tối đa
%[số ký số]f Nhập số thực có tối đa tính cả dấu chấm
%c Nhập một ký tự
Ví dụ:
%d Nhập số nguyên
%4d Nhập số nguyên tối đa 4 ký số, nếu nhập nhiều hơn 4 ký số thì chỉ nhận được 4
ký số đầu tiên
%f Nhập số thực
Sử dụng phần mềm C
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 12
%6f Nhập số thực tối đa 6 ký số (tính luôn dấu chấm), nếu nhập nhiều hơn 6 ký số
thì chỉ nhận được 6 ký số đầu tiên (hoặc 5 ký số với dấu chấm)
Địa chỉ của các biến: là địa chỉ (&) của các biến mà chúng ta cần nhập giá trị cho nó. Được
viết như sau: &.
Ví dụ:
scanf(“%d”,&bien1);/*Doc gia tri cho bien1 co kieu nguyen*/
scanf(“%f”,&bien2); /*Doc gia tri cho bien2 co kieu thưc*/
scanf(“%d%f”,&bien1,&bien2);
/*Doc gia tri cho bien1 co kieu nguyen, bien2 co kieu thuc*/
scanf(“%d%f%c”,&bien1,&bien2,&bien3);
/*bien3 co kieu char*/
Lưu ý:
Chuỗi định dạng phải đặt trong cặp dấu nháy kép (“”).
Các biến (địa chỉ biến) phải cách nhau bởi dấu phẩy (,).
Có bao nhiêu biến thì phải có bấy nhiêu định dạng.
Thứ tự của các định dạng phải phù hợp với thứ tự của các biến.
Để nhập giá trị kiểu char được chính xác, nên dùng hàm fflush(stdin) để loại bỏ các ký tự
còn nằm trong vùng đệm bàn phím trước hàm scanf().
Để nhập vào một chuỗi ký tự (không chứa khoảng trắng hay kết thúc bằng khoảng trắng),
chúng ta phải khai báo kiểu mảng ký tự hay con trỏ ký tự, sử dụng định dạng %s và tên
biến thay cho địa chỉ biến.
Để đọc vào một chuỗi ký tự có chứa khoảng trắng (kết thúc bằng phím Enter) thì phải
dùng hàm gets().
Ví dụ:
int biennguyen;
float bienthuc;
char bienchar;
char chuoi1[20], *chuoi2;
Nhập giá trị cho các biến:
scanf(“%3d”,&biennguyen);
Nếu ta nhập 1234455 thì giá trị của biennguyen là 3 ký số đầu tiên (123). Các ký số còn
lại sẽ còn nằm lại trong vùng đệm.
scanf(“%5f”,&bienthuc);
Nếu ta nhập 123.446 thì giá trị của bienthuc là 123.4, các ký số còn lại sẽ còn nằm trong
vùng đệm.
scanf(“%2d%5f”,&biennguyen, &bienthuc);
Nếu ta nhập liên tiếp 2 số cách nhau bởi khoảng trắng như sau: 1223 3.142325, thì:
2 ký số đầu tiên (12) sẽ được đọc vào cho biennguyen.
Sử dụng phần mềm C
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 13
2 ký số tiếp theo trước khoảng trắng (23) sẽ được đọc vào cho bienthuc.
scanf(“%2d%5f%c”,&biennguyen, &bienthuc,&bienchar)
Nếu ta nhập liên tiếp 2 số cách nhau bởi khoảng trắng như sau: 12345 3.142325:
2 ký số đầu tiên (12) sẽ được đọc vào cho biennguyen.
3 ký số tiếp theo trước khoảng trắng (345) sẽ được đọc vào cho bienthuc.
Khoảng trắng sẽ được đọc cho bienchar.
Nếu ta chỉ nhập 1 số gồm nhiều ký số như sau: 123456789:
2 ký số đầu tiên (12) sẽ được đọc vào cho biennguyen.
5 ký số tiếp theo (34567) sẽ được đọc vào cho bienthuc.
bienchar sẽ có giá trị là ký số tiếp theo ‘8’.
scanf(“%s”,chuoi1); hoặc scanf(“%s”,chuoi2)
Nếu ta nhập chuỗi như sau: Nguyen Van Linh () thì giá trị của biến chuoi1 hay chuoi2
chỉ là Nguyen .
scanf(“%s%s”,chuoi1, chuoi2);
Nếu ta nhập chuỗi như sau: Duong Van Hieu () thì giá trị của biến chuoi1 là Duong và
giá trị của biến chuoi2 là Van.
Vì sao như vậy? C sẽ đọc từ đầu đến khi gặp khoảng trắng và gán giá trị cho biến đầu
tiên, phần còn lại sau khoảng trắng là giá trị của các biến tiếp theo.
gets(chuoi1);
Nếu nhập chuỗi : Nguyen Van Linh () thì giá trị của biến chuoi1 là Nguyen Van Linh
c) Lệnh xuất giá trị của biểu thức lên màn hình (hàm printf)
Hàm printf (nằm trong thư viện stdio.h) dùng để xuất giá trị của các biểu thức lên màn hình.
Cú pháp: printf(“Chuỗi định dạng ”, Các biểu thức);
Giải thích:
Chuỗi định dạng: dùng để qui định kiểu dữ liệu, cách biểu diễn, độ rộng, số chữ số thập
phân... Một số định dạng khi đối với số nguyên, số thực, ký tự.
Định dạng Ý nghĩa
%d Xuất số nguyên
%[.số chữ số thập phân]f Xuất số thực có theo quy tắc làm tròn số.
%o Xuất số nguyên hệ bát phân
%x Xuất số nguyên hệ thập lục phân
%c Xuất một ký tự
%s Xuất chuỗi ký tự
%e hoặc %E hoặc %g hoặc %G Xuất số nguyên dạng khoa học (nhân 10 mũ x)
Ví dụ:
%d In ra số nguyên
%4d In số nguyên tối đa 4 ký số, nếu số cần in nhiều hơn 4 ký số thì in hết
%f In số thực
%6f In số thực tối đa 6 ký số (tính luôn dấu chấm), nếu số cần in nhiều hơn 6 ký số
thì in hết
Sử dụng phần mềm C
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 14
%.3f In số thực có 3 số lẻ, nếu số cần in có nhiều hơn 3 số lẻ thì làm tròn.
Các biểu thức: là các biểu thức mà chúng ta cần xuất giá trị của nó lên màn hình, mỗi biểu
thức phân cách nhau bởi dấu phẩy (,).
Ví dụ:
include
int main()
{
int bien_nguyen=1234, i=65;
float bien_thuc=123.456703;
printf(“Gia tri nguyen cua bien nguyen =%d\n”,bien_nguyen);
printf(“Gia tri thuc cua bien thuc =%f\n”,bien_thuc);
printf(“Truoc khi lam tron=%f \n
Sau khi lam tron=%.2f”,bien_thuc, bien_thuc);
return 0;
}
Kết quả in ra màn hình như sau:
Lưu ý:
Đối với các ký tự điều khiển, ta không thể sử dụng cách viết thông thường để hiển thị chúng.
Ký tự điều khiển là các ký tự dùng để điều khiển các thao tác xuất, nhập dữ liệu.
Một số ký tự điều khiển được mô tả trong bảng:
Ký tự điều khiển
Giá trị thập lục
phân
Ký tự được hiển thị Ý nghĩa
\a 0x07 BEL Phát ra tiếng chuông
\b 0x08
BS Di chuyển con trỏ sang trái 1 ký tự và xóa ký tự
bên trái (backspace)
\f 0x0C FF Sang trang
\n 0x0A LF Xuống dòng
\r 0x0D CR Trở về đầu dòng
Sử dụng phần mềm C
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 15
\t 0x09 HT Tab theo cột (giống gõ phím Tab)
\\ 0x5C \ Dấu \
\’ 0x2C ‘ Dấu nháy đơn (‘)
\” 0x22 “ Dấu nháy kép (“)
\? 0x3F ? Đấu chấm hỏi (?)
\ddd ddd Ký tự có mã ACSII trong hệ bát phân là số ddd
\xHHH oxHHH Ký tự có mã ACSII trong hệ thập lục phân là HHH
Ví dụ:
#include
#include
int main ()
{
clrscr();
printf("\n Tieng Beep \a");
printf("\n Doi con tro sang trai 1 ky tu\b");
printf("\n Dau Tab \tva dau backslash \\");
printf("\n Dau nhay don \' va dau nhay kep \"");
printf("\n Dau cham hoi \?");
printf("\n Ky tu co ma bat phan 101 la \101");
printf("\n Ky tu co ma thap luc phan 41 la \x041");
printf("\n Dong hien tai, xin go enter");
getch();
printf("\rVe dau dong");
getch();
return 0;
}
Kết quả trước khi gõ phím Enter:
Kết quả sau khi gõ phím Enter:
Sử dụng phần mềm C
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 16
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 17
BÀI THỰC HÀNH SỐ 1
(Chương I: CÁC THÀNH PHẦN CƠ BẢN CỦA NGÔN NGỮ LẬP TRÌNH C)
Hãy đọc thật kỹ phần hàm và biểu thức trong giáo trình C, và làm các bài tập sau:
1) Viết chương trình nhập vào một số nguyên n và x. Hãy cho biết thương nguyên và số
dư của phép chia n cho x; và phép chia phân của n cho x.
Hướng dẫn: sử dụng phép toán số học /(phép chia thương nguyên), %(phép chia lấy số dư), và
chuyển đổi số nguyên n hoặc x thành số thực.
2) Viết chương trình nhập vào một số thực x và tính giá trị y của các biểu thức sau:
a.y=x7.ex + 3x – 8
b.y=(xx + 9)/(5x + 7)
c.y=I5x – 30I . (2x2 + 9)
d.y=7x+15
e.y=25x3–9 (căn bậc 7)
Hướng dẫn: sử dụng các hàm chuẩn trong C gồm hàm pow(double x,double y) – tính xy, hàm
exp(x) – tính ex, hàm fabs(x) – tính trị tuyệt đối của một số thực x và hàm sqrt(x) – tính căn bậc 2
của x.
3) Viết chương trình nhập vào các giá trị điện trở R1, R2, R3 của một mạch điện và tính
tổng trở theo công thức:
1R=1/R1+1/R2+1/R3
4) Viết chương trình nhập vào họ tên và tuổi của một sinh viên, rồi xuất ra các thông tin
vừa nhập.
Hướng dẫn: do yêu cầu nhập họ tên và tuổi nên cần khai báo 2 biến: hoten và tuoi. Họ tên của một
người thì nhiều hơn một ký tự cho nên phải khai báo như sau: char hoten[30] (với 30 là chiều dài tối
đa được phép nhập cho họ tên một người).
Đoạn chương trình có dạng sau:
char hoten[30];
int tuoi;
printf(“Nhap ho ten : “);
gets(hoten); //câu lệnh gets dùng để lấy các ký tự vừa nhập và gán cho biến hoten
fflush(stdin) //xóa sạch bộ đệm mỗi khi nhập dữ liệu giữa kiểu chuỗi và kiểu số
printf(“Nhap tuoi : “);
scanf(“%d”,&tuoi);
printf(“Sinh vien %s - %d tuoi”,hoten,tuoi);
//vì biến hoten là một chuỗi ký tự cho nên phải sử dụng định dạng %s khi xuất ra màn hình
5) Viết một đoạn mã giả và vẽ một lưu đồ để nhập một giá trị là độ 0C (Celsius) và chuyển
nó sang độ 0F (Fahrenheit). [Hướng dẫn: C/5 = (F-32)/9]
7
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 18
BÀI THỰC HÀNH SỐ 2
(Chương II: CÁC LỆNH CỦA NGÔN NGỮ LẬP TRÌNH C)
1) Viết chương trình nhập vào một số thực x từ bàn phím. Hãy xuất ra màn hình câu
thông báo “Bạn đã nhập đúng yêu cầu” nếu x€[5,10]; nếu không thì xuất ra câu thông
báo “Bạn đã nhập x nằm ngoài đoạn [5,10]”.
Hướng dẫn: sử dụng biểu thức điều kiện và phép toán logic (&& hoặc ||).
float x;
printf(“%s”,(x=10)?”Ban da nhap dung yeu cau”:”Ban da nhap x nam ngoai doan
[5,10]”;
2) Viết chương trình nhập vào 4 số thực từ bàn phím. Hãy xuất ra màn hình giá trị lớn
nhất và giá trị nhỏ nhất trong 4 số vừa nhập.
Hướng dẫn: sử dụng biểu thức điều kiện
float x,y,u,v;
float min,max;
max=((x>=y?x:y) >= (u>=v?u:v)) ? (x>=y?x:y) : (u>=v?u:v);
min=((x<=y?x:y) <= (u<=v?u:v)) ? (x<=y?x:y) : (u<=v?u:v);
Hoặc cũng có thể khai báo thêm các biến phụ min_xy, max_xy, min_uv và max_uv cho giá trị min và
max của từng cặp x-y, u-v.
3) Viết chương trình nhập vào chiều dài hai đáy a,b và chiều cao h của một hình thang.
Hãy tính và xuất ra màn hình diện tích của hình thang có 3 độ dài vừa nhập.
Hướng dẫn: sử dụng công thức tính diện tích hình thang dt=(a+b)*h/2;
4) Viết chương trình nhập vào 3 hệ số của một phương trình có dạng ax2+bx+c=0. Hãy
biện luận và xuất ra các nghiệm của phương trình này.
Hướng dẫn: biện luận từng trường hợp dẫn đến phương trình bị suy biến thành phương trình bậc
nhất hay bậc 0 phụ thuộc vào các hệ số a,b và c như sau:
float a,b,c;
float delta,x1,x2;
nếu a==0
nếu b==0
nếu c==0
printf(“Phương trình suy biến thành 0x2+0x+0=0, và có vô số nghiệm!”);
ngược lại //tức c≠0
printf(“Phương trình suy biến thành 0x2+0x+c=0, vô nghiệm!”);
ngược lại //tức b≠0, phương trình bậc nhất
printf(“Phương trình suy biến thành 0x2+bx+c=0, có nghiệm duy nhất x=%8.2f”,-c/b);
ngược lại //tức a≠0, phương trình bậc 2
{
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 19
delta=b*b-4*a*c;
nếu delta<0
printf(“Phương trình bậc 2 có Δ<0, vì vậy phương trình vô nghiệm!”);
còn nếu delta==0
printf(“Phương trình bậc 2 có Δ=0, có nghiệm kép x1=x2=%8.2f”,-b/(2*a));
ngược lại //tức Δ>0, phương trình bậc 2 có 2 nghiệm phân biệt
{
x1=(-b-sqrt(delta))/(2*a);
x2=(-b+sqrt(delta))/(2*a);
printf(“Phương trình có 2 nghiệm phân biệt: x1=%8.2f và x2=%8.2f”,x1,x2);
}
}
5) Viết chương trình nhập vào điểm Toán, Lý và Hóa của một sinh viên. Sau đó tính và
xuất ra màn hình điểm trung bình cùng kết quả xếp loại của sinh viên này biết:
dtb<4: Loại F
4<=dtb<5.5: Loại D
5.5<=dtb<7: Loại C
7<=dtb<8.5: Loại B
8.5<=dtb<=10: Loại A
Hướng dẫn: sử dụng câu lệnh if (dạng đầy đủ hoặc khuyết)
float t,l,h,dtb;
//Nhập vào điểm 3 môn toán, lý và hóa
dtb=(t+l+h)/3;
if(dtb<4)
printf(“Điểm trung bình là %8.2f, xếp loại F”,dtb);
else if(4<=dtb && dtb<5.5)
printf(“Điểm trung bình là %8.2f, xếp loại D”,dtb);
else if(5.5<=dtb && dtb<7)
printf(“Điểm trung bình là %8.2f, xếp loại C”,dtb);
else if(7<=dtb && dtb<8.5)
printf(“Điểm trung bình là %8.2f, xếp loại B”,dtb);
else
printf(“Điểm trung bình là %8.2f, xếp loại A”,dtb);
6) Viết chương trình nhập vào một tháng trong năm và xuất ra số ngày của tháng đó.
Hướng dẫn: tháng 1,3,5,7,8,10,12 có 31 ngày; tháng 4,6,9,11 có 30 ngày; riêng tháng 2 có 29 ngày
nếu năm đó là năm nhuần – còn lại là 28 ngày.
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 20
Vì số ngày phụ thuộc vào tháng và năm là các số nguyên nên chúng ta có thể dùng câu lệnh switch
như sau:
int thang,nam;
//nhập vào tháng và năm (tháng 2 có 28/29 ngày phụ thuộc vào năm nhuần hay không
switch(thang)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
printf("Thang %d/%d co 31 ngay",thang,nam);
break;
case 4:
case 6:
case 9:
case 11:
printf("Thang %d/%d co 30 ngay",thang,nam);
break;
default:
if(nam%4==0 && nam%100!=0)
printf("Thang %d/%d co 29 ngay",thang,nam);
else
printf("Thang %d/%d co 28 ngay",thang,nam);
}
7) Viết chương trình nhập vào một số thực dương x (kiểm tra nếu x<0 thì nhập lại và lặp
lại việc nhập này cho đến khi x>0).Sau đó xuất ra giá trị x vừa nhập
Hướng dẫn: sử dụng câu lệnh goto hoặc câu lệnh while/do…while
Cách 1: câu lệnh goto
float x;
nhap:
printf(“Nhap vao gia tri cua n : “);
scanf(“%f”,&x);
if(x<=0)
{
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 21
printf(“Ban da nhap sai, nhap lai!!! “);
goto nhap;
}
Cách 2: câu lệnh while
float x;
printf(“Nhap vao gia tri cua n : “);
scanf(“%f”,&x);
while(x<=0)
{
printf(“Ban da nhap sai, hay nhap lai gia tri cua n : “);
scanf(“%f”,&x);
}
Cách 3: câu lệnh do…while
float x;
do
{
printf(“Nhap vao gia tri cua n : “);
scanf(“%f”,&x);
}
while(x<=0);
8) Viết chương trình nhập vào một số nguyên dương n. Tính và xuất ra màn hình giai
thừa của n.
Hướng dẫn: trước hết phải viết đoạn chương trình để đảm bảo n nhập vào là số dương (sử dụng
bài 6 ở trên)
Sau đó sử dụng câu lệnh for/while hoặc do…while
Cách 1: dùng câu lệnh for
int n,i,gt;
gt=1;
for(i=2;i<=n;i++)
gt=gt*i;
Cách 2: dùng câu lệnh while
int n,i,gt;
gt=1;
i=2;
while(i<=n)
{
gt=gt*i;
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 22
i++;
}
Cách 3: dùng câu lệnh do…while
int n,i,gt;
gt=1;i=1;
do
{
gt=gt*i;
i++;
}
while(i<=n);
9) Viết chương trình nhập vào số nguyên dương n và tính tổng các dãy số sau:
a. S = 1 - 2 + 3 – 4 + ....+ n
b. S = 1+ 1/2 + ... +1/n
c. S= 1 + 1/2! + 1/3! + ... + 1/n!
Hướng dẫn: trước hết nhập n>0, sau đó áp dụng công thức tính
a. S = 1 - 2 + 3 – 4 + ....+ n
#include
//khai thư viện math.h vì có sử dụng các hàm toán học như pow(x,y);
double S; //Khai kiểu double vì hàm pow(x,y) trả về kiểu double
S=0;
for(int i=1;i<=n;i++)
S=S+pow(-1,i+1)*i;
//hoặc dùng câu lệnh if cho trường hợp i chẵn và i lẻ
b.S = 1+ 1/2 + ... +1/n
S=0;
for(int i=1;i<=n;i++)
S=S+1.0/i;
//1.0/i vì chúng ta đang cần lấy cả phần phân và phần nguyên trong phép chia này
c.S= 1 + 1/2! + 1/3! + ... + 1/n!
S=0;gt=1;
for(int i=1;i<=n;i++)
{
gt=gt*i;
S=S+1.0/gt;
}
10)Viết chương trình tính bảng nhân và in ra màn hình như sau:
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 23
Hướng dẫn: sử dụng các ký tự in trong C và vòng lặp for lồng nhau như sau:
#include
#include
void main()
{
clrscr();
printf(" %c",179);
for(int i=1;i<=10;i++)
printf(" %2d",i);
printf("\n___%c____________________________________________________",179);
//an phim Shift voi phim dau gach ngang
for(i=1;i<=10;i++)
{
printf("\n %c",179);
printf("\n%2d %c",i,179);
for(int j=1;j<=10;j++)
printf(" %2d",i*j);
}
getch();
}
11)Viết chương trình giải bài toán cổ:
Vừa gà vừa chó
Bó lại cho tròn
36 con, 100 chân chẵn
Hướng dẫn: trước hết giới hạn số lượng gà và chó, sau đó dùng câu lệnh for để duyệt tất cả các
trường hợp có thể có như sau:
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 24
Gọi x là số gà, y là số chó x>0 và y>0
x+y=36 x<36
2x+4y=100 4y<100 y<25
int x,y;
for(x=1;x<36;x++)
for(y=1;y<25;y++)
if(2*x+4*y==100 && x+y==36)
printf(“\nSố gà: %d, và số chó: %d”,x,y);
12)Viết chương trình giải bài toán cổ:
Trăm trâu, trăm cỏ
Trâu đứng ăn năm
Trâu nằm ăn ba
Trâu già ba con một bó
Hướng dẫn: tương tự bài toán trên, tuy nhiên biểu thức kiểm tra điều kiện có dạng:
if(td*5+tn*3+tg*1.0/3==100 && td+tn+tg=100)
printf(“…”);
13)Viết chương trình in dãy gồm n số trong dãy số Fibonacci.
Hướng dẫn: trước hết, dãy Fibonacci là dãy có dạng như sau:
1 1 2 3 5 8 13 21 34 55 89 …
Đặt f1,f2 f1 f2
Đặt biến trung gian: tg tg=f2; f2=f1+f2; f1=tg;
f1 f2
tg=f2; f2=f1+f2; f1=tg;
f1 f2 ………………………………………………
int f1,f2,tg;
f1=0;
f2=1;
for(int i=1;i<=n;i++)
{
printf(“%d\t”,f2);
tg=f2;
f2=f1+f2;
f1=tg;
}
14)Viết chương trình nhập vào 2 số nguyên x và y. Hãy tính và xuất ra màn hình ước số
chung lớn nhất và bội số chung nhỏ nhất của 2 số này.
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 25
Hướng dẫn: phải viết thuật toán để có thể tính UCLN và BCNN cho cả số âm lẫn số dương.
Thuật toán được sử dụng ở đây là tính hiệu của 2 số này cho đến khi hiệu bằng 0.
Bội chung nhỏ nhất được tính bởi tích của x*y chia cho ước số chung lớn nhất (bcnn=x*y/ucln)
Chính vì vậy, cần phải tính UCLN và BCNN cho |x| và |y| (trị tuyệt đối).
Ví dụ ucln(8,4)=ucln(-8,4)=ucln(8,-4)=4;
Còn nếu giả sử x=0 và y≠0 thì khẳng định ngay ucln=|y|, mà chương trình không cần tính toán gì cả
int x, y, a, b;
printf(“Nhap vao 2 so x va y: “); scanf(“%d%d”,&x,&y);
a=abs(x);b=abs(y) //cần giữ lại giá trị của 2 số x,y và chỉ thao tác trên giá trị tuyết đối
while(a!=b && a*b!=0)
if(a>b)
a=a-b;
else
b=b-a;
if(a*b==0)
printf("Uoc chung lon nhat va boi chung nho nhat cua %d va %d la: %d va
%d",x,y,a+b,abs(x*y)/(a+b));
else
printf("Uoc chung lon nhat va boi chung nho nhat cua %d va %d la: %d va
%d",x,y,b,abs(x*y)/b);
15)Viết chương trình nhập vào một số nguyên. Hãy đếm số các chữ số và tính tổng các
chữ số của số nguyên vừa nhập. Sau đó, hãy xuất ra màn hình các giá trị vừa tính
được.
Hướng dẫn: để lấy được từng chữ số của một số nguyên, ta lấy từ phải sang trái (tức lấy từ hàng
đơn vị trở lui) như ví dụ sau:
Giả sử cần lấy các chữ số của số x=2358.
Lần 1: x=2358 chuso=x%10 (tức chuso=2358%10=8) lấy được chữ số 8; và x mới nhận giá trị
của các chữ số còn lại: x=x/10 (tức x=2358/10=235).
Lần 2: tương tự lần 1 với x bây giờ là 235 chuso=x%10=5; x=x/10=23.
Lần 3: tương tự với x=23 chuso=x%10=3; x=x/10=2.
Lần 4: tương tự với x=2 chuso=x%10=2; x=x/10=0.
Đến khi x bằng 0 thì dừng lại và tính được tổng các chữ số này.
int x,chuso,tong,dem;
tong=0;
dem=0;
while(x>0)
{
chuso=x%10;
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 26
tong=tong+chuso;
dem++;
x=x/10;
}
16)Viết chương trình nhập vào các tử và mẫu của hai phân số. Hãy cộng 2 phân số này và
xuất kết quả ra màn hình.
Hướng dẫn: giả sử 2 phân số là a/b và c/d cần tính a/b+c/d?
int a,b,c,d,tu,mau;
printf(“Nhập vào tử và mẫu của hai phân số : “);
scanf(“%d%d%d%d”,&a,&b,&c,&d);
tu=a*d+b*c;
mau=b*d;
printf(“Tổng 2 phân số %d/%d + %d/%d = %8.2f”,a,b,c,d,tu*1.0/mau);
17)Viết chương trình nhập vào một số nguyên x. Hãy kiểm tra xem số này có thuộc dãy
Fibonacci hay không và xuất câu khẳng định ra màn hình.
Hướng dẫn: một số không thuộc dãy Fibonacci khi và chỉ khi số đó nằm giữa hai số liên tiếp của
dãy Fibonacci. Chính vì vậy, nếu x vẫn còn lớn hơn f2 thì lặp lại việc tính f2 tiếp theo như sau:
int f1,f2,x;
//x được nhập từ bàn phím
f1=1; f2=1;
while(x>f2)
{
int tg=f2;
f2=f1+f2;
f1=tg;
}
if(x==f2)
printf(“%d thuoc day Fibonacci!”,x);
else
printf(“%d khong thuoc day Fibonacci!!”,x);
18)Viết chương trình nhập vào giá trị của một số thực x. Hãy tính và xuất ra màn hình giá
trị của sin(x) biết:
sin(x)= x - x3/3! + x5/5! - ....+(-1)nx2n+1/(2n+1)!+..........
với sai số cho phép. |x2n+1/(2n+1)!|<1E-4
Hướng dẫn: từ công thức tổng quát ta có số hạng thứ i của tổng là: (-1)ix2i+1/(2i+1)!
double x,tong,E;
int n,i,gt;
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 27
//nhập vào giá trị của x và E
//tính tổng=sin(x)
gt=1;
tong=0;
i=0;
while(fabs(pow(x,2*i+1)/gt)<(E-4) )
{
tong=tong+pow(-1,i)*pow(x,2*i+1)/gt;
i++;
gt=gt*(2*i)*(2*i+1);
}
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 28
BÀI THỰC HÀNH SỐ 3
(Chương III: HÀM VÀ CẤU TRÚC CHƯƠNG TRÌNH
Chương IV: CON TRỎ)
Hàm được sử dụng rất nhiều trong hầu hết các ngôn ngữ lập trình và C cũng vậy. Để sử dụng
hàm trong một chương trình C, cần phải định nghĩa hàm đó trước khi sử dụng chúng. Có 2 cách để
định nghĩa và sử dụng hàm trong C:
Cách 1: Đoạn chương trình định nghĩa hàm đặt trước đoạn chương trình của hàm main như sau
#include
#include
//định nghĩa một hàm max_xy(int x,int y) để tính giá trị lớn nhất của 2 tham biến x và y.
int max_xy(int x,int y)
{
return (x>y?x:y);
}
void main()
{
int x,y;
clrscr();
printf(“Nhap vao 2 so x va y: “);
scanf(“%d%d”,&x,&y);
//gọi hàm max_xy(x,y) để tính giá trị lớn nhất của 2 số x và y vừa mới nhập vào
printf(“Gia tri lon nhat cua x va y la: %d”,max_xy(x,y));
}
Cách 2: Đoạn chương trình định nghĩa hàm đặt sau đoạn chương trình của hàm main, vì vậy cần
phải có câu lệnh khai báo trước cho hàm như sau:
#include
#include
//câu lệnh khai báo trước cho hàm max_xy(int x,int y)
int max_xy(int x,int y);
void main()
{
int x,y;
clrscr();
printf(“Nhap vao 2 so x va y: “);
scanf(“%d%d”,&x,&y);
//gọi hàm max_xy(x,y) để tính giá trị lớn nhất của 2 số x và y vừa mới nhập vào
printf(“Gia tri lon nhat cua x va y la: %d”,max_xy(x,y));
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 29
}
//định nghĩa một hàm max_xy(int x,int y) để tính giá trị lớn nhất của 2 tham biến x và y.
int max_xy(int x,int y)
{
return (x>y?x:y);
}
1) Viết chương trình nhập vào 2 số nguyên x và y. Hãy xây dựng hàm hoán vị giá trị của
2 số nguyên này và xuất ra giá trị của chúng sau khi hoán vị.
Hướng dẫn: sau khi hoán vị, giá trị của x chính là giá trị của y trước hoán vị và giá trị của y chính là
giá trị của x trước hoán vị.
Chương trình sinh viên thường hay viết:
#include
#include
void hoanvi(int x,int y)
{
int tg;
tg=x;
x=y;
y=tg;
}
void main()
{
int x,y;
clrscr();
printf("Nhap vao 2 so x va y : ");
scanf("%d%d",&x,&y);
printf("Gia tri vua nhap: x=%d va y=%d",x,y);
hoanvi(x,y);
printf("\nGia tri vua nhap: x=%d va y=%d",x,y);
getch();
}
Khi chạy chương trình này, giả sử nhập vào x=3,y=5 thì cả 2 dòng lệnh in ra màn hình trên đều
cho x=3 va y=5. Như vậy, hàm hoán vị đã không thực hiện được chức năng hoán vị của nó. Lý do
dẫn đến điều này là chỉ các tham số là con trỏ mới lưu giữ giá trị thay đổi sau khi ra khỏi hàm, còn
các tham số bình thường cho dù có được thay đổi trong thân hàm thì khi ra khỏi hàm cũng vẫn
nhận giá trị trước gọi hàm.
Chương trình đúng cho bài này là:
#include
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 30
#include
//sử dụng con trỏ cho các tham số trong hàm để lưu giá trị sau khi hoán đổi.
void hoanvi(int *x,int *y)
{
int tg;
tg=*x;
*x=*y;
*y=tg;
}
void main()
{
int x,y;
clrscr();
printf("Nhap vao 2 so x va y : ");
scanf("%d%d",&x,&y);
printf("Gia tri vua nhap: x=%d va y=%d",x,y);
hoanvi(&x,&y);
printf("\nGia tri vua nhap: x=%d va y=%d",x,y);
getch();
}
2) Viết chương trình nhập vào một số nguyên dương n. Hãy viết hàm để tính và xuất ra
màn hình giai thừa của n.
Hướng dẫn: trước hết phải đảm bảo giá trị của n khi nhập vào là dương.
long int gthua(int n)
{
if(n==0)
return 1;
else
return n*gthua(n-1);
}
3) Viết chương trình nhập vào một số nguyên dương n. Hãy viết hàm để tính và xuất ra
màn hình số Fibonacci thứ n của dãy số Fibonacci.
Hướng dẫn: trước hết phải viết đoạn lệnh để đảm bảo giá trị của n là dương
int fib_n(int n)
{
if(n==0 || n==1)
return 1;
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 31
else
return fib_n(n-2)+fib_n(n-1);
}
4) Viết chương trình nhập vào 2 số nguyên a và b. Hãy viết hàm để tính và xuất ra màn
hình ước số chung lớn nhất của 2 số trên.
Hướng dẫn: viết hàm tính ước chung lớn nhất của trị tuyệt đối của a và b.
int a,b;
int ucln(int a,int b)
{
a=abs(a);b=abs(b);
if(a==b)
return a;
else if(a*b==0)
return a+b;
else if(a>b)
return ucln(a-b,b);
else
return ucln(a,b-a);
}
5) Viết chương trình xây dựng hàm tính diện tích hình tròn với bán kính R được nhập ở
hàm main.
Hướng dẫn: xây dựng hàm dtht(int R) và gọi hàm này trong hàm main() để tính và in ra diện tích
hình tròn với tham số R là bán kính nhập từ bàn phím.
float pi=3.14;
float dtht(int r) //r là tham biến trong định nghĩa hàm dtht
{
retrun r*r*3.14;
}
void main()
{
float R;
printf(“Nhap vao ban kinh R : “);scanf(“%f”,&R);
printf(“Dien tich hinh tron = %8.2f”,dtht(R));//R là giá trị truyền vào khi gọi hàm dtht
getch();
}
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 32
6) Viết chương trình xây dựng hàm tính tổng các chữ số và hàm đếm số chữ số của một
số nguyên dương. Sau đó hãy gọi 2 hàm này trong hàm main cho một số cụ thể nhập từ
bàn phím.
Hướng dẫn: vì việc đếm và tính tổng các chữ số có thể thực hiện được cùng nhau, nên có 2 giá trị
cần phải trả về đó là tổng các chữ số và số chữ số. Nhưng câu lệnh return trong một hàm chỉ cho
phép trả về một giá trị. Chính vì vậy, cần phải sử dụng các tham biến con trỏ để nhận 2 giá trị trả về
này trong hàm.
int tong_dem_chuso(int n,int *dem,int *tong)
{
int chuso;
while(n>0)
{
chuso=n%10;
*tong=*tong+chuso;
*dem=*dem+1;
n=n/10;
}
}
void main()
{
int n,tong,dem;
printf(“Nhap vao so tu nhien n : “);scanf(“%d”,&n);
tong_dem_chuso(n,&dem,&tong);
printf(“So %d co %d chu so và tong cac chu so = %d”,n,dem,tong);
getch();
}
7) Viết hàm kiểm tra một số có phải là số nguyên tố hay không?
Hướng dẫn: một số là số nguyên tố khi và chỉ khi nó chỉ chia hết cho 1 và chính nó.
int kiemtra_nto(int n)
{
for(int i=2;i<=floor(sqrt(n));i++)
if(n%i==0)
break; //nếu n chia hết cho i, thì dừng vòng lặp for vì có thể khẳng định n là hợp số
if(i>floor(sqrt(n)))
return 1; // n là số nguyên tố, hàm kiểm tra trả về giá trị 1
else
return 0; // n là hợp số
}
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 33
8) Viết chương trình xây dựng hàm tính diện tích hình thang với kết quả trả về nằm ở
biến chứa kết quả kq.
Hướng dẫn: để trả về kết quả ở biến, thì biến đó phải là biến con trỏ (để nhận được giá trị mới sau
khi ra khỏi hàm)
void dththang(float daylon,float daynho,float chieucao,float *kq)
{
*kq=(daylon+daynho)*chieucao/2;
return;
}
9) Viết chương trình xây dựng hàm giải phương trình bậc hai với nghiệm nằm ở biến
chứa nghiệm x1,x2.
Hướng dẫn: định nghĩa hàm với 2 biến con trỏ x1,x2 nhận giá trị trả về của nghiệm.
void ptbac2(float a, float b, float c, float *x1,float *x2);
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 34
BÀI THỰC HÀNH SỐ 4
(Chương V: DỮ LIỆU KIỂU MẢNG)
1) Viết chương trình nhập vào một mảng các số thực từ bàn phím. Hãy viết chương trình
định nghĩa hàm tính số lớn nhất của 2 số thực và sử dụng hàm này để tìm số lớn nhất
trong mảng nói trên.
Hướng dẫn: xây dựng hàm tìm số lớn nhất của 2 số thực. Nhập vào mảng rồi gọi hàm vừa định
nghĩa.
float max_xy(float x,float y)
{
return x>y?x:y;
}
void main()
{
float m[100],max;
int n;
printf(“Nhap vao so phan tu n cua mang : “);scanf(“%d”,&n);
for(int i=1;i<=n;i++)
scanf(“%f”,&m[i]);
max=m[1];
for(i=2;i<=n;i++)
max=max_xy(max,m[i]);
}
2) Viết chương trình trong đó có các hàm: Nhập dãy số, kiểm tra dãy số tăng dần, chèn
một số vào vị trí thích hợp trong dãy tăng dần. Trong hàm main() yêu cầu nhập dãy số
và một số. Kiểm tra nếu dãy số tăng dần thì chèn số vào vị trí thích hợp trong dãy.
//hàm nhập vào một mảng với số phần tử là n
void nhap(int n,float a[])
{
for(int i=1;i<=n;i++)
{
printf(“a[%d]= “,i);
scanf(“%f”,&a[i]);
}
}
//hàm xuất mảng
void xuat(int n,float a[])
{
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 35
for(int i=1;i<=n;i++)
printf(“%.1f “,a[i]);
}
//hàm kiểm tra một mảng có tăng dần hay không? Nếu tăng dần thì trả về ‘C’ (có), ngược lại
//trả về ‘K’ (không)
char ktra_tangdan(float a[])
{
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
if(a[j]<a[i])
break;
if(j<=n)
return ‘K’;
else
return ‘C’;
}
//hàm chèn một số vào vị trí thích hợp: chỉ cho biết số cần chèn, và chính số đó sẽ quyết
định vị trí chèn trong mảng tăng dần.
void chen(float x,float a[])
{
int vt=1;
while(vt<=n && a[vt]<=x)
vt++;
for(int j=n;j>=vt;j--)
a[j+1]=a[j];
a[vt]=x;
}
void main()
{
float a[100],x;
int n;
clrscr();
printf(“Nhap vao so phan tu n cua mang : “);scanf(“%d”,&n);
nhap(n,a);
xuat(n,a);
if(ktra_tangdan(a)==’C’)
printf(“\nMang tang dan!!!”);
else
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 36
printf(“\nMang khong tang dan!!!”);
printf(“\nNhap vao mot so can chen x= “);scanf(“%f”,&x);
chen(x,a);
xuat(n+1,a);
}
3) Viết chương trình trong đó có các hàm: Nhập ma trận, In ma trận, Cộng hai ma trận,
Nhân hai ma trận. Trong hàm main() yêu cầu nhập hai ma trận A nxn, B nxn , In ra
màn hình ma trận A, ma trận B , ma trận tổng, ma trận tích.
void tong_matran(float A[n][n],float B[n][n],float T[n][n])
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
T[i][j]=A[i][j]+B[i][j];
}
void tich+matran(float A[n][n],float B[n][n],float Ti[n][n])
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
float sohang=0;
for(int k=1;k<=n;k++)
sohang=sohang+A[i][k]*B[k][j];
Ti[i][j]=sohang;
}
}
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 37
BÀI THỰC HÀNH SỐ 4
(Chương VI: DỮ LIỆU KIỂU XÂU KÍ TỰ)
Đối với kiểu dữ liệu xâu ký tự, việc sử dụng thành thạo các hàm thuộc thư viện string.h được
xây dựng sẵn trong các phần mềm C là rất cần thiết.
Vào Help chọn Index gõ cụm từ string.h, rồi ấn Enter.
Sau đó click chọn một hàm nào đó cần xem (cấu trúc hàm và cách sử dụng hàm) và ấn Enter.
Một màn hình mới sẽ hiện ra cho bằng tiếng Anh mô tả về hàm. Tuy nhiên, đa số sinh viên ngại
đọc tiếng Anh, nên có thể hiểu được ý nghĩa và công dụng của hàm bằng cách kéo thanh công cụ
xuống dưới đến khi nào gặp mục Example như hình sau:
Sau đó, copy cả đoạn chương trình ví dụ ở trên vào cửa sổ soạn thảo của C và ấn Ctrl-F9 để
chạy chương trình. Đến lúc này, với các giá trị nhập vào và kết quả xuất ra màn hình sẽ phần nào
giúp chúng ta hiểu được chức năng – công dụng của hàm một cách nhanh nhất.
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 38
Việc cấp phát bộ nhớ cho các biến kiểu xâu ký tự trong ngôn ngữ C:
Cách thứ nhất: khai báo theo mảng
char bien[chiều_dài_tối_đa];
lúc này, bộ nhớ sẽ cấp số bytes cho biến bien là chiều_dài_tối_đa + 1 (bytes) để lưu trữ nội
dung của chuỗi bien, trong đó byte cuối cùng lưu trữ ký tự ‘\0’ để báo hiệu chấm dứt chuỗi ký tự
Cách thứ hai: khai báo theo con trỏ
char *bien;
với khai báo này, trước tiên bộ nhớ cấp phát 2bytes dùng để lưu trữ địa chỉ của biến bien (và
chưa cung cấp nơi để lưu trữ dữ liệu của biến bien này). Lúc này, muốn có chỗ để lưu trữ thì phải
sử dụng hàm malloc() hoặc calloc() thuộc thư viện “allloc.h”.
Lưu ý:
Mỗi kí tự của xâu được chứa trong một phần tử của mảng. Để làm việc với phần tử của
xâu kí tự ta gọi qua tên xâu kí tự và chỉ số nó trong xâu theo cú pháp: Tênxâukítự[chỉ
số]; chỉ số này có thể chạy từ 0 tới độ dài cực đại của xâu kí tự. Nếu vị trí đó nằm ngoài
độ dài thực của xâu kí tự thì phần tử đó của xâu kí tự không có gía trị xác định Vì vậy
khi làm việc với xâu ta phải biết được độ dài của xâu bằng cách dùng hàm strlen(xâu).
Vì xâu kí tự là một mảng nên C không cho phép gán hay cộng … các xâu ký tự. Để thực
hiện việc này ta dùng các hàm thuộc thư viện string.h như strcopy, strcat… hoặc gán giá
trị ngay trong lúc khai báo.
Một số hàm xử lý chuỗi (xâu) ký tự thông dụng trong thư viện string.h
1) Hàm strcpy() – để sao chép toàn bộ nội dung của chuỗi nguồn vào chuỗi đích
char *strcpy(char *Des,const char *Source)
Ví dụ: char hoten[30];
strcpy(hoten,”Nguyen Van A”); //gán cho biến hoten xâu ký tự “Nguyen Van A”
//không được gán: hoten=”Nguyen Van A”;
Lưu ý: không được sử dụng phép gán chuỗi ký tự như hoten=”Nguyen Van A” sau khi đã có dòng
khai báo char hoten[30]; mà chỉ có thể vừa khai báo vừa gán giá trị như sau:
char hoten[30]=”Nguyen Van A”;
2) Hàm strcat() –để cộng 2 chuỗi ký tự
char *strcat(char *des, const char *source)
Hàm này có tác dụng ghép chuỗi nguồn (source) vào chuỗi đích (des), tức là sau khi gọi hàm
strcat(dich,nguon) thì hệ thống thực hiện việc ghép chuỗi nguon vào phía sau chuỗi dich rồi gán
chuỗi vừa ghép này cho chuỗi dich.
Ví dụ: char dich[30],nguon[30];
strcpy(dich,”Nguyen Van A”); //tức là gán chuỗi ký tự “Nguyen Van A” vào biến dich
strcpy(nguon,” hoc lop 08T2”); //tức là gán chuỗi ký tự “ hoc lop 08T2” vào biến nguon
strcat(dich,nguon); //lúc này, chuỗi dich=”Nguyen Van A hoc lop 08T2”;
Lưu ý: không được sử dụng phép cộng như dich=dich + nguon; (giống như kiểu dữ liệu số đã học)
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 39
3) Hàm strlen() – để xác định độ dài của chuỗi
int strlen(const char* s)
Hàm này dùng để xác định độ dài của một chuỗi ký tự.
Ví dụ: char hoten[30];
strcpy(hoten,”Nguyen Van A”);
strlen(hoten)=12; //chuỗi hoten trên có chiều dài là 12 ký tự
4) Hàm strupr() – để đổi một chuỗi ký tự thường thành chuỗi ký tự hoa
char *strupr(char *s)
Ví dụ: char hoten[30];
strcpy(hoten,”Nguyen Van A”);
strupr(hoten); //hoten=”NGUYEN VAN A”;
Lưu ý: nếu muốn đổi một ký tự thường thành ký tự hoa thì dùng hàm toupper(char c) trong thư viện
ctype.h
5) Hàm strlwr() – để đổi một chuỗi ký tự thành chuỗi ký tự thường
char *strlwr(char *s)
Ví dụ: char hoten[30];
strcpy(hoten,”Nguyen Van A”);
strlwr(hoten); //hoten=”nguyen van a”;
6) Hàm strncpy() – để sao chép một phần chuỗi, cụ thể là n ký tự đầu tiên của chuỗi
nguồn sang chuỗi đích
char *strncpy(char *Des,const char *Source,size_t n)
Ví dụ: char hoten[30],ho[30];
strcpy(hoten,”Nguyen Van A”);
strncpy(ho,hoten,6);//lấy 6 ký tự từ biến hoten ở trên (chính là xâu “Nguyen”), gán cho biến ho
7) Hàm strchr() – để trích một phần chuỗi (nếu có thì trả về một chuỗi, ngược lại trả về
NULL)
char *strchr(const char *str,int c)
Trong đó, c chính là giá trị mã Ascii của một ký tự, ví dụ c=97 có nghĩa là trích chuỗi từ ký tự ‘a’
hoặc nếu c=101 tức là trích chuỗi từ ký tự ‘e’.
Ví dụ: char hoten[30]=”Nguyen Van A”,st_trich[30];
strcpy(st_trich,strchr(hoten,101));
//trích chuỗi bắt đầu từ ký tự ‘e’ (có mã Ascii 101) từ chuỗi hoten và gán vào cho biến st_trich
//st_trich nhận giá trị là “en Van A”
8) Hàm strstr() – để tìm kiếm nội dung chuỗi (nếu có thì trả về một chuỗi, ngược lại trả
về NULL), cụ thể là tìm kiếm sự xuất hiện đầu tiên của một chuỗi st2 trong chuỗi st1
với cú pháp giả sử là
char *strstr(const char *st1,const char *st2)
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 40
Ví dụ: char st1[30],st2[30],ketqua[30];
strcpy(st1,”Xin chao cac ban”);
strcpy(st2,”chao”);
strcpy(ketqua,strstr(st1,st2)); //chuỗi ketqua nhận giá trị là “chao cac ban”
9) Hàm strcmp() – để so sánh chuỗi, kết quả trả về là một số nguyên có giá trị bằng hiệu
mã Ascii của st1 và st2 tại vị trí đầu tiên xảy ra sự khác nhau (st1<st2 nếu kết quả là số
âm, st1=st2 nếu kết quả bằng 0, và st1>st2 nếu kết quả là số dương)
int strcmp(const char *st1,const char *st2)
Ví dụ: char st1[30]=”xin chao”,st2[30]=”xin loi”;
int ketqua;
ketqua=strcmp(st1,st2); //-9
//do 2 chuỗi st1 và st2 khác nhau từ vị trí thứ 5, tức là ký tự ‘c’ ở chuỗi st1 và ký tự ‘l’ ở chuỗi
//st2, mà mã Ascii của ‘c’=99 và ‘l’=108 nên ketqua=99-108=-9<0, do đó st1<st2
10)Hàm stricmp() – để so sánh chuỗi mà không phân biệt ký tự thường hay hoa, và kết
quả trả về tương tự kết quả trả về của hàm strcmp()
int stricmp(const char *st1,const char *st2)
Ví dụ: char st1[30]=”Xin Chao”,st2[30]=”xin loi”;
int ketqua;
ketqua=stricmp(st1,st2); //-9
11)Hàm memset() – để khởi tạo chuỗi, cụ thể là khởi tạo bằng cách đặt n ký tự đầu tiên
của chuỗi là ký tự c
memset(char *Des,int c,size_t n)
Ví dụ: char matkhau[30];
memset(matkhau,’*’,8); //matkhau=”********”
12)Các hàm atoi(), atof(), atol() – để đổi chuỗi ra số (thuộc thư viện stdlib.h), nếu thành
công thì kết quả trả về là các số nguyên, ngược lại kết quả trả về là 0
int atoi(const char *st);
long atol(const char *st);
float atof(const char *st);
Ví dụ: char soint=”12”,solong=”12”,sofloat=”12.8”;
int soi;
long int sol;
float sof;
soi=atoi(soint); //soi=12 có giá trị số là 12 (còn soint=”12” – là một chuỗi ký tự “12”)
sol=atol(solong); //sol=12 có giá trị số nguyên dài là 12
sof=atof(sofloat); //sof=12.8 có giá tr ị số thực là 12.8
Lưu ý: chuỗi “12” khác với số nguyên có giá trị là 12.
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 41
13)Các hàm tolower() và toupper() thuộc thư viện ctype.h giúp đổi ký tự thành ký tự
thường và ký tự hoa (khác với các hàm strupr() và strlwr() là đổi các chuỗi ký tự)
Ví dụ: char c=’A’,ch=’b’;
c=tolower(c); //c=’a’;
ch=toupper(ch); //ch=’B’;
Bài tập:
1) Hãy viết chương trình nhập vào một chuỗi ký tự, thực hiện việc đổi chuỗi thành chữ
hoa đầu từ bằng hàm Doi_Dau_Tu(). Xuất ra màn hình chuỗi trước và sau khi gọi
hàm.
Hướng dẫn: trước hết cần chèn ký tự trống ‘ ‘ vào phía trước chuỗi st để quy luật được áp dụng
cho cả chuỗi
sử dụng hàm for cho biến i chạy với điều kiện i+1<=len(st)-1 và thực hiện:
Kiểm tra nếu st[i]=’ ‘ và st[i+1]!=’ ‘ thì
Chuyển st[i+1] thành chữ hoa bằng hàm toupper()
2) Viết chương trình nhập vào một chuỗi và một từ. Cho biết từ đó xuất hiện trong chuỗi
bao nhiêu lần?
Hướng dẫn: gọi chuỗi nhập vào là str và từ cần tìm là tu. Để tìm cần phải sử dụng hàm tìm kiếm
chuỗi strstr(str,tu). Tuy nhiên, có thể từ tu xuất hiện nhiều lần trong chuỗi nhưng do hàm strstr() chỉ
trả về vị trí đầu tiên của chuỗi. Chính vì vậy, cần phải dùng vòng lặp while/do…while với điều kiện
strstr(str,tu)!=NULL thì tiếp tục tìm, đồng thời sau khi tìm được thì chuỗi str phải được cắt bớt phần
từ tu.
Ví dụ: char str[80]=”chao co chao thay chao chu chao bac chaochaochao”,tu[4]=”chao”;
//như vậy, số lần xuất hiện của từ “chao” trong chuỗi str là 7 lần.
//nhưng dùng hàm strstr(str,tu) thì chỉ tìm thấy vị trí đầu tiên. Chính vì vậy, sau khi tìm xong
//một từ thì cần phải cắt bỏ phần từ vừa tìm được trong str, cụ thể là str=” co chao thay chao
//chu chao bac” bằng cách đặt ký tự kết thúc xâu ‘\0’ ở vị trí thích hợp
#include
#include
#include
void main()
{
char str[80],tu[4],tam[80];
int dem=0,n;
clrscr();
printf("Nhap vao chuoi ky tu : ");gets(str);
printf("\nNhap vao tu can tim : ");gets(tu);
n=strlen(tu);
strcpy(tam,str);
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 42
while(strstr(tam,tu)!=NULL)
{
dem++;
strcpy(tam,strstr(tam,tu));
//tam[strlen(tam)]='\0';
strrev(tam);
tam[strlen(tam)-n]='\0';
strrev(tam);
}
printf("\nTu %s xuat hien trong chuoi \"%s\" : %d lan",tu,str,dem);
getch();
}
3) Viết chương trình nhập vào một chuỗi ký tự và kiểm tra xem chuỗi đó có đối xứng
hay không?
Hướng dẫn: so sánh chuỗi nhập vào và chuỗi đảo của nó có bằng nhau hay không?
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 43
BÀI THỰC HÀNH SỐ 4
(Chương VII: DỮ LIỆU TỰ ĐỊNH NGHĨA – DỮ LIỆU KIỂU CẤU TRÚC)
Kiểu dữ liệu liệt kê: dùng từ khóa enum và không đọc/ghi trực tiếp các giá trị của nó.
Ví dụ: enum mausac{xanh,tim,vang,do,cam,luc};
enum mausac mau; //khai báo biến mau thuộc kiểu dữ liệu mausac đã định nghĩa ở trên
if(mau==tim)
printf….
Định nghĩa kiểu: dùng từ khóa typedef
Ví dụ: typedef int songuyen; //tạo một kiểu dữ liệu mới có tên là songuyen giong kiểu dữ liệu int
songuyen x;
Kiểu dữ liệu cấu trúc: có thể vừa định nghĩa vừa khai báo biến thuộc kiểu cấu trúc ngay phía
sau dấu kết thúc }. Và từ khóa typedef có thể đặt trước struct hoặc không.
[typedef] struct tênkiểu
{
//khai báo các thành phần của cấu trúc;
}[biến];
Cặp dấu [ ] là có thể có hoặc không có thành phần này.
Ví dụ: typedef struct svien
{
char hoten[40],quequan[40];
int namsinh;
};
svien sv;
1) Viết chương trình nhập vào một chuỗi ký tự và đếm số lần xuất hiện của mỗi loại ký
tự.
Hướng dẫn: định nghĩa một kiểu dữ liệu cấu trúc có thành phần thứ nhất là kiểu ký tự và thành
phần thứ hai là kiểu int chứa số lượng ký tự trong chuỗi, rồi khai báo một mảng các phần tử thuộc
cấu trúc vừa định nghĩa như sau:
typedef struct KyTu_SoLuong
{
char kt;
int sluong;
};
KyTu_SoLuong mang[100];
2) Viết chương trình nhập vào một danh sách các sinh viên, trong đó mỗi sinh viên cần
nhập họ tên, quê quán, năm sinh và điểm toán – lý – hóa. Hãy tính và xuất ra danh
sách sinh viên với điểm trung bình của mỗi sinh viên dưới dạng bảng danh sách.
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 44
Hướng dẫn: định nghĩa kiểu dữ liệu cấu trúc như sau:
struct SinhVien
{
char hoten[40],quequan[40];
int namsinh;
float toan,ly,hoa,dtb;
};
SinhVien sv[100];
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 45
BÀI THỰC HÀNH SỐ 4
(Chương VIII: DỮ LIỆU KIỂU FILE)
Thông thường cần khai báo biến con trỏ kiểu file để dễ quản lý vùng nhớ của file với khai
báo cụ thể như sau:
FILE *fp; (stdio.h)
Câu lệnh fflush: nếu đang ghi mà gặp hàm fflush thì mọi thông tin từ vùng đệm sẽ được đưa
vào file và vùng đệm trở về trạng thái rỗng; ngược lại nếu đang đọc mà gặp hàm fflush thì
vùng đệm cũng được làm rỗng.
Mã LF=10 (bao gồm 2 mã CR=13 và LF=10) ghi từ bộ nhớ ra file
Đọc từ file ra bộ nhớ thì đọc luôn 2 ký tự CR và LF nhưng bộ nhớ sẽ lọc ra và chỉ nhận ký tự
LF
Khi đọc trên file, nếu gặp ký tự có mã 26 thì có nghĩa là kết thúc file (biểu thức cho biết
kết thúc file là EOF=-1)
Các thao tác trên tập tin:
Khai báo biến tập tin (con trỏ tập tin)
Mở tập tin bằng hàm fopen()
Thực hiện các thao tác xử lý dữ liệu bằng các hàm đọc/ghi dữ liệu
Đóng tập tin bằng hàm fclose()
Mở file: cú pháp như sau
Biếnfile = fopen(tênfile trên đĩa, kiểu xử lý file);
Trong đó, tênfile trên đĩa có thể là một hằng kiểu xâu hay một biến kiểu xâu ; kiểu xử lý file thuộc
dạng sau
Kiểu xử lý
File văn
bản
File nhị
phân
Ý nghĩa
“r” “rb” Mở file tồn tại để đọc
“w” ”wb” Mở file mới để ghi
“a” “ab” Mở file đã có và ghi thêm dữ liệu tiếp nối vào cuối file
này. Nếu file này chưa có thì một file mới sẽ được tạo ra.
“r+” “r+b” Mở file đã có và cho phép cả ghi, cả đọc
“w+” “w+b” Mở file mới cho cả ghi và đọc.
“a+” “a+b” Mở file đã có hoặc tạo file mới để đọc và ghi thêm dữ
liệu tiếp nối vào cuối file này hoặc đọc.
Nếu mở một file thành công thì biến con trỏ sẽ trả về giá trị khác NULL, ngược lại (không thành
công) thì con trỏ nhận giá trị NULL.
Đóng file: cú pháp như sau
fclose(biến file);
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 46
Mặc định, nếu kết thúc chương trình mà không đóng file thì file vẫn được đóng bởi hệ thống.
Ghi một ký tự lên file:
File văn bản:
putc(char ch, FILE biếncontrỏ);
fputc(char ch[30], FILE biếncontrỏ) ;
fprintf(FILE biếncontrỏ,…);
File nhị phân :
fwrite(&i,sizeof(int),1, biếncontrỏ);//ghi số nguyên vào file
&i: địa chỉ của một khối dữ liệu, ở đây là địa chỉ của biến i
Tiếp theo là kích thước của khối dữ liệu cần ghi vào, ở đây do ta chỉ ghi 1 số nguyên nên
kích thước của nó là sizeof(int)
Tiếp đến là số khối dữ liệu mà bạn cần ghi vào tệp, ở đây là 1 khối
Cuối cùng là con trỏ cấu trúc tệp
fread(&i,sizeof(int),1,biếncontrỏ);
Lưu ý khi đọc file: kiểm tra xem có hết tệp chưa? Tức là phải khác feof(biếncontrỏ).
Fseek(biếncontrỏ,No*kích_thước_1_phần_tử,SEEK_SET);
Đọc một ký tự từ file và lưu vào biến :
getc(biênfile);
fgetc(str,biênfile);
fscanf();
Hàm feof(biến con trỏ) cho biết đã gặp ký tự kết thúc file hay chưa? Nếu trả về 0 thì chưa, còn trả
về giá trị khác 0 (≠0) thì có nghĩa đã kết thúc file
Hàm với file văn bản:
fprintf, fscanf, fgets, fputs
fprintf(biếncontrỏ, chuỗi điều khiển, danh sách các tham số);
giống như printf nhưng đưa dữ liệu ra file.
fscanf(biếncontrỏ, chuỗi các đặc tả, danh sách địa chỉ các biến);
giống như scanf nhưng dữ liệu nhận từ file.
Con trỏ tập tin: khi một tập tin được mở ra để làm việc, tại mỗi thời điểm sẽ có một vị trí của
tập tin mà tại đó việc đọc/ghi thông tin sẽ xảy ra (có nghĩa là có một con trỏ đang chỉ đến vị
trí đó và đặt tên nó là con trỏ tập tin).
Bài tập:
1) Viết chương trình mở một tập tin văn bản tên VD_File.txt chứa trong ổ đĩa D để ghi
nội dung vào tập tin này.
Hướng dẫn: đây là tập tin văn bản nên phải mở với chế độ “w”
#include
#include
void main()
{
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 47
clrscr();
FILE *fpt;
char filename[50]="D:\\CDCNghe\\GT_CDCN\\GT_THanh\\LT_C\\VD_File.txt";
//fpt=fopen("D:\\CDCNghe\\GiaoTrinhCDCN\\GT_Thuchanh\\LT_C\\ViDuFile.txt","w");
//Lưu ý: Tên thư mục chứa không được đặt quá dài giống như dòng chú thích trên
//Bởi vì nếu để đường dẫn như câu lệnh trên thì sẽ không thực thi được!!!
fpt=fopen(filename,"w");
if(fpt==NULL)
printf("\n Error - Khong mo duoc tep!!!");
else
{
char c;
do
putc(c=getchar(),fpt);
while(c!='\n');
//Ghi cho đến khi gõ vào phím Enter.
fclose(fpt);
}
//getch(); Không cần hàm getch() vì gặp phím Enter là chương trình đã thoát rồi
}
2) Viết chương trình mở một tập tin văn bản tên VD_File.txt chứa trong ổ đĩa D để ghi
nội dung vào tập tin này.
Hướng dẫn: đây là tập tin văn bản nên phải mở với chế độ “w+b” hoặc “wb”
#include
#include
void main()
{
char filename[50]="D:\\CDCNghe\\GT_CDCN\\GT_THanh\\LT_C\\File_NhiPhan.dat";
FILE *fpt;
int i;
clrscr();
fpt=fopen(filename,"w+b");
if(fpt==NULL)
printf("\nError - Khong mo duoc file!!!");
else
{
for(i=1;i<=10;i++)
Bài thực hành
Giảng viên Nguyễn Thị Hà Quyên – Trường CĐCN 48
fwrite(&i,sizeof(int),1,fpt);
fclose(fpt);
}
fpt=fopen(filename,"rb");
//Muốn ghi và đọc file trong cùng một chương trình thì phải đóng file trước khi mở để đọc
//lại file đó
//while(fread(&i,sizeof(int),1,fpt),!feof(fpt))
// printf(“\n%d”i);
do
{
fread(&i,sizeof(int),1,fpt);
if(!feof(fpt))
printf("\n%d",i);
}
while(!feof(fpt));
fclose(fpt);
getch();
}
Các file đính kèm theo tài liệu này:
- Kỹ thuật lập trình C.pdf