intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Ngôn ngữ lập trình C - Chương 3

Chia sẻ: Nguyen Nhi | Ngày: | Loại File: PDF | Số trang:0

117
lượt xem
21
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tài liệu tham khảo bài giảng về Ngôn ngữ lập trình C++ gồm 7 chương - Chương 3 Các kiểu dữ liệu phức hợp

Chủ đề:
Lưu

Nội dung Text: Ngôn ngữ lập trình C - Chương 3

  1. Ch−¬ng 3 Ch C¸c kiÓu d÷ liÖu phøc hîp
  2. 3.1 C++ vµ c¸c kiÓu d÷ liÖu phøc hîp 3.1.1 Kiểu dữ liệu trong ngôn ngữ lập trình – Kiểu cơ sở (vô hướng) • Gồm các kiểu dữ liệu kí tự, số (nguyên, thực), có thể cả kiểu lôgic. – Là các kiểu cơ bản trong hầu hết các ngôn ngữ lập trình. • Sử dụng khi cần biễu diễn các dữ liệu nguyên tố, đơn giản – Khả năng biễu diến dữ liệu bị hạn chế. – Kiểu phức hợp (bậc cao, dẫn xuất) • Kiểu dữ liệu phức hợp: được tạo thành từ các kiểu cơ sở – Còn gọi là kiểu bậc cao hay kiểu dẫn xuất. – Thực tế lập trình đòi hỏi các kiểu dữ liệu phức tạp • Kiểu dữ liệu phức hợp tính cấu trúc của dữ liệu tăng khả năng biểu diễn dữ liệu. – Sử dụng trong các chương trình đòi hỏi khả năng biễu diễn dữ liệu phức tạp hơn. 2 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  3. 3.1 C++ vµ c¸c kiÓu d÷ liÖu phøc hîp 3.1.2 Kiểu dữ liệu phức hợp trong C++ – Các kiểu dữ liệu phức hợp trong C++ • Kiểu liệt kê (enum) • Kiểu mảng: mảng một chiều, mảng nhiều chiều. • Kiểu cấu trúc (struct): cấu trúc, kiểu hợp (union), kiểu trường bit. – Kết hợp các kiểu dữ liệu trong C++ • Có thể tổ hợp các kiểu cơ sở, phức hợp với nhau. – Ví dụ: khai báo một mảng các cấu trúc, hay khai báo một cấu trúc có thành phần là mảng, … – Đặt tên kiểu dữ liệu bằng typedef trong C++ • Cú pháp: typedef tên_kiểu_đã_có tên_mới; • Từ khóa typedef thường sử dụng để đặt tên một kiểu dữ liệu phức hợp có thể dùng tên đó để khai báo biến sau này. – Trong C, typedef thường dùng để đặt tên cho kiểu cấu trúc. 3 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  4. 3.1 C++ vµ c¸c kiÓu d÷ liÖu phøc hîp 3.1.3 Kiểu liệt kê – Khái niệm: tập hợp các giá trị được liệt kê tường minh – Cú pháp: enum kiểu_liệt_kê {các_phần_tử} các_biến; • VD: enum Thu {T2, T3, T4, T5, T6, T7, CN} t1, t2; • Có thể có các khai báo biến thể (lược bỏ một số thành phần), ví dụ không có tên kiểu, tên biến hay cả tên kiểu lẫn tên biến. • Khai báo biến: Thu t3, t4; – Chú ý: trong C biến enum thực chất là biến nguyên, tên sau từ khóa enum chưa được coi là tên kiểu phải khai báo biến theo cú pháp: enum kiểu_liệt_kê biến_liệt_kê; – Chuyển kiểu giữa enum và int • Có thể chuyển kiểu tự động từ enum sang int • Để chuyển từ kiểu int sang enum phải dùng toán tử ép kiểu – VD: int m=2; t1=(Thu)m; – Trong C có thể gán trực tiếp biến int cho biến enum. 4 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  5. 3.2 M¶ng 3.2.1 Khai báo và định nghĩa mảng – Kiểu mảng • Là kiểu dữ liệu bao gồm dãy liên tiếp các phần tử cùng kiểu. • Số chiều của mảng là không giới hạn. • Kích thước mảng được tính bằng tổng số phần tử của mảng. • Mảng cho phép thao tác với một dãy các phần tử dữ liệu một cách thuận tiện hơn, hiệu quả hơn. – Khai báo mảng • Mảng một chiều: kiểu_dữ_liệu tên_mảng[kích_thước]; • Mảng nhiều chiều: kiểu_dữ_liệu tên_mảng[kích_thước][kích_thước][…]…; • VD: int A[10]; long B[20][10]; float C[10][20][30]; 5 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  6. 3.2 M¶ng 3.2.2 Thao tác với biến mảng – Truy nhập vào phần tử mảng • Mảng một chiều: tên_mảng[chỉ_số] – Chỉ số có thể là số thực C++ tự động chuyển sang kiểu nguyên. • Mảng nhiều chiều: tên_mảng[chỉ_số][chỉ_số][…]… – Điều này thể hiện định nghĩa mảng trong C++ ( ≠ Pascal). • Chú ý 1: C/C++ không kiểm tra việc tràn chỉ số – Việc sử dụng chỉ số vượt khỏi phạm vi cho phép có thể gây lỗi, chẳng hạn có thể làm thay đổi các biến khác trong chương trình. • Chú ý 2: Tên mảng là địa chỉ phần tử đầu của mảng – Tên mảng là hằng con trỏ, chứa địa chỉ phần tử đầu tiên của mảng. – Địa chỉ các thành phần của mảng n chiều được tính cho các phần tử con n-1 chiều (không tính theo kiểu dữ liệu). 6 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  7. 3.2 M¶ng 3.2.2 Thao tác với biến mảng – Nhập dữ liệu cho biến mảng • Nhập trực tiếp – Sử dụng hàm scanf (hoặc cú pháp cin>>) cho từng phần tử mảng. – Chú ý: trong TC 2.0 chỉ cho phép dùng toán tử địa chỉ với mảng số nguyên (mảng kiểu int). • Sử dụng biến trung gian – Cách này không ngắn gọn bằng cách nhập trực tiếp nhưng có thể tiện lợi hơn khi ta cần xử lý trên giá trị nhập vào trước khi gán cho một phần tử mảng. • Trong thực tế ta thường dùng vòng lặp for để nhập dữ liệu. – Chỉ số mảng là tương ứng với biến điều khiển. – Mảng có bao nhiêu chiều dùng bấy nhiêu vòng for. 7 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  8. 3.2 M¶ng 3.2.2 Thao tác với biến mảng – Khởi đầu giá trị khi khai báo mảng • Nếu không khởi đầu, mảng sẽ được gán giá trị 0. • Cú pháp: kiểu_dữ_liệu tên_mảng[k.thước] = {g.trị_1,g.trị_2,...} kiểu_dữ_liệu tên_mảng[k.thước][…] = {{g.trị_1.1, g.trị_1.2,...}, {g.trị_2.1, g.trị_2.2,...},...} – Nếu không mô tả đủ giá trị các giá trị còn lại được lấy ngẫu nhiên (thường là 0). – Nếu không mô tả kích thước mảng trình dịch tự xác định dựa vào số giá trị được khởi đầu. • Không được khai báo khởi đầu giá trị cho mảng khai báo trong thân hàm (kể cả hàm main). 8 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  9. 3.2 M¶ng 3.2.3 Xâu kí tự – Khái niệm xâu kí tự • Xâu kí tự là mảng một chiều các kí tự (kiểu char). – Trong xâu kí tự có kí tự kết thúc xâu ‘\0’ hay NULL (≠ kí tự kiểu char) kích thước mảng lớn hơn số ký tự trong xâu là 1. • Không tồn tại các phép toán so sánh, gán… trên xâu – Để thực hiện các phép toán này, phải viết các đoạn mã lệnh xử lý trên mảng hoặc dùng thư viện. – Mảng các xâu: • Là mảng 2 chiều đặc biệt. • Có thể được khai báo như là mảng các con trỏ. • Thao tác trên mảng các xâu: tương tự như thao tác trên mảng thông thường. 9 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  10. 3.2 M¶ng 3.2.3 Xâu kí tự – Vào/ra với xâu kí tự • Dùng hàm printf, scanf với định dạng %s cho biến xâu – Nên dùng chỉ thị fflush(stdin) (hoặc cin.clear() nếu dùng các phép toán >> và
  11. 3.3 Con trá vµ m¶ng 3.3.1 Con trỏ mảng – Con trỏ và mảng một chiều • Tên mảng là địa chỉ đầu của mảng (là một hằng con trỏ). – Có thể gán tên mảng cho một biến trỏ thao tác trên biến trỏ ~ thao tác trên tên mảng (~ thao tác trên địa chỉ các phần tử mảng). – VD: int A[10]; int *p; p = A; p[5] = 100; *(p+5) = 100; • Chú ý: tên mảng không phải là biến trỏ không thể thực hiện phép toán số học con trỏ (cộng, trừ, …) trên tên mảng. – Nếu thực hiện các thao tác thay đổi giá trị đối với tên mảng, trình dịch sẽ báo lỗi. 11 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  12. 3.3 Con trá vµ m¶ng 3.3.1 Con trỏ mảng – Con trỏ và mảng nhiều chiều • Có thể khai báo con trỏ cho trỏ đến mảng nhiều chiều – Chú ý trong cách xác định địa chỉ phần tử mảng: phần tử mảng ở đây là mảng con (với số chiều ít hơn 1) chứ không phải là kiểu cơ sở. – Có thể dùng con trỏ để duyệt các phần tử của mảng nhiều chiều nhưng phải chuyển kiểu cho phù hợp – Nếu không chuyển kiểu, C++ sẽ báo lỗi. – VD: int *p; int A[20][10]; báo lỗi! p = (int*)A; //p = A //Chú ý: Trong C chỉ cảnh báo và chương trình vẫn làm việc • Con trỏ nhiều cấp và mảng nhiều chiều – Có thể sử dụng cấp phát động để tạo ra mảng nhiều chiều. – Cấp con trỏ ~ số chiều của mảng. 12 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  13. 3.3 Con trá vµ m¶ng 3.3.2 Mảng con trỏ và cấp phát bộ nhớ động – Mảng các con trỏ • Kiểu phần tử của mảng là biến trỏ mảng các con trỏ tạo ra mảng với các phần tử có vị trí (trong bộ nhớ) bất kì. – VD: int *p[3]; int k, m, n, ; p[0] = &k; p[1] = &m; p[2] = &n; • Việc thao tác trên các biến trỏ sẽ không tác động đến các phần tử mà chúng trỏ đến có nhiều ưu điểm (thời gian, bộ nhớ…). – Ví dụ: để sắp xếp mảng chỉ cần đổi chỗ các con trỏ. • Nếu các biến trỏ trỏ đến mảng mảng của các mảng – Khác với mảng hai chiều, các mảng con có thể có vị trí bất kì có thể thao tác trên các mảng con mà không tác động đến các mảng đó. – VD: int *p[3]; int A[10], B[20], C[30]; p[0] = A; p[1] = B; p[2] = C; 13 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  14. 3.3 Con trá vµ m¶ng 3.3.2 Mảng con trỏ và cấp phát bộ nhớ động – Cấp phát động cho mảng • Để cấp phát động cho mảng ta sử dụng các hàm malloc, calloc, realloc, farmalloc, farcalloc, farrealloc… • Để giải phóng bộ nhớ sử dụng hàm free. • Mảng một chiều: sử dụng con trỏ – Lưu ý chuyển kiểu con trỏ trả về thành kiểu con trỏ phù hợp. • VD: – Cấp phát bộ nhớ: int *i_ptr; // cấp phát mảng 10 phần tử i_ptr = (int *) calloc (10, sizeof(int)); – Giải phóng bộ nhớ cho con trỏ sau khi dùng xong: free(i_ptr); 14 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  15. 3.3 Con trá vµ m¶ng 3.3.2 Mảng con trỏ và cấp phát bộ nhớ động – Cấp phát động cho mảng (tiếp) • Mảng nhiều chiều: sử dụng con trỏ nhiều cấp – Lưu ý chuyển kiểu con trỏ trả về thành kiểu con trỏ phù hợp. • VD: – Cấp phát mảng con trỏ sau đó cấp phát cho các con trỏ thành phần: int **i_ptr; i_ptr = (int **) calloc(10, sizeof(int *)); for (int i=0; i
  16. 3.3 Con trá vµ m¶ng 3.3.3 Thao tác với vectơ và ma trận – Các phép toán cơ bản với vectơ và ma trận: • Cộng, trừ, nhân ma trận • Nghịch đảo, chuyển vị • Tính định thức • … – Cấu trúc chung khai báo vectơ và ma trận • Vectơ: mảng 1 chiều, ma trận: mảng 2 chiều. • Có thể sử dụng cấp phát động. – Cài đặt các thao tác trên vectơ và ma trận • Xử lý trên mảng 1 chiều và 2 chiều. 16 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  17. 3.3 Con trá vµ m¶ng 3.3.3 Thao tác với vectơ và ma trận Bài tập lớn! – Đọc tài liệu – Lập trình cài đặt • Vào/ra dữ liệu (nên kết hợp với vào/ra tập tin (xem chương 5)). • Các thao tác xử lý trên véctơ và ma trận (cộng, trừ, nhân, …). • Các bài toán trên vectơ và ma trận (tính định thức, nghịch đảo, chuyển vị, …). • Các bài toán khác. • Tổ chức thành các hàm (xem chương 4). – Có thể xây dựng thành một thư viện. 17 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  18. 3.4 CÊu tróc 3.4.1 Khai báo và định nghĩa cấu trúc – Kiểu cấu trúc • Một kiểu dữ liệu bao gồm tập hợp các kiểu dữ liệu khác nhau kết hợp với nhau dưới một tên chung. • Cấu trúc cho phép xử lý một phần tử có nhiều thuộc tính khác nhau một cách thống nhất. Các thành phần dữ liệu được truy nhập thông qua tên. • Khái niệm cấu trúc trong C++ ~ bản ghi trong Pascal hay FoxPro. – Khai báo cấu trúc • Khai báo kiểu dữ liệu cấu trúc: struct tên_kiểu_cấu_trúc { khai báo các thành phần; }; 18 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  19. 3.4 CÊu tróc 3.4.1 Khai báo và định nghĩa cấu trúc – Khai báo cấu trúc (tiếp) • Các thành phần trong cấu trúc có thể là bất kì kiểu dữ liệu nào đã được định nghĩa, kể cả một cấu trúc khác. • Khai báo biến cấu trúc: tên_kiểu_cấu_trúc tên_biến; • Khai báo đồng thời cấu trúc và biến: struct tên_kiểu_cấu_trúc { khai báo các thành phần; } tên_các_biến; – Với cách này, khi khai báo có thể không cần tên kiểu cấu trúc. Tuy vậy nếu không có tên, dĩ nhiên không khai báo được thêm biến mới ngoài các biến khai báo khi định nghĩa kiểu. 19 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
  20. 3.4 CÊu tróc 3.4.1 Khai báo và định nghĩa cấu trúc – Một số chú ý với kiểu cấu trúc trong C: • Khác với C++, trong C tên sau từ khóa struct chưa phải là tên kiểu chưa thể dùng để khai báo phải khai báo theo cú pháp: struct tên_kiểu_cấu_trúc tên_biến; • Để khắc phục điều này, trong C có thể dùng từ khóa typedef để định nghĩa kiểu cho cấu trúc được khai báo: typedef struct tên_đã_khai_báo tên_kiểu; khi đó có thể dùng tên_kiểu để khai báo biến. • Cũng có thể dùng typedef ngay khi khai báo kiểu dữ liệu: typedef struct tên_cấu_trúc { //tên có thể không cần các thành phần } các_kiểu_cấu_trúc; 20 Bài giảng C++. 14/10/2008 V.S.Nam. B/m KTHT, khoa CNTT, ĐHXD
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2