Giáo trình thực hành Kỹ thuật lập trình C

Đọ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)

pdf49 trang | Chia sẻ: aloso | Lượt xem: 3021 | Lượt tải: 1download
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:

  • pdfKỹ thuật lập trình C.pdf