1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Giáo trình ngôn ngữ lập trình c lý thuyết và thực hành

195 1K 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 195
Dung lượng 1,47 MB

Nội dung

BÙI THẾ HỒNG GI ÁO TR ÌNH Ngôn ngữ lập trình C: L Ý THUYẾT THỰC HÀNH NHÀ XUẤT BẢN KHOA HỌC KỸ THUẬT LỜI NÓI ĐẦU Phần I: Các khái niệm Bài Mở đầu Tóm tắt lịch sử phát triển ngôn ngữ C Ngôn ngữ lập trình C Dennis Ritchie tạo lập vào năm 1972 Bell Telephone Laboratories Mục đích ban đầu ngôn ngữ để thiết kế hệ điều hành UNIX C ngôn ngữ mạnh mềm dẻo nên nhiều người sử dụng Khắp nơi người ta bắt đầu dùng để viết loại chương trình Tuy nhiên, tổ chức khác bắt đầu sử dụng version khác C, phát sinh nhiều khác thao tác làm cho người lập trình phải đau đầu Để khắc phục vấn đề này, năm 1983, Viện Tiêu chuẩn Quốc gia Mỹ (ANSI) thành lập ủy ban để đưa định nghĩa chuẩn cho ngôn ngữ C, gọi ANSI Standard C Có lẽ phải nói thêm chút tên ngôn ngữ Ngôn ngữ có tên C trước có ngôn ngữ gọi B Ngôn ngữ B Ken Thompson phát triển Bell Labs Có thể, B để tên phòng thí nghiệm, C đứng sau B Tại lại dùng C? Trong giới lập trình ngày nay, có nhiều ngôn ngữ lập trình bậc cao để lựa chọn, chẳng hạn C, Pascal, BASIC, Modula, v.v Tất ngôn ngữ tuyệt vời phù hợp cho hầu hết công việc lập trình Nhưng vậy, có vài để nhiều nhà lập trình chuyên nghiệp cảm thấy C ngôn ngữ đứng đầu, vì:     C ngôn ngữ mạnh mềm dẻo Hạn chế C hạn chế tư trừu tượng người lập trìnhC sử dụng cho nhiều mục đích khác nhau, thiết kế hệ điều hành, soạn thảo văn bản, đồ hoạ, trang tính, chí làm chương trình dịch cho ngôn ngữ khác C ngôn ngữ bình dân nhiều người lập trình chuyên nghiệp ưa dùng Bằng chứng có nhiều chương trình dịch khác nhiều tiện ích kèm theo C ngôn ngữ chuyển đổi tức chương trình C viết cho hệ máy vi tính (ví dụ IBM PC) dịch chạy hệ thống khác (ví dụ DEC VAX) mà cần thay đổi chút không cần thay đổi C ngôn ngữ ngắn gọn, bao gồm số từ gọi từ khóa (keyword) làm sở để tạo câu lệnh ngôn ngữ Với đặc điểm trên, C lựa chọn tuyệt vời ngôn ngữ lập trình Nhưng có lẽ người ta nghe nói C++ kỹ thuật lập trình gọi lập trình hướng đối tượng Cũng đáng hoang mang cho thực C++ ngôn ngữ siêu C với tất mà C có cộng thêm với kỹ thuật lập trình hướng đối tượng Nếu bắt đầu việc học C++, tất dạy học C áp dụng cho C++ Trong học C, học ngôn ngữ lập trình phổ thông mạnh hôm mà tự chuẩn bị cho kỹ thuật lập trình hướng đối tượng cho ngày mai Chuẩn bị cho việc lập trình Khi giải toán cần phải tiến hành số bước định Đầu tiên phải hình thành hay gọi định nghĩa toán Nếu toán cần phải giải tìm kết qủa Một toán định rõ, lập kế hoạch để giải Sau có kế hoạch việc thực toán trở nên dễ dàng Cuối cùng, kế hoạch thực thi, kết qủa phải thử lại để kiểm chứng xem liệu toán giải trọn vẹn chưa Một logic áp dụng cho nhiều lĩnh vực khác bao gồm việc lập trình máy tính Khi tạo lập chương trình C, nên tiến hành theo bước sau đây: Xác định mục tiêu chương trình Xác định phương pháp mà ta muốn sử dụng viết chương trình Tạo lập chương trình để giải toán Chạy chương trình để xem xét kết qủa Chu trình phát triển chương trình Chu trình phát triển chương trình có bước riêng Trong bước thứ nhất, soạn thảo sử dụng để tạo tệp đĩa chứa mã gốc (source code) Tại bước thứ hai, mã gốc dịch để tạo tệp đích (object file) Tại bước thứ ba, mã dịch kết nối lại để tạo tệp chương trình chạy (executable file) Cuối cùng, bước bốn để chạy chương trình kiểm tra xem có làm việc dự kiến không Tạo lập mã gốc Các mã gốc loạt câu lệnh, lệnh sử dụng để thị cho máy tính thực công việc mà người lập trình mong muốn Ví dụ, dòng mã gốc: printf ("Chào bạn"); Lệnh thị cho máy tính hình thông điệp Chào bạn Hầu hết chương trình dịch có sạon thảo để soạn tệp mã gốc Tuy nhiên, ta sử dụng soạn thảo văn để viết chương trình C Chỉ cần lưu ý cất giữ tệp phải chọn kiểu tệp văn có phần mở rộng C Dịch mã gốc Các máy tính hiểu ngôn ngữ, ngôn ngữ máy (machine language) Bởi vậy, trước chương trình C chạy máy tính, phải dịch từ mã gốc sang mã máy chương trình gọi chương trình dịch (compiler) Chương trình dịch lấy mã gốc làm input cho tệp đĩa chứa câu lệnh mã máy tương ứng với câu lệnh mã gốc Các câu lệnh mã máy tạo chương trình dịch gọi mã đích tệp đĩa chứa chúng gọi tệp đích Tệp đích có tên trùng với tên tệp gốc có đuôi OBJ Đuôi OBJ để tệp tệp đích sử dụng chương trình kết nối (linker) Kết nối để tạo tệp chạy Cần phải thực thêm bước chương trình chạy Trong C có phận gọi thư viện hàm, chứa mã đích hàm lập sẵn Ví dụ, hàm printf sử dụng ví dụ trước hàm thư viện Các hàm thư viện thực công việc thường hay phải dùng đến, chẳng hạn thông tin lên hình, đọc số liệu từ tệp đĩa Nếu chương trình có sử dụng hàm thư viện tệp đích cần phải kết nối với mã đích hàm để tạo chương trình chạy Tệp có tên trùng với tên tệp gốc có đuôi EXE Hoàn thiện chu trình phát triển Sau dịch kết nối cần phải chạy thử chương trình Nếu kết qủa nhận không mong muốn cần phải tìm nguyên nhân dẫn đến sai sót sửa lại chương trình cho Khi có thay đổi mã gốc, chương trình phải dịch kết nối lại Chu trình phải lặp lặp lại nhận kết qủa mong muốn Một điểm lưu ý cuối việc dịch kết nối là, việc dịch kết nối trình bầy hai giai đoạn tách biệt nhiều chương trình dịch, chẳng hạn chương trình dịch chạy DOS lại gộp hai bước thành Cho dù phải hiểu hai qúa trình riêng rẽ chúng thực lệnh Chu trình phát triển chương trình C Bước 1: Sử dụng soạn thảo để viết mã gốc Thông thường tệp gốc C có đuôi C Bước 2: Dùng chương trình để dịch chương trình gốc Nếu chương trình dịch không phát sai sót chương trình gốc, sinh tệp đích Tệp có tên với tệp chương trình gốc với đuôi OBJ Nếu chương trình dịch tìm thấy lỗi đó, thông báo lên hình ta phải trở lại từ bước để sửa lỗi phát chương trình gốc Bước 3: Kết nối chương trình kết nối Nếu lỗi, kết nối sinh tệp đĩa có tên trùng với tên chương trình đích với đuôi EXE, chứa chương trình chạy Bước 4: Chạy chương trình Cần phải chạy thử chương trình sau kết thúc bước để xem hoạt động mong muốn chưa Nếu chưa phải quay lại từ bước tiến hành thay đổi cần thiết mã gốc Kết luận C công cụ lập trình mạnh, thông dụng chuyển đổi Bài giải thích bước khác qúa trình viết chương trình C Đó chu trình soạn thảo/dịch/kết nối/kiểm tra Việc mắc lỗi phát triển chương trình điều tránh khỏi Chương trình dịch C phát lỗi mã gốc thông báo lỗi kiểu lỗi vị trí lỗi Các thông tin giúp người lập trình sửa lại mã gốc cách dễ dàng Tuy nhiên, chương trình dịch lúc thông báo xác kiểu lỗi vị trí chúng Đôi người lập trình phải vận dụng kiến thức C để phát sai sót gây thông báo lỗi Câu hỏi trả lời Nếu muốn cho người chương trình C phải cho tệp nào? C ngôn ngữ có chương trình dịch Điều có nghĩa là, sau mã gốc dịch phát sinh chương trình chạy Chương trình tự chạy Nếu muốn chuyển CHAO đến người đó, điều cần làm chuyển cho họ tệp CHAO.EXE Họ không cần tệp gốc CHAO.C, tệp đích CHAO.OBJ chí chương trình dịch C Sau tạo tệp chạy được, có cần phải giữ tệp gốc tệp đích không? Nếu tệp gốc bị sau không cách khác để thay đổi chương trình dịch kết nối Do nên giữ lại tệp gốc Nhưng tệp đích lại khác Có vài cần phải giữ lại tệp đích, nhiên nói sớm Do vậy, xóa tệp đích có tệp chạy Nếu cần tệp đích, dịch lại từ tệp gốc Liệu bỏ qua thông báo nhắc nhở không? Một số thông báo nhắc nhở không làm ảnh hưởng đến việc chạy chương trình Một số khác lại có Nếu chương trình dịch cho thông báo nhắc nhở, dấu hiệu báo có không hoàn toàn Hầu hết chương trình dịch cho phép đặt mức nhắc nhở Bằng cách dó nhận nhắc nhở từ mức trở Trong chương trình, cần phải xem nhắc nhở định nên khắc phục không Tốt nên sửa lại mã gốc cho không thông báo lỗi nhắc nhở Luyện lập Mục Luyện tập cho câu hỏi để giúp người đọc củng cố lại kiến thức tập nhằm cung cấp kinh nghiệm sử dụng điều học Câu hỏi Hãy nêu ba C lựa chọn tốt ngôn ngữ lập trình Chương trình dịch làm công việc gì? Các bước chu trình phát triển chương trình gì? Cần phải gõ lệnh để dịch chương trình có tên PROG1.C chương trình dịch C ? Chương trình dịch C kết nối dịch lệnh hay hai lệnh riêng rẽ? Nên dùng đuôi cho tệp gốc C? FILENAME.TXT có hợp lệ cho tệp gốc C không? Nếu chương trình dịch không làm việc mong muốn, nên làm ? Mã máy gì? 10 Bộ kết nối làm công việc gì? Bài tập Hãy nhập dịch chương trình sau Chương trình làm việc gì? (không viết số hiệu dòng soạn chương trình) 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: include int bankinh, dientich; main()  printf( "Nhập bán kính: " ); scanf( "%d", &bankinh ); dientich = 3.14159 * bankinh * bankinh; printf( "\n\nDiện tích = %d", dientich ); return 0;  Nhập dịch chương trình sau Chương trình làm việc gì? 1: 2: 3: 4: 5: 6: 7: 8: 9: #include int x,y; main()  for ( x = 0; x < 10; x++, printf( "\n" ) ) for ( y = 0; y < 10; y++ ) printf( "X" ); return 0;  Chương trình sau có lỗi Hãy nhập dịch Các dòng sinh thông báo lỗi? 1: 2: 3: 4: 5: 6: 7: #include main();  printf( "Hãy nhìn xem!" ) printf( "Bạn tìm thấy nó!" ); return 0;  Chương trình sau có lỗi Hãy nhập dịch Các dòng sinh thông báo lỗi? 1: 2: 3: 4: 5: 6: #include main()  printf( "Đây chương trình" ) do_it( "có lỗi!" ); return 0; 7:  Thay lệnh số chương trình tập Dịch chạy lại chương trình Bây chương trình làm gì? 7: printf( "%c", ); Bài Các thành phần chương trình C Mọi chương trình C chứa số thành phần liên kết với theo cách định Để có tranh tổng thể, trước hết, ta bắt đầu xét chương trình C ngắn hoàn chỉnh với tất thành phần Một chương trình C ngắn Chương trình 2.1 mã gốc chương trình có tên NHAN.C Đây chương trình đơn giản: bao gồm việc nhập hai số từ bàn phím tính tích chúng Ở đây, chưa cần phải hiểu tất lệnh chương trình, mà chủ yếu làm quen với thành phần chương trình C mà Trước xét chi tiết chương trình này, cần phải hiểu rõ khái niệm hàm (function), hàm yếu tố việc lập trình C Một hàm phận độc lập chương trình, đặt tên thực công việc Bằng việc gọi tên hàm, chương trình thực lệnh hàm Chương trình gửi thông tin, gọi đối số (argument) cho hàm, hàm đưa trở lại thông tin cho chương trình Có hai kiểu hàm: hàm thư viện - phận chương trình dịch C; hàm người sử dụng tự định nghĩa Chương trình 2.1 NHAN.C 1: 2: 3: 4: 5: 6: 7: 8: 9: 10 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: /* Chương trình tính tích hai số */ #include int a,b,c; int tich(int x, int y); main()  /* Nhập số thứ */ printf("Nhập số nằm 100: "); scanf("%d", &a); /* Nhập số thứ hai */ printf("Nhập số khác nằm 100: "); scanf("%d", &b); /* Tính kết qủa */ c = tich(a,b); printf( "\n%d nhân %d = %d", a, b, c);  /* Hàm tính tích hai đối số */ int tich(int x, int y)  return ( x * y );  Chương trình hình dòng kết qủa sau: Nhập số nằm 100: 35 dụ, ta mở tệp để đọc đọc vào 10 bytes, 10 bytes tệp (các bytes vị trí từ đến 9) đọc vào đệm Sau phép đọc này, báo vị trí vào vị trí thứ 10, phép đọc bắt đầy từ Vì vậy, ta muốn đọc tất liệu tệp cách ghi liệu cách lên tệp, không cần phải quan tâm đến báo vị trí, hàm I/O tự động làm điều Khi cần phải điều khiển chi tiết hơn, sử dụng hàm thư viện cho phép định thay đổi giá trị báo vị trí Bằng cách điều khiển báo này, ta thực phép truy nhập ngẫu nhiên Ngẫu nhiên có nghĩa đọc liệu từ, ghi liệu lên vị trí tệp mà không cần phải đọc ghi tất liệu đứng trước Các hàm ftell() rewind() Để chuyển báo vị trí tới đầu tệp, ta sử dụng hàm rewind() Nguyên mẫu STDIO.H có dạng: void rewind(FILE *fp); Đối số fp trỏ cho kiểu FILE gắn với luồng Sau gọi rewind(), báo vị trí cho tệp đầu tệp (byte 0) Người ta sử dụng rewind()khi cần đọc lại từ đầu tệp mà không cần phải đóng mở lại Để xác định giá trị báo vị trí tệp, ta sử dụng hàm ftell() Hàm có nguyên mẫu STDIO.H có dạng: long ftell(FILE *fp); Đối số fp trỏ trỏ tới kiểu FILE cho trở lại từ hàm fopen() tệp mở Hàm ftell() cho số nguyên dài vị trí báo tệp tính bytes đầu tệp Nếu có lỗi xuất hiện, ftell() cho -1L (kiểu long -1) Chương trình 15.5 Sử dụng hàm ftell() rewind() 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: /* Trình diễn hàm ftell() rewind() */ #include #define BUFLEN char msg[] = ―abcdefghijklmnopqrstuvwxy‖; main() { FILE *fp; char buf[BUFLEN]; if( (fp = fopen(―TEXT.TXT‖,‖w‖)) == NULL) { fprintf(stderr, ―Lỗi mở tệp.‖); exit(1); } 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: if (fputs(msg, fp) == EOF); { fprintf(stderr, ―Lỗi ghi tệp.‖); exit(1); } fclose(fp); /* Bây mở tệp để đọc */ if ((fp = fopen(―TEXT.TXT‖, ―r‖)) == NULL) { fprintf(stderr, ―Lỗi mở tệp.‖); exit(1); } printf(―\nNgay sau mở, báo = %ld‖, ftell(fp)); /* Đọc vào ký tự */ fgets(buf, BUFLEN, fp); printf(―\nSau đọc vào %s, báo = %ld‖, buf, ftell(fp)); /* đọc tiếp ký tự */ fgets(buf, BUFLEN, fp); printf(―\n\nNăm ký tự %s, báo=%ld‖, 46: buf, ftell(fp)); 47: 48: /* quay trở lại */ 49: 50: rewind(fp); 51: 52: printf(―\n\nSau quay đầu, báo trở lại= %ld‖, 53: ftell(fp)); 54: 55: /* đọc vào ký tự */ 56: 57: fgets(buf, BUFLEN, fp); 58: printf(―\nvà lại đọc từ đầu tệp lần nữa: %s‖, buf); 59: fclose; 60: } Hàm fseek() Hàm dùng để chuyển báo vị trí tới nơi tệp int fseek(FILE *fp, long offset, int origin); Khoảng cách mà báo vị trí cần phải di chuyển cho offset tính theo bytes Đối số origin thị mốc khởi đầu phép chuyển Có ba giá trị cho origin với ký hiệu định nghĩa IO.H: Hằng Giá trị ý nghĩa SEEK_SET Chuyển báo vị trí offset bytes tính từ đầu tệp SEEK_CUR Chuyển báo vị trí offset bytes tính từ vị trí hành SEEK_END Chuyển báo vị trí offset bytes tính từ cuối tệp Hàm fseek() cho báo vị trí chuyển thành công, khác có lỗi xuất Chương trình 15.6 Thâm nhập ngẫu nhiên hàm fseek() 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: /* Thâm nhập ngẫu nhiên fseek() */ #include #include #define MAX 50 main() { FILE *fp; int data, count, array[MAX]; long offset; /* Khởi tạo mảng */ for (count = 0; count < MAX; count++) array[count] = count * 10; /* mở tệp nhị phân để ghi */ if ((fp = fopen(―RANDOM.DAT‖, ―wb‖)) == NULL) { fprintf( stderr, ―\nLỗi mở tệp.‖); exit(1); } /* Ghi array lên tệp, sau đóng lại */ if ((fwrite(array, sizeof(int), MAX, fp) !=MAX) { 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: fprintf(stderr, ―\nLỗi ghi liệu lên tệp.‖); exit(1); } fclose(fp); /* Mở tệp để đọc */ if (fp = fopen(―RANDOM.DAT‖, ―rb‖)) == NULL) { fprintf(stderr, ―\nLỗi mở tệp.‖); exit(1); } /* Nhắc người sử dụng nhập phần tử cần đọc Đọc */ /* lên hình, -1 nhập vào */ while(1) { printf(―\nNhập phần tử cần đọc, 0-%d, -1 để ra: ―, MAX-1); scanf(―%ld, &offset); 51: 52: 53: if(offset < 0) 54: break; 55: else if (offset > MAX-1) 56: continue; 57: 58: /* chuyển báo tới phần tử định */ 59: 60: if((fseek(fp, (offset*sizeof(int), SEEK_SET)) != NULL) 61: { 62: fprintf(stderr, ―\nLỗi dùng fseek().‖); 63: exit(1); 64: } 65: 66: /* Đọc vào số nguyên đơn */ 67: 68: fread(&data, sizeof(int), 1, fp); 69: 70: printf(―\nPhần tử thứ %ld có giá trị %d.‖, offset,data); 71: } 72: 73: fclose(fp); 74: } Phát đuôi tệp Đôi khi, ta biết cách xác độ dài tệp không cần phải biết cách phát đuôi tệp Ví dụ, ta sử dụng fwrite() để ghi mảng nguyên gồm 100 phần tử, ta biết tệp dài 200 bytes Tuy nhiên, lần khác, ta tệp dài lại cần đọc liệu từ đầu tệp tiếp tục cuối tệp Có hai cách để phát cuối tệp Khi đọc tệp mode văn theo kiểu ký tự một, ta kiểm tra xem thấy ký tự EOF chưa Hằng ký hiệu EOF định nghĩa STDIO.H với giá trị -1 (một giá trị không sử dụng cho ký tự nào) Khi hàm input ký tự đọc đến EOF mode văn bản, chắn đến cuối tệp Ví dụ, ta viết: while ( ( c = fgetc (fp) ) != EOF) Với luồng mode nhị phân, phát cuối tệp cách tìm -1, byte liệu luồng mode nhị phân nhận giá trị này, dẫn đến việc kết thúc sớm cách nhầm lẫn Thay vào đó, sử dụng hàm feof() (hàm dùng cho mode văn bản): int feof(FILE *fp); Đối số fp trỏ, trỏ tới kiểu FILE, cho hàm fopen() tệp mở Hàm feof() cho chưa phát cuối tệp, khác đến cuối tệp Nếu hàm feof() phát cuối tệp phép đọc tiếp tục trừ có hàm rewind() thực hiện, fseek() gọi, tệp đóng mở lại Các hàm quản tệp Thuật ngữ quản tệp sử dụng cho tệp tồn với công việc đọc hay ghi mà xóa, đổi tên, copy Xoá tệp int remove (const char *filename); *filename trỏ, trỏ tới tên tệp cần phải xóa Tệp thị để xoá phải không mở Nếu tệp tồn tại, bị xoá remove() cho giá trị Ngược lại, tệp chưa tồn tại, để ghi, lỗi xuất hiện, remove() cho -1 Đổi tên tệp int rename (const char *oldname, const char *newname ); oldname newname trỏ, trỏ tới tên tệp Hạn chế tên chúng phải trỏ tới ổ đĩa; đổi tên tệp sang đĩa khác Lỗi xuất điều kiện sau: Tệp oldname chưa tồn Một tệp có tên newname tồn Đổi tên sang ổ đĩa khác Copy tệp Nhu cầu copy tệp đĩa thường xuyên xẩy Trong DOS có lệnh COPY để thực việc Trong C lại hàm thư viện để làm việc người lập trình phải tự viết lấy hàm riêng Thế qủa có phức tạp, thực đơn giản biết cách sử dụng luồng C Sau cách tiếp cận mà sử dụng: Mở tệp gốc để đọc theo mode nhị phân Mở tệp đích để ghi theo mode nhị phân Đọc ký tự từ tệp gốc Chú ý tệp mở lần đầu, trỏ vị trí đặt đầu tệp, không cần phải đặt lại trỏ Dùng feof() để thử xem gặp cuối tệp chưa Nếu đúng, công việc copy coi hoàn tất đóng hai tệp lại trở lại chương trình gọi Nếu chưa đến cuối tệp, ghi ký tự lên tệp đích quay trở lại bước Sử dụng tệp tạm Một số chương trình có sử dụng tệp tạm thời trình thực Một tệp tạm tệp mở chương trình, sử dụng cho mục đích lúc chạy chương trình, sau bị xoá trước chương trình kết thúc Khi tạo lập tệp vậy, người ta không quan tâm đến tên bị xoá Điều tên chưa sử dụng Thư viện chuẩn C có hàm tên tmpnam() dùng để tạo lập tên tệp hợp lệ không trùng với tên tệp tồn char *tmpnam (char *s); Đối số s phải trỏ, trỏ tới đệm đủ lớn để giữ tên tệp Cũng truyền trỏ rỗng (NULL), trường hợp tên tạm cất giữ đệm bên tmpnam(), hàm cho trỏ, trỏ tới đệm Câu hỏi trả lời Có thể sử dụng tên ổ đĩa đường dẫn tên tệp dùng hàm erase(), rename(), fopen() hàm thao tác tệp không? Có thể sử dụng tên tệp đầy đủ với ổ đĩa, đường dẫn tên tệp Nếu có tên tệp hàm tìm tên tệp cho thư mục hành mà Lưu ý muốn viết dấu sổ ngược đường dẫn phải viết thêm dấu lần Có thể tiếp tục đọc sau gặp dấu hiệu kết thúc tệp không ? Có thể đọc sau hết tệp đọc trước bắt đầu tệp Các kết thu từ phép đọc thường không xác định nghĩa Việc đọc tệp giống làm việc với mảng Nếu sử dụng hàm fseek() nên kiểm tra xem đến cuối tệp chưa dừng lại Điều xẩy quên không đóng tệp mở ? Tốt nên đóng tất tệp mở Bình thường tệp tự động đóng lại chương trình kết thúc, nhiên không nên tin tưởng vào điều Có thể mở đồng thời tệp ? Không có số định Số lượng phụ thuộc vào tham số định nghĩa hệ điều hành Có thể đọc tệp theo kiểu hàm truy nhập ngẫu nhiên không? Khi đọc tệp cách không cần phải dùng đến hàm trỏ tệp luôn dừng lại vị trí cuối mà đọc đến Sự khác luồng mode văn luồng mode nhị phân gì? Một luồng mode văn tự động thực việc chuyển đổi ký tự dòng \n mà C dùng để đánh dấu cuối dòng cặp ký tự đầu dòng kéo dòng mà DOS dùng để đánh dấu cuối dòng Ngược lại, luồng mode nhị phân lại không thực chuyển đổi Tất ký tự input output chuyển đổi Trước thâm nhập tới tệp cần phải làm gì? Phải mở tệp trước Khi sử dụng hàm fopen() phải cung cấp thông tin hàm cho trở lại ? Khi dùng fopen() phải thị tên tệp đĩa cần mở mode để mở Hàm cho trở lại trỏ, trỏ tới kiểu FILE Con trỏ sử dụng lệnh chương trình để thâm nhập tới tệp mở Ba phương pháp tổng quát để thâm nhập tệp ? Có format, ký tự, trực tiếp 10 Hai phương pháp tổng quát để đọc thông tin tệp ? Tuần tự ngẫu nhiên 11 Giá trị EOF sử dụng ? EOF dấu hiệu kết thúc tệp Nó ký hiệu có giá trị băng -1 EOF sử dụng tệp mode văn để đánh dấu cuối tệp 12 Làm để phát cuối tệp mode văn nhị phân ? Trong mode nhị phân bắt buộc phải dùng hàm feof() Trong mode văn tìm ký tự EOF dùng hàm fseek() 13 Chỉ báo vị trí làm để thay đổi ? Chỉ báo vị trí vị trí nơi mà phép đọc phép ghi xảy Có thể thay đổi báo vị trí hàm rewind() fseek() 14 Khi tệp mở lần đầu tiên, báo vị trí đâu ? Ở ký tự tệp Bài tập Trong chương trình sau có sai không? FILE *fp int c; if (( fp = fopen (oldname, "rb")) == NULL) return -1; while (( c = fgets(fp)) !=EOF) fprintf(stdout, "%c", c); fclose(fold); Viết chương trình để in nội dung tệp lên hình Viết chương trình mở tệp in nội dung máy in với trang gồm 55 dòng Viết chương trình mở tệp văn copy tệp sang tệp với chữ thường đổi thành chữ hoa ký tự khác giữ nguyên Bài 16 Thao tác xâu ký tự Các liệu văn mà C lưu giữ thành xâu phận quan trọng chương trình Cho đến ta học cách input output xâu cách cất giữ chúng C cung cấp nhiều hàm cho thao tác khác xâu ký tự Trong học: Làm để xác định độ dài xâu Làm để copy kết nối xâu Các hàm so sánh xâu Làm để tìm xâu Làm để thử ký tự Độ dài xâu Một xâu dãy ký tự mà nơi khởi đầu đến trỏ nơi kết thúc đánh dấu ký tự null (\0) Để tính độ dài xâu (số ký tự từ chỗ bắt đầu đến chỗ kết thúc xâu) ta dùng hàm strlen() size_t strlen(char *str); Kiểu giá trị quay lại từ hàm size_t Nó định nghĩa STRING.H số nguyên không dấu sử dụng nhiều hàm xâu Ta cần nhớ size_t không dấu Đối số truyền cho strlen() trỏ, trỏ tới xâu mà ta cần biết độ dài Hàm strlen() cho số ký tự nằm str ký tự null (nhưng không tính ký tự này) Copy xâu ký tự C có ba hàm để copy xâu Trong C, gán xâu cho xâu khác mà phải copy xâu gốc từ vị trí nhớ sang vị trí khác nhớ (vị trí xâu đích) Hàm strcpy() char *strcpy( char *destination, char *source ); Hàm copy xâu (kể ký tự null kết thúc \0) trỏ source tới vị trí trỏ destination Giá trị quay lại trỏ, trỏ tới xâu mới, destination Cần phải phân bổ nhớ cho xâu đích trước sử dụng hàm Hàm strncpy() char *strncpy( char *destination, char *source, size_t n ); Các đối số destination source trỏ, trỏ tới xâu đích xâu gốc Hàm copy nhiều n ký tự xâu gốc sang xâu đích Nếu xâu gốc n ký tự ký tự null copy chèn thêm vào đuôi cho đủ n ký tự Nếu xâu gốc dài n ký tự n copy ký tự kết thúc null không thêm vào xâu đích Giá trị cho trở lại từ hàm destination Hàm strdup() Hàm tương tự hàm strcpy(), khác strdup() tự phân bổ nhớ cho xâu đích cách tự gọi hàm malloc() char *strdup( char *source ); Ghép xâu Nếu chưa quen với thuật ngữ ghép (concatenation), hiểu đơn giản ghép xâu tiếp vào đuôi xâu khác Hàm strcat() char *strcat( char *str1, char *str2 ); Hàm ghép copy xâu str2 vào đuôi xâu str1, chuyển ký tự kết thúc tới đuôi xâu Người lập trình phải tự phân bổ nhớ đủ dài cho str1 để chứa thêm str2 Giá trị quay lại hàm str1 Hàm strncat() Hàm thực việc ghép hai xâu cho phép thị ký tự xâu str2 ghép vào đuôi xâu str1 char *strncat( char *str1, char *str2, size_t n ); Nếu str2 có nhiều n ký tự, thi n ký tự ghép với str1 Nếu có hơn, toàn str2 ghép với str1 Người lập trình phải phân bổ đủ nhớ cho str1 để chứa thêm str2 So sánh xâu Các xâu sánh với để xem chúng có hay không Nếu chúng không xâu coi lớn bé xâu Việc định lơn hay bé thực thông qua mã ASCII ký tự Thư viên C chứa hàm cho ba kiểu so sánh xâu: so sánh toàn hai xâu, so sánh hai xâu không phân biệt chữ thường hay hoa, so sánh phần hai xâu So sánh hai xâu int strcmp (char *str1, char *str2); Hàm cho giá trị sau: 0 str1 nhỏ str2 str1 str2 str1 lơn str2 Hàm có phân biệt chữ hoa chữ thường So sánh hai xâu - không phân biệt chữ hoa chữ thường Vì hàm ANSI chuẩn, nên ngôn ngữ C viết khác Zortech gọi strcmpl(), Microsoft gọi _strcmp(), So sánh phần int strncmp(char *str1, char *str2, size_t n); hàm so sánh n ký tự str2 với str1 Việc so sánh tiếp tục n ký tự so xong đến đuôi str1 Cách so sánh giá trị cho trở lại hàm giống hàm strcmp() Tìm kiếm xâu Thư viện C có số hàm dùng để tìm xâu Việc tìm kiếm khẳng định xem liệu xâu có xuất xâu khác không, có vào chỗ Có sáu hàm loại Hàm strchr() char *strchr ( char *str, int ch); Hàm tìm str gặp ký tự ch, gặp ký tự kết thúc Nếu tìm thấy ch, hàm cho trỏ, trỏ tới Nếu không, cho NULL Khi hàm strchr() tìm thấy ký tự cần tìm, cho trỏ, trỏ tới ký tự Ta biết str trỏ, trỏ tới ký tự xâu, nhận vị trí ký tự tìm thấy cách lấy trỏ trừ str Hàm strrchr() char *strrchr ( char *str, int ch ); Hàm giống hệt hàm strchr() khác tìm lần xuất cuối ký tự ch xâu str Nó cho trỏ, trỏ tới ký tự thấy cho NULL không tháy ký tự ch xâu Hàm strcspn() size_t strcspn (char *str1, chr *str2 ); Hàm tìm xâu str1 xem có thấy ký tự str2 không Nó ký tự str1, thử xem có trùng voí ký tự str2 không Nếu có trùng hợp vậy, cho khoảng cách tính từ điểm đầu xâu str1 vị trí trùng Nếu trùng cho giá trị hàm strlen(str1) Tức ký tự trùng ký tự kết thúc NULL Ví dụ: /* Tìm kiếm strcspn() */ #include #include main() { char buf1[80], buf2[80]; size_t loc; /* Nhập xâu */ printf(―Nhập xâu để tìm kiếm:‖); gets(buf1); printf(―Nhập xâu chứa ký tự cần tìm:‖); gets(buf2); /* Thực tìm kiếm */ loc * strcspn(buf1, buf2 ); if (loc == strlen(buf1) ) printf(―Không tìm thấy trùng nhau.‖); else printf(―Chỗ trùng vị trí %d.‖,loc); } Kết qủa: Nhập xâu để tìm kiếm: How now brown Cow? Nhập xâu chứa ký tự cần tìm: CzD Chỗ trùng vị trí 14 Hàm strspn() size_t strspn ( char str1, char str2); Hàm gần giống hàm trước Nó lấy ký tự str1 so với ký tự str2, cho vị trí mà ký tự str1 không trùng với ký tự str2 Nói cách khác strspn() cho độ dài đoạn khởi đầu chứa toàn ký tự tìm thấy str2 Ví dụ: /* Tìm kiếm strspn() */ #include #include main() { char buf1[80], buf2[80]; size_t loc; /* Nhập xâu */ printf(―Nhập xâu để tìm kiếm:‖); gets(buf1); printf(―Nhập xâu chứa ký tự cần tìm:‖); gets(buf2); /* Thực tìm kiếm */ loc * strspn(buf1, buf2 ); if (loc == NULL ) printf(―Không tìm thấy trùng nhau.‖); else printf(―Các ký tự trùng đến vị trí thứ %d.‖,loc); } Kết qủa: Nhập xâu để tìm kiếm: How now brown Cow? Nhập xâu chứa ký tự cần tìm: How now what? Các ký tự trùng đến vị trí thứ Hàm strpbrk() Hàm tương tự hàm strcspn(), tìm xâu xuất lần ký tự có xâu khác Chúng khác chỗ có xét đến ký tự NULL hay không Hàm strpbrk() không xét ký tự NULL char *strpbrk( char *str1, char *str2); Hàm strpbrk() cho trỏ, trỏ tới ký tự str1 mà trùng với ký tự str2 Nếu trùng hợp nào, hàm cho NULL Hàm strstr() Hàm cuối có lẽ hàm hay sử dụng hàm strstr() Hàm tìm xuất xâu xâu khác char *strstr (char str1, char str2); Hàm cho trỏ, trỏ tới xuất str2 str1 Nếu không tìm thấy trùng hàm cho NULL Nếu độ dài str2 hàm cho str1 Khi strstr() tìm thấy chỗ trùng nhau, có khoảng cách tính từ đầu str1 đến chỗ trùng cách lấy trỏ cho trở lại trừ str1 Ví dụ: /* Tim kiem bang strstr() */ #include #include main() { char *loc, bù1[80], bù2[80]; clrscr(); /* Nhap cac xau */ printf(―Nhap xau duoc tim \(str1\)‖); gets(buf1); printf(―Nhap xau can tim \(str2\)‖); gets(buf2); loc = strstr(buf1, buf2); if( loc == NULL) printf(―Khong trung‖); else printf(―%s duoc tim thay o vi tri %d.‖, buf2, buf1-loc); getch(); return 0; } Các chuyển đổi xâu Có nhiều thư viện C chứa hai hàm dùng để chuyển chữ hoa thành chữ thường ngược lại Các hàm chuẩn ANSI Nguyên mẫu chúng để STRING.H char *strlwr (char *str); char *strupr (char *str); Các hàm khác xâu Hàm strrev() Hàm đảo ngược thứ tự xuất ký tự xâu Tuy nhiên ký tự null giữ nguyên đuôi xâu char *strrev( char *str ); Các hàm strset() strnset() Các hàm ANSI chuẩn Chúng chuyển tất ký tự (strset()) số ký tự (strnset()) xâu thành ký tự định char *strset (char *str, int ch); char *strnset (char *str, int ch, size_t n); Chuyển xâu thành số Đôi ta cần phải chuyển biểu diễn dạng xâu ký tự số thành biến số thực Có ba hàm thực việc Hàm atoi() Hàm chuyển xâu chữ số thành số nguyên int atoi (char *str); Ngoài chữ số, xâu str chứa khoảng trắng dẫn đầu dấu cộng + trừ - Việc chuyển đổi đầu xâu tiếp tục gặp ký tự chuyển đổi Hàm atol() Hàm làm việc y hệt hàm trước khác cho số kiểu long long atol(char *str); Hàm atof() Hàm làm việc y hệt hàm trước khác cho số kiểu double float atof(char *str); Câu hỏi trả lời Độ dài xâu làm để xác định độ dài xâu? Độ dài xâu số ký tự nằm đầu xâu ký tự null kết thúc xâu Có thể xác định độ dài xâu hàm strlen() Trước copy xâu, cần phải làm ăn ? Phải phân bổ đủ nhớ cho xâu Khi so sánh xâu, câu nói “Xâu lớn xâu kia” có nghĩa gì? Câu có nghĩa giá trị ASCII xâu lớn giá trị ASCII xâu Sự khác strcmp() strncmp() ? strcmp() so sánh toàn hai xâu, strncmp() so sánh số lượng định ký tự xâu Sự khác strcmp() strcmpi() ? strcmp() so sánh hai xâu có xét đến khác chữ hoa chữ thường strcmpi() không xét đến khác Bài tập Viết chương trình nhập họ, tên đệm tên số người Sau ghi tên người vào xâu theo cách sau đây: chữ đầu họ, đến dấu chấm dấu cách, chữ dầu tên dệm, dấu chấm dấu cách, tên Ví dụ: Trần Thanh Hằng đổi thành T T Hằng In xâu cũ hình Hàm strstr() tìm xuất xâu xâu khác có tính đến chữ hoa chữ thường Hãy viết hàm thực nhiệm vụ tương tự không kể chữ thường hay chữ hoa Viết hàm xác định số lần xuất xâu xâu khác Viết chương trình tìm kiếm tệp văn xuất xâu người sử dụng gõ vào, sau in số hiệu dòng dòng văn chứa xâu cần tìm Ví dụ, ta tìm chương trình C xuất xâu "printf()" chương trình phải liệt kê số hiệu tất dòng có lời gọi hàm printf() ... Chương trình dịch làm c ng vi c gì? C c bư c chu trình phát triển chương trình gì? C n phải gõ lệnh để dịch chương trình c tên PROG1 .C chương trình dịch C ? Chương trình dịch C kết nối dịch lệnh... tính, chí làm chương trình dịch cho ngôn ngữ kh c C ngôn ngữ bình dân nhiều người lập trình chuyên nghiệp ưa dùng Bằng chứng c nhiều chương trình dịch kh c nhiều tiện ích kèm theo C ngôn ngữ chuyển... c nhiều ngôn ngữ lập trình b c cao để lựa chọn, chẳng hạn C, Pascal, BASIC, Modula, v.v Tất ngôn ngữ tuyệt vời phù hợp cho hầu hết c ng vi c lập trình Nhưng vậy, c vài lý để nhiều nhà lập trình

Ngày đăng: 24/10/2017, 15:56

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w