Bài giảng Tin học đại cương - Phần 3, Chương 5: Mảng, con trỏ và xâu ký tự

pptx 107 trang haiha333 07/01/2022 3770
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Tin học đại cương - Phần 3, Chương 5: Mảng, con trỏ và xâu ký tự", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pptxbai_giang_tin_hoc_dai_cuong_phan_3_chuong_5_mang_con_tro_va.pptx

Nội dung text: Bài giảng Tin học đại cương - Phần 3, Chương 5: Mảng, con trỏ và xâu ký tự

  1. Phần 3: Lập trình C Nội dung chính • Chương 1: Tổng quan về ngôn ngữ C • Chương 2: Kiểu dữ liệu và biểu thức trong C • Chương 3: Vào ra dữ liệu • Chương 4: Cấu trúc điều khiển • Chương 5: Mảng, con trỏ và xâu ký tự • Chương 6: Cấu trúc • Chương 7: Hàm • Chương 8: Tệp dữ liệu 01-Jan-16 239
  2. Chương 5: Mảng, con trỏ và xâu ký tự Nội dung chính 1. Mảng • Khái niệm • Khai báo và sử dụng • Các thao tác thường gặp 2. Con trỏ • Khái niệm và cách khai báo • Toán tử địa chỉ (&), toán tử nội dung (*) • Phép toán trên con trỏ • Con trỏ và mảng 3. Xâu ký tự • Khái niệm, khai báo và sử dụng • Các hàm xử lý ký tự và xâu ký tự • Mảng xâu ký tự 01-Jan-16 240
  3. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Giới thiệu Bài toán: • Nhập điểm thi (số nguyên) môn Tin đại cương cho lớp gồm 50 sinh viên rồi đưa ra số lượng sinh viên phải học lại Phương pháp: Điểm của mỗi sinh viên là 1 biến • Tên biến là tên sinh viên Ví dụ: int An, Anh, Binh1, Binh2, Cuong, Van, Viet; • Tên biến dạng “dx” với x là chỉ số thứ tự của SV trong lớp Ví dụ: int d1, d2, d3, ,d50; Nhận xét 1: Không hợp lý • Có quá nhiều biến (Điểm thi cho toàn trường !?) • Khó khăn cho các thao tác duyệt toàn bộ danh sách – Số SV học lại: if(d1 <5) d++; if(d2 <5) d++; if(d50 <5) d++; 01-JanNhận-16 xét 2: Các biến có chung ý nghĩa, tính chất 241
  4. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Giới thiệu • Trong thực tế, thường gặp các đối tượng có tính chất chung – Tháng trong năm – Điểm trung bình của sinh viên trong lớp • Các đối tượng được nhóm lại dưới một tên • Đối tượng được đặc trưng bởi tên nhóm và thứ tự trong nhóm – Tháng thứ 3 trong năm: Tháng 3 – Sinh viên thứ 17 trong lớp: • Số thứ tự của đối tương trong nhóm là chỉ 01-Jasn-1ố6 phần tử 242
  5. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Khái niệm mảng • Kiểu mảng là một kiểu dữ liệu gồm – Một số hữu hạn thành phần. – Các thành phần có cùng một kiểu: kiểu cơ sở hay là kiểu thành phần. • Mỗi phần tử của mảng được tham khảo thông qua – Tên mảng và –Chỉ số của phần tử trong mảng Ví dụ: – : Điểm thi tin của sinh viên thứ tự 7 trong lớp 01-Jan-16 243
  6. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Khai báo mảng Kiểu_dữ_liệu Tên_Mảng[Kích thước]; • Kiểu_dữ_liệu: kiểu của các phần tử trong mảng (nguyên, thực, ký tự, chuỗi, mảng, ) • Tên_mảng: tên của mảng • Kích_thước_mảng: số phần tử trong mảng Ví dụ // khai báo mảng 50 phần tử có kiểu dữ liệu int int DiemTin[50]; float A[10]; // Mảng 10 phần tử kiểu số thực 01-Jan-16 244
  7. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Cấp phát bộ nhớ cho mảng • Các phần tử trong mảng được cấp phát các ô nhớ kế tiếp nhau trong bộ nhớ • Kích thước của mảng bằng kích thước một phần tử nhân với số phần tử Ví dụ: int A[10];//Mảng A gồm 10 phần tửnguyên A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] Kích thước của mảng A: 10 x 2 = 20 bytes 01-Jan-16 245
  8. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Truy nhập đến thành phần của mảng • Biến mảng lưu trữ địa chỉ ô nhớ đầu tiên trong vùng nhớ được cấp phát • Ngôn ngữ C đánh chỉ số các phần tử trong mảng bắt đầu từ 0 • Các phần tử của mảng được truy nhập thông qua – Tên mảng và – Chỉ số của phần tử của phần tử trong mảng Tên_Mang[Chỉ_số_phần_tử]; 01-Jan-16 246
  9. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Truy nhập đến thành phần của mảng→Ví dụ int A[10];//Mảng A gồm 10 phần tửnguyên A[0]7 A5[1] A[2] A[3] A7[4] A[5] A[6] A[7] A[8] A[9] A A[0] A[4] A[9] A[0] = 7; A[1] = 5; A[4] = 7; int N = A[1] + A[4]; → N = 12 01-Jan-16 247
  10. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ int A[10]; for(int i = 0; i < 10; i++) A[i]= 2* i; 0? 2? 4? 6? 8? 10? 12? 14? 16? 18? i : 190142563780 Chú ý: C không kiểm tra vượt quá giới hạn của mảng khi truy nhâp int A[3], B[4], C[3]; A[0] A[1] A[2] B[0] B[1] B[2] B[3] C[0] C[1] C[2] 01-Jan-16 A[5] B[2] C[-2] nếu c/cấp liên tiếp 248
  11. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Mảng nhiều chiều • Mỗi phần tử của mảng có thể là một mảng Mảng nhiều chiều Kiểu Tên[Chiều_1] [Chiều_2] [Chiều_N]; • Kiểu: Kiểu của mỗi phần tử trong mảng • Chiều_1, Chiều_2, Chiều_N: Các hằng số nguyên, cho biết kích thước (số phần tử) của mỗi chiều • Mảng gồm: Chiều_1 x Chiều_2 x x Chiều_N phần tử được lưu trữ trong vùng nhớ liên tục. Các phần tử thuộc kiểu Kiểu 01-Jan-16 249
  12. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Mảng nhiều chiều int t[3][4] ; t[0] t[0][0] t[0][1] t[0][2] t[0][3] t[1] t[1][0] t[1][1] t[1][2] t[1][3] t[2] t[2][0] t[2][1] t[2][2] t[2][3] t[1][0] t[1][1] t[1][2] t[1][3] 01-Jan-16 250
  13. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Mảng nhiều chiều→Ví dụ int b[3][4][5]; b[2][2][4] b[2] b[1] b[0] b[0][1][2] • Mảng b gồm 3 phần tử b[0], b[1], b[2] • Mỗi phần tử là mảng hai chiều gồm 4 hàng (hàng 0, 1, 2, 3) và 5 cột (0, 1, 2, 3, 4) • Mỗi phần tử có kiểu nguyên có dấu, 2 byte 01-Jan-16 251
  14. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Khởi tạo giá trị cho mảng Các phần tử của mảng có thể được khởi tạo giá trị ngay khi khai báo Ví dụ int a[4] = {1,4,6,2}; int b[2][3]={ {1,2,3}, {4,5,6} }; int t[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, }; 01-Jan-16 252
  15. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Khởi tạo giá trị cho mảng → Chú ý • Số lượng giá trị khởi tạo không được lớn hơn số lượng phần tử trong mảng – Nếu số lượng này nhỏ hơn, các phần tử còn lại được khởi tạo giá trị 0 int A[3][4] = { {1}, {4,5} }; int A[3][4] = { };Tất cả đều mang giá trị 0 • Có thể xác định kích thước mảng thông qua số giá trị khởi tạo nếu để trống kích thước mảng int A1 [8] = {2, 4, 6, 8, 10, 12, 14, 16}; int A2 [] = {2, 4, 6, 8, 10, 12, 14, 16}; 01-Jan-16 253
  16. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Các thao tác thường gặp • Nhập/Xuất dữ liệu cho mảng – Mảng 1 chiều, ma trận • Bài toán đếm – Đếm số phần tử – Tính toán trên các phần tử • Tìm kiếm phần tử – Lớn nhất/nhỏ nhất/bất kỳ • Sắp xếp phần tử trong mảng – Theo thứ tự, theo nguyên tắc • Chèn thêm phần tử, xóa phần tử 01-Jan-16 254
  17. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Nhập dữ liệu Dùng hàm scanf() Ví dụ: int Table[10]; • Nhập dữ liệu cho một phần tử scanf(“%d”,&Table[2]);phần tử thứ 3 của mảng • Nhập dữ liệu cho cả mảng – Dùng vòng lặp for for(i = 0; i < 10; i++) scanf(“%d”,&Table[i]); – Nên in ra chỉ số phần tử khi nhập printf(“Table[%d] : ”,i); scanf(“%d”,&Table[i]) 01-Jan-16 255
  18. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Nhập dữ liệu→Ví dụ 1 Nhập vào lượng mưa (mm) trong năm #include #define MONTHS 12 int main(){ int rainfall[MONTHS], i; for ( i=0; i < MONTHS; i++ ){ printf(“Nhap luong mưa tháng %d: “, i+1); scanf("%d", &rainfall[i] ); } return 0; } 01-Jan-16 256
  19. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Nhập dữ liệu→Lưu ý • Nếu số phần tử của mảng chỉ được biết tại thời điểm thực hiện chương trình (nhưng biết số phần tử tối đa) – Khai báo mảng với kích thước tối đa – Sử dụng biến nguyên lưu số phần tử thực sự của mảng. Ví dụ: • Nhập vào mảng không quá 100 số thực – Khai báo mảng thực Table có tối đa 100 phần tử. – Nhập số phần tử thực sự của mảng – Nhập giá trị cho từng phần phần tử (dùng for) 01-Jan-16 257
  20. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Nhập dữ liệu→Ví dụ 2 #include void main(){ float A[100]; int n, i; do{ printf(“\n Cho biet so phan tu cua mang: “); scanf(“%d”,&n); }while (n>100 || n<=0); for(i = 0; i < n; i++){ printf(“A[%d] = ", i); scanf("%f",&A[i]); } } 01-Jan-16 258
  21. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Xuất dữ liệu trong mảng Dùng hàm printf() Ví dụ: int Table[10]; • Hiện thị phần tử thứ 5: printf(“%d”,Table[4]); • Để hiển thị tất cả các phần tử: for(i = 0; i < 10; i++) printf(“%4d”,Table[i]); Các kiểu xuất dữ liệu – Hiển thị tất cả/một phần theo dòng/cột – Hiển thị từng k phần tử trên một dòng 01-Jan-16 259
  22. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Xuất dữ liệu trong mảng→Ví dụ 1 #include #define MAX 12 void main(){ int A[MAX], i; for ( i=0; i < MAX; i++ ){ //Nhập dữ liệu printf(“A[%d]: “, i+1); scanf("%d", &A [i] ); } ffoorr (( ii==00;; ii<<MMAAXX;ii++++ )){ pppriinntf(""%%4dd\n”””,,,AAA[[i[i]i])]););; if( (i+1) %4==0) printf(“\n”); } } 01-Jan-16 260
  23. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Xuất dữ liệu trong mảng→Ví dụ 1→Thực hiện 01-Jan-16 261
  24. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ 2: Nhập và đưa ra màn hình một ma trận 1. #include 2. void main(){ 3. int A[20][20], n, m, i,j; 4. printf("Nhap so hang : "); scanf("%d",&n); 5. printf("Nhap so cot : "); scanf("%d",&m); 6. printf("\n"); 7. for ( i=0; i < n; i++ ) 8. for(j=0; j < m; j++) { 9. printf("Nhap phan tu A[%d,%d]: ", i+1,j+1); 10. scanf("%d", &A[i][j] ); 11. } 12. printf("\n\n MA TRAN DA NHAP\n\n"); 13. for ( i=0; i < n; i++ ){ 14. for(j=0; j < m; j++) 15. printf( "%4d" ,A[i][j]); 16. printf("\n"); 17. } 011-J8an.-1}6 262
  25. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ 2→Kết quả thực hiện 01-Jan-16 263
  26. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Đếm số phần tử thỏa mãn điều kiện • Duyệt từng phần tử của dãy (dùng for ) • Nếu phần tử xét thỏa mãn điều kiện – Ghi nhận • Chuyển sang xem xét phần tử tiếp theo Ví dụ: Đếm số tháng có lượng mưa lớn hơn 50mm int dem = 0; for(i = 0; i 50) dem++; printf("\nThang mua nhieu hon 50mm: %d", dem); 01-Jan-16 264
  27. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ: Nhập mảng, đưa ra TBC các số chia hết cho 7 #include void main(){ intA[100]; int n, i, d = 0, S=0; printf(“\n So phan tu cua mang ( 0) printf(”TBC so chia het cho 7: %7.2f”,(float)S/d); else printf(”Trong day khong co so chia het cho 7”); 0}1-Jan-16 265
  28. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Tìm kiếm phần tử Tìm phần tử lớn nhất (nhỏ nhất) – Giả sử phần tử đó là phần tử đầu tiên – Lần lượt so sánh với các phần tử còn lại • Nếu phần tử mới của dãy lớn hơn coi đây là phần tử lớn nhất và tiếp tục so sánh với phần tử kế • Nếu không đúng, so sánh tiếp với phần tử kế Ví dụ: Tìm tháng có lượng mưa nhiều nhất trong năm max = rainfall[0]; for(i = 1; i max) max = rainfall[i]; printf("\n Luong mua nhieu nhat la: %d", max); 01-Jan-16 266
  29. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Tìm kiếm phần tử • Tìm kiếm các phần tử thỏa mãn điều kiện (giống bài toán đếm) – Dùng for duyệt toàn bộ – Nếu cần thiết, dùng thêm mảng ghi lại chỉ số Ví dụ: Đưa ra danh sách các tháng có lượng mưa nhiều hơn 50mm printf(“Thang co luong mua lon hon 500mm”) for(i = 0; i 50) printf("\nThang %d", i+1); 01-Jan-16 267
  30. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Tìm kiếm phần tử (tiếp) • Tìm phần tử đầu tiên của danh sách – Dùng vòng lặp for kết hợp với break; – Dùng vòng lặp while Ví dụ Đưa ra phần tử đầu của mảng có giá trị bằng k; 01-Jan-16 268
  31. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Tìm kiếm phần tử →Ví dụ int Table[100] int N, i, k, f;//N: số phần tử, k phần tử cần tìm Dùng for for(i = 0; i < N; i++) if(Table[i] == k) break; if(i< N) printf(“Tim thay tai vi tri %d“,i); Dùng while i=0; f =0; //f: found. f = 1 k is found while(i < N && f==0){ if(Table[i] == k) f = 1; else i++;} if (f==1) printf(“Tim thay tai vi tri %d”,i); 01-Jan-16 269
  32. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài tập 1 1. Nhập vào dãy (<100) số, tính và đưa ra màn hình • Tổng và tích của dãy số • Các số chia hết cho 3 và lớn hơn 10 • Đếm các số nằm trong đoạn [100,1000) 2. Nhập vào một dãy số; tìm số chẵn nhỏ nhất dãy 3. Nhập dãy số; đếm xem có bao nhiêu bộ 3 số thỏa mãn điều kiện xi=(xi-1+xi+1)/2 4. Viết chương trình nhập vào từ bàn một dãy số (<100 phần tử). Đưa ra số bé nhất và vị trí những số bằng số bé nhất 5. Nhập vào n và dãy số (x1,x2, xn) ;(y1,y2, yn) rồi tính n n n−1 2 a) cosx sin x b) (x − y ) c) xi+1 y  i i  i i  2 i+1 i=1 i=1 1 01-Jan-16 270
  33. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài 1 01-Jan-16 271
  34. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài toán sắp xếp theo thứ tự • Cho mảng phần tử, sắp xếp theo thứ tự tăng/giảm • Các thuật toán – Sắp xếp thêm dần (insertion sort) – Sắp xếp lựa chọn (selection sort) – Sắp xếp nổi bọt (bubble sort) – Sắp xếp vun đống (heap sort) – Sắp xếp nhanh (quick sort) – Sắp xếp trộn (merge sort) – . 01-Jan-16 272
  35. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài toán sắp xếp tăng →Thuật toán lựa chọn Nguyên tắc Tại lượt sắp thứ k, tìm phần tử nhỏ nhất trong số các phần tử chưa được sắp xếp ([k last]) và đổi chỗ cho phần tử thứ k (có chỉ số k-1) – Khi k = 1, phần tử thứ nhất (chỉ số 0) đúng vị trí – Khi k= 2, phần tử thứ hai (chỉ số 1) đúng vị trí 01-Jan-16 273
  36. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài toán sắp xếp tăng →Thuật toán lựa chọn Dãy Lượt 1 Lượt 2 Lượt 3 Lượt 4 3 132 1 1 1 1 5 5 532 2 2 2 2 32 35 35 3 3 6 6 6 6 56 5 1 21 23 53 65 6 01-Jan-16 274
  37. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài toán sắp xếp tăng →Thuật toán lựa chọn //Khai báo các biến int A[100]; //Mảng chứa dữ liệu int N, i, j, tmp; //Sắp xếp for(i = 0; i A[j]) { tmp = A[i]; A[i] = A[j]; A[j] = tmp; } 01-Jan-16 275
  38. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ Nhập vào từ bàn phím một mảng các số nguyên không quá 100 phần tử Hiển thị dãy số vừa nhập Sắp xếp dãy theo thứ tự giảm dần Hiện thị dãy tại mỗi lượt sắp xếp 01-Jan-16 276
  39. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ 1. #include 2.void main(){ 3. int A[100] ; 4. int N, i, j , t; 5. printf("So phan tu [< 100]: "); scanf("%d",&N); 6. printf("Hay nhap day so \n"); 7. for(i=0; i < N; i++){ 8. printf("A[%d] = ",i+1); scanf("%d",&A[i]); 9. } 10. printf("\nDay vua nhap \n"); 11. for(i=0; i < N; i++) 12. printf("%4d", A[i]); 13. printf("\n\n"); 01-Jan-16 277
  40. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ 14. printf("Sap xep day theo thuat toan lua chon"); 15. for(i=0; i < N-1; i++){ 16. for(j=i+1; j < N; j++) 17. if(A[i] < A[j]) { 18. t = A[i]; 19. A[i] = A[j]; 20. A[j] = t; 21. }//if & for_j 22. printf("\nLuot %d : ",i+1); 23. for(j=0; j < N; j++) 24. printf("%4d", A[j]); 25. }//for_i 26. }//main 01-Jan-16 278
  41. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Ví dụ→Kết quả 01-Jan-16 279
  42. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài toán chèn phần tử a vào vị trí k for(i = N; i > k; i ) 2 A[i] = A[i-1]; 5 k A[k] = a; 78 7 N= N + 1; 84 Chú ý: 49 N = MAX: không chèn được k > N → Chèn vào vị trí N; 9? k< 0 → Chèn vào vị trí 0 01-Jan-16 280
  43. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài toán xóa phần tử ở vị trí k (0 k<N) 2 5 for(i = k+1; i < N; i++) k 38 A[i-1] = A[i]; 39 N= N - 1; N 49 4 01-Jan-16 281
  44. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài tập 2 1. Nhập vào từ bàn phím một dãy số nguyên ( n, chèn x vào vị trí n+1. 3. Nhập vào một dãy số (<100 phần tử) và sắp xếp theo thứ tự tăng dần. Nhập thêm vào một số và chèn số mới nhập vào đúng vị trí 4. Nhập vào một dãy (<100 phần tử); xóa đi các phần tử chia hết cho 5 và đưa kết quả ra màn hình 01-Jan-16 282
  45. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài chữa #include void main(){ int A[100]; int N, i; //Nhập dữ liệu printf("So phan tu : "); scanf("%d",&N); for(i=0; i < N; i ++){ printf("A[%d] = ",i);scanf("%d",&A[i]); } //Các thao tác xử lý mảng: chèn, xóa, sắp xếp, //Đưa Dữ liệu ra for(i=0; i < N; i ++) printf("%4d",A[i]); } 01-Jan-16 283
  46. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài chữa → Sắp xếp số chẵn chia hết 3 lên đầu dãy 1. { int d = 0, t; 2. for(i=0;i < N; i++) 3. if(A[i]%6==0){ 4. t=A[i]; A[i]=A[d]; A[d] = t; 5. d++; 6. } 7. for(i=d; i < N; i++) 8. if(A[i]%3 != 0){ 9. t=A[i]; A[i]=A[d]; A[d] = t; 10. d++; 11. } 12. } 01-Jan-16 284
  47. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài chữa → Sắp xếp tăng dần và chèn đúng vị trí 1. { int k = 0,i, j, t; 2. for(i=0;i A[j]){ 5. t = A[j]; A[j] = A[i]; A[i]=t; 6. } 7. printf("Phan tu moi:"); scanf("%d",&k);//Nhập p/tử mới 8. i = N; //Chèn đúng vị trí 9. while( (i > 0) &&(A[i-1] > k) ){ 10. A[i] =A[i-1]; 11. i ; 12. } 13. A[i] = k; 14. N++; 15. } 01-Jan-16 285
  48. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài chữa → Xóa các phần tử chia hết cho 5 1. { // PP: Giữ lại các phần tử không chia hết cho 5 2. int d = 0, i; 3. for(i=0;i < N; i++) 4. if(A[i] % 5 != 0){ 5. A[d] = A[i]; 6. d++; 7. } 8. N = d; 9. } 01-Jan-16 286
  49. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Xóa các phần tử chia hết cho 5 →Kết quả 01-Jan-16 287
  50. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Bài tập 3 : Ma trận 1. Viết chương trình nhập vào một ma trận vuông, các phần tử nguyên, sau đó • Đưa ra ma trận tam giác duới • Đưa ra ma trận tam giác trên 2. Nhập M, N (M, N < 30) và một ma trận MxN. Đưa ma trận ra màn hình • Tìm hàng/cột có tổng các phần tử lớn nhất • Tìm số lớn nhất/nhỏ nhất và vị trí trong ma trận • Đưa ra ma trận S cùng kích thước thỏa mãn 1 nê'u ui, j 0 = si, j 0 nê'u ui, j = 0 −1 nê'u ui, j 0 01-Jan-16 288
  51. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Nhập vào một ma trận vuông, #include void main(){ int A[20][20], N,i,j; printf("Nhap kich thuoc : "); scanf("%d",&N); printf("\n"); for ( i=0; i < N; i++ ) for(j=0; j < N; j++) { printf("Nhap phan tu [%d,%d]:", i+1,j+1); scanf("%d", &A[i][j] ); } printf("\n\n MA TRAN DA NHAP\n\n"); for ( i=0; i < N; i++ ){ for(j=0; j < N; j++) printf( "%4d" ,A[i][j]); printf("\n"); 01-Jan-1}6 289
  52. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Đưa ra ma trân tam giác trên, dưới printf("\n\n MA TRAN TAM GIAC TREN \n\n"); for ( i=0; i = i) printf( "%4d" ,A[i][j]); else printf("%4c",32); //32 là mã ASCII của dấu cách printf("\n"); } printf("\n\n MA TRAN TAM GIAC DUOI \n\n"); for ( i=0; i < N; i++ ){ for(j=0; j <= i; j++) printf( "%4d" ,A[i][j]); printf("\n"); } 0}1/-J/amn-a16in 290
  53. Chương 5: Mảng, con trỏ và xâu ký tự 5.1 Mảng Thực hiện 01-Jan-16 291
  54. Chương 5: Mảng, con trỏ và xâu ký tự Nội dung chính 1. Mảng • Khái niệm • Khai báo và sử dụng • Các thao tác thường gặp 2. Con trỏ • Khái niệm và cách khai báo • Toán tử địa chỉ (&), toán tử nội dung (*) • Phép toán trên con trỏ • Con trỏ và mảng 3. Xâu ký tự • Khái niệm, khai báo và sử dụng • Các hàm xử lý ký tự và xâu ký tự • Mảng xâu ký tự 01-Jan-16 292
  55. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Giới thiệu • Là một khái niệm “mạnh“ 00000 trong C 00001 – Cho phép tính toán trên con trỏ – Sử dụng con trỏ hàm Biến • Cho phép truy nhập gián tiếp tới một đối tượng có địa chỉ (biến, hàm) Con trỏ – Truy nhập trực tiếp→ thông qua tên FFFFF Bộ nhớ 01-Jan-16 293
  56. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Địa chỉ • Bộ nhớ gồm dãy các ô nhớ – Mỗi ô nhớ là một byte – Mỗi ô nhớ có một địa chỉ riêng • Các biến trong chương trình được lưu tại vùng nhớ nào đó trong bộ nhớ • Khi khai báo biến, tùy thuộc vào kiểu, biến sẽ được cấp một số ô nhớ liên tục nhau – Biến int được cấp 2 bytes, float được cấp 4 bytes, – Địa chỉ của biến, là địa chỉ của byte đầu tiên trong số các byte được cấp – Khi gán giá trị cho biến, nội dung các byte cung cấp cho biến sẽ thay đổi 01-Jan-16 294
  57. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Địa chỉ →Ví dụ int N; float x; Địa chỉ biến N E8? N char Arr[4]; Địa chỉ biến X 03? 00? 00? X N = 1000;//03E8 1B? Địa chỉ biến Arr 41? X=9.6875;//411B0000 01? for(i=0;i<4;i++) 05? 09? Arr Arr[i]= 4*i+1; 0D? Địa chỉ của một biến là địa chỉ byte nhớ đầu tiên được cung cấp cho Bộ nhớ biến để lưu trữ dữ liệu 01-Jan-16 295
  58. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Con trỏ • Con trỏ là một biến mà 0000 giá trị của nó là địa chỉ Biến nhớ của một vùng nhớ EB03 ABCD – Vùng nhớ này có thể dùng để chứa các biến có kiểu cơ bản (nguyên, thực, ký tự, ) hay có cấu trúc (mảng, bản ghi, ) • Con trỏ dùng “trỏ tới” một ABCD EFCD biến nhớ Biến con trỏ – Có thể trỏ tới một hàm FFFF – Có thể trỏ tới con trỏ khác Bộ nhớ 01-Jan-16 296
  59. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Con trỏ →Khai báo Kiểu * Tên; • Tên: Tên của một biến con trỏ • Kiểu: Kiểu của biến mà con trỏ “Tên” trỏ tới – Giá trị của con trỏ có thể thay đổi được • Trỏ tới các biến khác nhau, có cùng kiểu – Kiểu biến mà con trỏ trỏ tới không thay đổi được • Muốn thay đổi phải thực hiện “ép kiểu” Ví dụ: int * pi; //Con trỏ, trỏ tới một biến kiểu nguyên char * pc; //Con trỏ, trỏ tới một biến kiểu ký tự 01-Jan-16 297
  60. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Toán tử địa chỉ (&) • Ký hiệu: & 0000 • Là toán tử một ngôi, trả Biến N về địa chỉ của biến ABCD – Địa chỉ biến có thể được gán cho một con trỏ, trỏ tới đối tượng cùng kiểu Ví dụ ABCD EFCD int N; // &N→ ABCD Biến pi int * pi; FFFF pi = &N; // piABCD Bộ nhớ 01-Jan-16 298
  61. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Toán tử nội dung (*) • Ký hiệu: * 0000 • Là toán tử một ngôi, trả về giá Biến N trị (nội dung) của vùng nhớ mà 210 ABCD con trỏ đang trỏ tới Ví dụ int N; int * pi; pi = &N; N= 10; *pi = 10; ABCD EFCD N = 10;//Vùng nhớ mà pi trỏ tới Con trỏ pi mang giá trị 10; Vậy *pi=10 *pi = 20;// Vùng nhớ pi trỏ tới được FFFF gán giá trị 20; Vậy N= 20 Bộ nhớ 01-Jan-16 299
  62. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Gán giá trị cho con trỏ • Con trỏ được gán địa chỉ của một biến – Biến cùng kiểu với kiểu mà con trỏ trỏ tới • Nếu không, cần phải ép kiểu • Con trỏ được gán giá trị của con trỏ khác – Hai con trỏ sẽ trỏ tới cùng một biến(do cùng địa chỉ) – Hai con trỏ nên cùng kiểu trỏ đến • Nếu không, phải ép kiểu • Con trỏ được gán giá trị NULL Ví dụ: int *p; p = 0; • Gán nội dung vùng nhớ 2 con trỏ trỏ tới. Ví dụ: int *p1, *p2; *p1 = *p2; 01-Jan-16 300
  63. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Ví dụ #include #include void main(){ void main(){ int N=5, M=10; int N=5, M=10; int *p1 = &N; int *p1 = &N; int *p2 = &M; int *p2 = &M; *p1 = *p2; p1 = p2; printf("%d %d",*p1,*p2); printf("%d %d",*p1,*p2); } } 10 10 10 10 01-Jan-16 301
  64. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Ví dụ→Trường hợp 1 0000 1. #include 2. void main(){ 105 ABCD 3. int N=5, M=10; 10 ABCF 4. int *p1 = &N; 5. int *p2 = &M; ABCF p2 6. *p1 = *p2; ABCD p1 7. printf("%d %d",*p1,*p2); 8. } FFFF Bộ nhớ 01-Jan-16 302
  65. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Ví dụ→Trường hợp 2 0000 1. #include 2. void main(){ ABCD 3. int N=5, M=10; 5 ABCF 4. int *p1 = &N; 10 5. int *p2 = &M; p2 6. p1 = p2; ABCF p1 7. printf("%d %d",*p1,*p2); AABCFBCD 8. } FFFF Bộ nhớ 01-Jan-16 303
  66. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Các phép toán trên con trỏ • Cộng con trỏ với một số nguyên – Kết quả: Con trỏ cùng kiểu • Trừ con trỏ với một số nguyên – Kết quả: Con trỏ cùng kiểu • Trừ 2 con trỏ cùng kiểu cho nhau – Kết quả: Một số nguyên • Khoảng cách giữa 2 con trỏ được đo bằng số phần tử thuộc kiểu dữ liệu mà con trỏ trỏ tới 01-Jan-16 304
  67. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Các phép toán trên con trỏ→Ví dụ int N=1000, M=2000,P=3000; 0000 int * p1 = &P, *p2 = &N; P E8 ABC0 03 ABC1 M D0 ABC2 p1 - p2 → -2 07 ABC3 N B8 ABC4 0B ABC5 * (p2-1) → 2000 ABC6 * ++ p1 → 2000 p2 ABC4 p1 ABC2ABC0 Ghi chú: • Kiểu int, các phần tử cách nhau 2 bytes FFFF • Kiểu float, các phần tử cách nhau 4 bytes Bộ nhớ 01-Jan-16 305
  68. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Mối quan hệ giữa con trỏ và mảng một chiều • Nếu T là tên một mảng T là một con trỏ hằng chứa địa chỉ của phần tử đầu tiên của mảng T (&T [0]) – Không tồn tại phép tính trên tên mảng, hoặc gán giá trị cho tên mảng (VD: T= ; T++) • Có thể sử dụng một con trỏ để duyệt mảng nếu nó được gán giá trị bằng địa chỉ của mảng (địa chỉ của phần tử đầu tiên) 01-Jan-16 306
  69. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Ví dụ int A[10]; int * p = A; // int *p = &A[0] for(i = 0; i < 10; i ++) printf(“%d ”, *(p + i) ); for(i = 0; i < 10; i ++) printf(“%d ”, p[i]); for(i = 0; i < 10; i ++) printf(“%d ”, *(p++) ); 01-Jan-16 307
  70. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Con trỏ void void * Tên_con_trỏ • Là một con trỏ đặc biệt: con trỏ không có kiểu • Có thể nhận giá trị là địa chỉ của một biến có kiểu dữ liệu bất kỳ – Thường dùng làm đối số trong lời gọi hàm để cóthể nhận bất kỳ kiểu địa chỉ nào của tham số được truyền Ví dụ: void * p, *q; int n; float x; p = & n; q= & x; \\Các câu lệnh hợp lệ 01-Jan-16 308
  71. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Câu hỏi 1 #include int main() 30 { int a=3, *p; p = &a; printf("%d\n", a * *p * a + *p); return 0; } 01-Jan-16 309
  72. Chương 5: Mảng, con trỏ và xâu ký tự 5.2 Con trỏ Câu hỏi 2 #include int main(){ int arr[2][2][2] = {10, 2, 3, 4, 5, 6, 7, 8}; int *p, *q; p = &arr[1][1][1]; q = (int *) arr; 8, 5 printf("%d, %d\n", *p, *(q+4) ); return 0; } 01-Jan-16 310
  73. Chương 5: Mảng, con trỏ và xâu ký tự Nội dung chính 1. Mảng • Khái niệm • Khai báo và sử dụng • Các thao tác thường gặp 2. Con trỏ • Khái niệm và cách khai báo • Toán tử địa chỉ (&), toán tử nội dung (*) • Phép toán trên con trỏ • Con trỏ và mảng 3. Xâu ký tự • Khái niệm. khai báo và sử dụng • Các hàm xử lý ký tự và xâu ký tự • Mảng xâu ký tự 01-Jan-16 311
  74. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Khái niệm xâu ký tự • Xâu kí tự (string) là một dãy các kí tự viết liên tiếp nhau – Độ dài xâu là số kí tự có trong xâu – Xâu không có kí tự nào: Xâu rỗng • Ví dụ: “Tin hoc”, “String” • Lưu trữ: kết thúc xâu bằng kí tự ‘\0’ hay NULL (mã ASCII là 0) ‘T’ ‘i’ ‘ n ‘ ‘ ‘ ‘h’ ‘o’ ‘c’ ‘\0’ 01-Jan-16 312
  75. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Khái niệm xâu ký tự→Lưu ý • Xâu kí tự > được lưu trữ trong 2 byte 01-Jan-16 313
  76. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Khai báo char tên_xâu [số_kí_tự_tối_đa]; • Để lưu trữ một xâu có n kí tự chúng ta cần một mảng có kích thước n+1 – Phần tử cuối cùng chứa ký tự NULL Ví dụ • Để lưu trữ xâu “Tin hoc” chúng ta phải khai báo xâu có số phần tử tối đa ít nhất là 8 char str[8] = “Tin hoc”; ‘T’ ‘i’ ‘ n ‘ ‘ ‘ ‘h’ ‘o’ ‘c’ ‘\0’ 01-Jan-16 314
  77. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Truy nhập phần tử của xâu Giống như truy nhập tới một phần tử của mảng ký tự tên_xâu [chỉ_số_của_kí_tự] Ví dụ: char Str[10] = “Tin hoc”; T i n - h o c \0 ?1 \?0 Str[0] → ‘T’ Str[3] = ‘-’; Str[3] → ‘ ’ Str[7] = ‘ ’; Str[7] → ‘\0 ‘ Str[8] = ‘1 ‘ ; Str[8] → ? Str[9] = ‘\0’; Str: Tin-hoc 1 01-Jan-16 315
  78. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ: Nhập xâu và đếm số ký tự ‘*’ #include Tính chiều dài của xâu void main(){ d=0; char Str[100]; while(Str[d] != '\0') d++; int d=0, i=0; printf("Nhap xau ky tu: "); gets(Str); while(Str[i] != '\0'){ if(Str[i]=='*') d++; i++; } printf("Ket qua : %d",d); } 01-Jan-16 316
  79. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ: Nhập câu và đưa ra dưới dạng cột 1. #include 2. void main(){ 3. char S[100]; 4. int i=0; 5. printf("Nhap xau: "); gets(S); 6. while(S[i] != '\0'){ //32 là mã ASCII của phím space 7. if(S[i] != 32 && S[i+1]==32) printf("%c\n",S[i]); 8. else if(S[i] != 32) printf("%c",S[i]); 9. i++; 10. } 11. printf(“\n\n”); Đếm số từ, nếu các từ 12.} được cách nhau bởi dấu phân cách 01-Jan-16 317
  80. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý ký tự Tệp tiêu đề : ctype.h #include 01-Jan-16 318
  81. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý ký tự→Chuyển đổi chữ hoa/thường • int toupper(char ch): – Chuyển kí tự thường thành kí tự hoa toupper(‘a’) => ‘A’ • int tolower(char ch) – Chuyển kí tự hoa thành kí tự thường tolower(‘B’) => ‘b’ Ví dụ do{ . printf(“Tiep tuc ? :”); fflush(stdin); }while(toupper(getche()) !='K'); 01-Jan-16 319
  82. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý ký tự →Kiểm tra chữ hoa/thường • int islower(char ch) – Kiểm tra chữ thường: • Hàm trả về giá trị khác 0 nếu ch là chữ thường, ngược lại trả về 0 • Ví dụ: printf("%d ",islower('A')); 0 • int isupper(char ch): – Kiểm tra chữ hoa: • Hàm trả về giá trị khác 0 nếu ch là chữ hoa, ngược lại trả về 0 • Ví dụ: printf("%d ",isupper('A')); ≠ 0 (1 !?) 01-Jan-16 320
  83. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý ký tự →Kiểm tra chữ cái/chữ số • int isalpha(char ch): – Kiểm tra kí tự trong tham số có phải chữ cái không (‘a’ ’z’,’A’, ’Z’). Hàm trả về khác 0 nếu đúng, ngược lại trả về giá trị bằng 0 – Ví dụ: printf("%d ",isalpha('A')); ≠ 0 (1 !?) • int isdigit(char ch): – Kiểm tra kí tự trong tham số có phải chữ số (‘0‘,‘1‘, ‘9‘) không. Hàm trả về khác 0 nếu đúng, ngược lại trả về giá trị bằng 0 – Ví dụ: printf("%d ",isdigit('A')); 0 01-Jan-16 321
  84. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Khái niệm xâu ký tự→Kiểm tra ký tự đặc biệt • int iscntrl(char ch) – Kiểm tra kí tự điều khiển (0-31). – Hàm trả về khác 0 nếu đúng, ngược lại trả về giá trị bằng 0 • int isspace(char ch) – Kiểm tra kí tự dấu cách (mã 32), xuống dòng (‘\n’ 10), đầu dòng (‘\r’ 13), tab ngang (‘\t’ 9), tab dọc (‘\v’ 11). – Hàm trả về khác 0 nếu đúng, ngược lại trả về giá trị bằng 0 01-Jan-16 322
  85. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ: Nhập xâu, chuyển thành xâu chữ hoa 1. #include 2. #include 3. void main(){ 4. int i =0; 5. char S[50]; 6. printf("Nhap mot xau: "); gets(S); 7.printf("\n\nXau ban dau : %s. ",S); 8. while(S[i] != '\0'){ 9. S[i] = toupper(S[i]); 10. i = i + 1; 11. } 12. printf("Xau ket qua : %s",S); 13. } 01-Jan-16 323
  86. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ: Nhập xâu và đếm từ, phân cách bởi dấu trắng #include #include #include int main(){ char Str[100]; int d=0, i=0; printf("Nhap xau ky tu: "); gets(Str); if(Str[0] == '\0') printf(“ Xau rong "); else{ if( ! isspace(Str[0]) ) d=1; i=1; while(Str[i] != '\0'){ if( isspace(Str[i-1] ) && (! isspace(Str[i])) ) d++; i++; } printf("Ket qua : %d",d); } 01}-Jan-16 324
  87. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý xâu ký tự Vào/ra xâu ký tự • Tệp tiêu đề: stdio.h • Nhập xâu kí tự – gets(tên_xâu); – scanf(“%s”,&tên_xâu); • Hiển thị xâu kí tự – puts(tên_xâu); – printf(“%s”,tên_xâu); Sự khác nhau giữa gets và scanf? 01-Jan-16 325
  88. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý xâu ký tự Tệp tiêu đề: string.h #include Chú ý: char str[100] = “Hello world”; char * p = str; • p là con trỏ, trỏ tới mảng các ký tự/xâu ký tự p+6 : (Phép tính toán trên con trỏ), cũng là xâu ký tự. p+6 trỏ tới xâu “world” 01• -JanXâu-16 ký tự, có thể được khai báo char * 326
  89. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý xâu ký tự size_t strlen(char * xâu) – Trả về độ dài xâu printf("%d ",strlen("Hello world")); 11 char * strcpy(char * đích, char * nguồn) – sao chép nội dung xâu nguồn vào xâu đích, trả về giá trị xâu nguồn char Str[20]; printf("%s ",strcpy(Str,"Hello")); Hello printf("%s", Str); Hello Chú ý: Phép gán Str = “Hello” là không hợp lệ 01-Jan-16 327
  90. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý xâu ký tự int strcmp(char * xâu_1, char * xâu_2) – So sánh hai xâu. – Trả về giá trị 0 nếu hai xâu giống nhau; – Giá trị 0: xâu_1 > xâu_2 Ví dụ char Str[20]; strcpy(Str,“hello“); printf(“%d”, strcmp(Str,”hello”));→0 printf(“%d”, strcmp(Str,”hello!”); →-1 (!?) printf(“%d”, strcmp(Str,”Hello”); → 1 (!?) 01-Jan-16 328
  91. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý xâu ký tự char * strcat(char * xđích, char * nguồn) – Ghép nối xâu nguồn vào ngay sau xâu đích, trả lại xâu kết quả Ví dụ char Str[20]; strcpy(Str,"Hello "); printf("%s ",strcat(Str,"world")); Hello world printf("\n%s",Str); Hello world 01-Jan-16 329
  92. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý xâu ký tự char * strchr (char * s, int c) – Trả về con trỏ trỏ tới vị trí xuất hiện đầu tiên của ký tự c trong s. Nếu không có trả về con trỏ null strcpy(Str,"Hello world"); printf("%s ",strchr(Str,‘o')); o world char* strstr(char * s1, char * s2) – Trả về con trỏ trỏ tới vị trí xuất hiện đầu tiên của chuỗi s2 trong s1. Nếu không tồn tại, trả về con trỏ null printf("%s ",strstr(Str,”llo”)); llo world 01-Jan-16 330
  93. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Các hàm xử lý xâu ký tự (tiếp) Tệp tiêu đề: stdlib.h • int atoi(char * str): – Chuyển một xâu kí tự thành một số nguyên tương ứng – Ví dụ: atoi(“1234”) →1234 • int atol(char * str): – Chuyển xâu kí tự thành số long int • float atof(char * str): – Chuyển xâu kí tự thành số thực – Ví dụ: atof(“123.456E-2”) →1.23456 • Thất bại cả 3 hàm: trả về 0 01-Jan-16 331
  94. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ 1: Nhập 2 xâu cho biết số lần xuất hiện xâu 1 trong xâu 2 1. #include 2. #include 3. void main(){ 4. int d =0; 5. char S1[50],S2[20], *p; 6. printf("Nhap xau thu nhat: "); gets(S1); 7. printf("Nhap xau thu hai: "); gets(S2); 8. p = strstr(S1,S2); 9.while(p !=NULL ){ 10. d = d + 1; 11. p = strstr(p+1,S2);//vi tri tim kiem ke tiep 12. } 13. printf("Xau \“ %s\" x/hien trong xau \"%s \“ %d lan",S2,S1,d); 1014-J.an}-16 332
  95. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ 2: Kiểm tra xâu đối xứng #include #include main(){ char s[20]; int i,n; printf("Nhap vao xau ki tu: ");gets(s); n=strlen(s); for(i=0;i<n/2;i++) if(s[i]!=s[n-1-i]) break; if(i==n/2) printf("Xau doi xung"); else printf("Xau khong doi xung"); } 01-Jan-16 333
  96. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ 3: Đảo ngược xâu ký tự #include #include main(){ char s[100],c; int i, n; printf("Nhap xau: ");gets(s); n =strlen(s); for(i=0;i <n/2;i++){ c = s[i]; s[i] = s[n-i-1]; s[n-i-1]=c; } printf("%s",s); } 01-Jan-16 334
  97. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ 4: Đếm số lần xuất hiện chữ cái trong xâu #include #include #include main(){ char s[20]; int dem[26] = {}; int i,n; puts("Nhap vao xau ki tu:");gets(s); n=strlen(s); for(i=0;i<n;i++) if(isalpha(s[i])) dem[ tolower(s[i ]) - 'a‘ ]++; for(i=0;i<26;i++) if(dem[i]!=0) printf("Ki tu %c xuat hien %d lan\n",'a'+i,dem[i]); }01-Jan-16 335
  98. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Mảng xâu ký tự • Xâu ký tự có thể là kiểu phần tử của mảng • Khai báo char DS[100][30]; Mảng có tối đa 100 phần tử, các phần tử là xâu có độ dài tối đa 30 • Sử dụng – Như một mảng bình thường – Mỗi phần tử mảng được sử dụng như một xâu ký tự 01-Jan-16 336
  99. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ: Nhập vào DSSV cho tới khi gặp tên rỗng, in DS #include for(n = 0; n printf("Ten sinh vien[%d]: ",n+1); gets(DS[n]); void main(){ if(DS[n][0] ='\x0') break; int i, n; //n++; char DS[100][30]; } printf("Nhap DSSV ( 0) n++ }while(1); printf("\n\nDS sinh vien vua nhap \n"); for(i=0;i<n;i++) printf("%s\n",DS[i]); 337 01} -Jan-16 337
  100. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ→Kết quả thực hiện 01-Jan-16 338
  101. Nhập dãy ( 2. #include 3. void main(){ 4. int i, n = 0, d=0; 5. char DS[100][30], s[30]=""; 6. do{ 7. printf("Nhap xau thu [%d]: ",n+1); gets(DS[n]); 8. if( strcmp(DS[n]," ")) n= n + 1;//Không tính xâu “ ” 9. else break; 10. }while(1); 11. for(i = 0; i d){ 13. d = strlen(DS[i]); 14. strcpy(s,DS[i]); 15. } 16. printf("\n\nXau dai nhat la: %s, co do dai :%d\n",s,d); 1071-.Jan}-16 339
  102. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ: Nhập vào DS sinh viên, in ra DS đã sắp xếp #include #include void main(){ int i, j, N; char DS[100][30], str[30]; //Nhap DS sinh viên printf("So sinh vien : "); scanf("%d",&N); fflush(stdin); for(i=0;i < N;i++){ printf("Ten sinh vien[%d]: ",i); gets(DS[i]); } 01-Jan-16 340
  103. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ: Nhập vào DS sinh viên, in ra DS đã sắp xếp //So sánh theo Họ+đệm+tên for(i = 0; i 0){ strcpy(str,DS[i]); strcpy(DS[i],DS[j]); strcpy(DS[j],str); } //In danh sách đã sắp xếp printf("\nDS sinh vien vua nhap \n"); for(i=0;i < N;i++) printf("%s\n",DS[i]); }//main 01-Jan-16 341
  104. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ→Kết quả thực hiện 01-Jan-16 342
  105. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ : Sắp xếp theo tên //Sap xep theo tên char ten_i[30],ten_j[30]; for(i = 0; i 0){ strcpy(str,DS[i]); strcpy(DS[i],DS[j]); strcpy(DS[j],str); } } 01-Jan-16 343
  106. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Ví dụ 01-Jan-16 344
  107. Chương 5: Mảng, con trỏ và xâu ký tự 5.3 Xâu ký tự Bài tập 1. Nhập vào 2 xâu S1, S2 và một số nguyên k. Hãy chèn xâu S1 vào S2 và đưa ra màn hình (giả thiết xâu S2 được khai báo đủ lớn) 2. Một văn bản gồm không quá 60 dòng, mỗi dòng không quá 80 ký tự. Hãy viết chương trình thực hiện nhập vào một văn bản, sau đó 1. Nhập vào xâu s và chỉ ra vị trí xuất hiệncủa xâu S trong văn bản nếu có. 2. Thay tất cả các chuỗi « hanoi » (nếu có) bằng chuỗi « HANOI » 3. Đếm xem trong văn bản có bao nhiêu từ (các từ phân cách bởi dấu cách) 4. Tính tần xuất xuất hiện của các từ trong văn bản 01-Jan-16 345