Bài giảng Kỹ thuật lập trình - Bài 7: Chuỗi trong C, con trỏ hàm - Lê Gia Minh

ppt 25 trang hoanguyen 3290
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kỹ thuật lập trình - Bài 7: Chuỗi trong C, con trỏ hàm - Lê Gia Minh", để 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:

  • pptbai_giang_ky_thuat_lap_trinh_bai_7_chuoi_trong_c_con_tro_ham.ppt

Nội dung text: Bài giảng Kỹ thuật lập trình - Bài 7: Chuỗi trong C, con trỏ hàm - Lê Gia Minh

  1. Kỹ thuật lập trình Chuỗi trong C Con trỏ hàm 1
  2. Nội dung ¡ Giới thiệu về chuỗi trong C ¡ Khai báo – thao tác trên chuỗi ¡ Các hàm về chuỗi ¡ Con trỏ hàm ¡ Bài tập 2
  3. Chuỗi trong C ¡ Trong C không có kiễu chuỗi(String) ¡ Thao tác chuỗi trên mảng các ký tự ¡ Kết thúc chuỗi là ký tự null ‘\0’ l char Hoten[20]; l Khai báo như trên là khai 1 chuỗi chứa tối đa 19 ký tự (còn 1 ký tự cuối chuỗi) ¡ Chú ý : char * cũng được xem như 1 chuỗi 3
  4. Thí dụ về khai báo chuỗi 4
  5. Chuỗi trong C ¡ Sự khác biệt giữa : l char Hoten[20]; l char *st ; l Hoten đã được cấp vùng nhớ l st chỉ là con trỏ trỏ đến ký tự st = Hoten; st = &Hoten[0]; 5
  6. Nhập xuất chuỗi ¡ l Nhập : scanf(“%s” , Hoten); ¡ Gặp space,tab, new line thì dừng l Xuất : printf(“%s” , Hoten); ¡ l Nhập : gets(Hoten); ¡ Nhập được space, gap new line thì dừng l Xuất : puts(Hoten); 6
  7. Nói thêm về hàm strcpy ¡ strcpy(char *destination, char *source); thường trình này chứa một vòng lặp (tương tự như trường hợp printf) sẽ duyệt suốt chuỗi để kiểm tra ký tự null kết thúc. Trong khi chưa tìm thấy, nó tiếp tục sao chép chuỗi vào mảng đích. Nó bảo đảm ký tự null cũng được copy, vì vậy tạo nên “who” là một chuỗi hợp lệ hơn là một mảng ký tự. Chú ý là strcpy không kiểm tra biên, như vậy : strcpy(who, "a really long string” ); sẽ làm tràn mảng “who” và làm hỏng bộ nhớ sau nó. Điều này thường gây lỗi cho chương trình. ¡ strncopy(char* dest , char *source , size_t n) strncpy(who,"a really long string", sizeof(who)); 11 ký tự (số byte do sizeof cung cấp) sẽ được sao chép vào “who”, đáng tiếc là hàm strncpy bỏ qua ký tự null kết thúc, ta phải tự thêm vào: who[sizeof(who) - 1] = '\0'; 10
  8. String.h ¡ Các hàm về chuỗi được khai báo trong header file này. l size_t strlen ( const char *s ) : cho chiều dài không tính ký tự NUL . l char* strcat (char *dest ,const char *src ) Chép chuổi src vào cuối dest trả về pointer chỉ đến đầu dest . l int strcmp(const char *s1 ,const char *s2 ) So sánh s1 và s2 theo thứ tự tự điển 0 : s1 lớn hơn s2. 11
  9. String.h (tt) ¡ char* strtok(char *s1 , const char *s2 ) Xem s1 là 1 loạt chuổi con , ngăn cách nhau bởi 1 hay nhiều ký tự có trong s2 . ¡ void* memmove (void* dest ,void * source , size_t n); Chép n bytes từ vùng nhớ do source chỉ đến vào vùng nhớ do dest đang chỉ đến – Hàm này trả về con trỏ trỏ đến đầu vùng nhớ dest. 12
  10. Thí dụ về strok 1. #include 2. void main() 3. { 4. char s[80] , *p ; 5. gets(s); 6. p = strtok(s," "); 7. if (p) printf(“%s” , p); 8. while(p) 9. { 10. p = strtok(NULL," "); 11. if (p) printf(“%s” , p); 12. } 13. } 13
  11. String.h ¡ Đảo ngược chuỗi : l char* strrev(char *s) ¡ Copy một vùng nhớ : l void* memcpy(void *dest, const void* source, size_t n) l Copy n bytes từ source vào dest, việc copy sẽ không chính xác khi 2 vùng dest và source gối lên nhau 14
  12. String.h (tt) ¡ Di chuyển một vùng nhớ : l void* memmove(void *dest, const void* source, size_t n) l Di chuyển n bytes từ source vào dest, việc di chuyển vẩn chính xác khi 2 vùng dest và source gối lên nhau. 15
  13. Cắt khoảng trắng bên phải 1. void Rtrim(char* s) 2. { 3. int n =strlen(s) - 1; 4. while ( s[n] == ' ') n ; 5. s[n+1] = '\0'; 6. } 16
  14. Cắt khỏang trắng bên trái ¡ void Ltrim(char* st) ¡ { ¡ char *p = st; ¡ while (*p == ' ') p++; ¡ memmove(st,p,strlen(p)+1); ¡ } 17
  15. Các hàm chuyển đổi ¡ double atof(const char* s) l đổi s thành số double, trả về 0 nếu không đổi được. Thí dụ : printf(“%f\n”,atof(“12b.26”)); 12.000000 ¡ int atoi(const char* s) l đổi s thành số int, trả về 0 nếu không đổi được. printf(“%d\n”,atoi(“12.7”)); 12 ¡ int tolower(int ch) : l đổi ch thành chữ thường ¡ int toupper(int ch) : l đổi ký tự thành chữ hoa. 18
  16. Con trỏ hàm ¡ Tên hàm là địa chỉ của hàm ¡ Con trỏ có thể trỏ đến hàm ¡ Có thể gọi hàm thông qua con trỏ ¡ Khai báo : l KieuTraVe (*tenConTro)(tham so ) l int (*pf)(int , int); l Hàm trên có thể trỏ đến hàm trả về kiễu int và nhận 2 tham số kiễu int 19
  17. Gọi hàm thông qua con trỏ ¡ int AddNum(int a , int b); ¡ int (*pf)(int , int); ¡ Cho con trỏ trỏ tới hàm : l pf = AddNum; ¡ Chạy hàm thông qua con trỏ : l int kq = (*pf)(7,5); 20
  18. Mảng con trỏ hàm 1. void input( int[], int ); 2. void output( int[], int); 3. long sum(int[],int); 4. long squaresum(int[],int); 5. long sum2(int[],int); 6. typedef long (*func)(int [],int ); 7. long value(func , int a[], int n); 8. func arrf[] = { sum , squaresum ,sum2 }; 22
  19. 1. void main() 2. { 3. int* a; 4. int n , k = sizeof(arrf)/sizeof(func); 5. printf("Nhap so phan tu : “); 6. scanf(“%d”, &n); 7. a = (int*)malloc(n*sizeof(int)); 8. if (!a) exit(1); 9. input(a,n); 10. output(a,n); 11. printf("Gia tri lan luot ham : \n“); 12. for ( int i = 0; i< k ; i++) 13. printf(“%li ” , value(arrf[i],A,n)); 14. free(a); 15. } 23
  20. Các hàm ¡ void input(int a[],int n) ¡ { ¡ srand(time(NULL)); ¡ for (int i = 0; i<n ; i++) ¡ a[i] = rand()%20; ¡ } ¡ void output(int a[],int n) ¡ { ¡ for (int i = 0; i<n ; i++) printf(%d ” , a[i]); ¡ printf(“\n”); ¡ } 24
  21. Các hàm 1. long value(func p, int a[], int n) 2. { 3. return (*p)(a,n); 4. } 25