Giới thiệu Một đối tượng dữ liệu kiểu mảng có các đặc trưng sau: Số chiều : là một giá trị nguyên dương cố định nên được biểu diễn bằng một hằng số nguyên dương.. Kiểu mảngCác thao tá
Trang 1Trường Đại Học Bách Khoa Hà Nội
Viện: Điện Tử - Viễn Thông
Bộ Môn: Điện tử - Kỹ thuật máy tính
Ngôn ngữ lập trình C/C++
Chương 1: Ôn tập Ngôn ngữ lập trình C
Cấu trúc dữ liệu mảng và con trỏ
Trang 31 Kiểu mảng
1.1 Giới thiệu
Một đối tượng dữ liệu kiểu mảng có các đặc trưng sau:
Số chiều : là một giá trị nguyên dương cố định nên được biểu
diễn bằng một hằng số nguyên dương
Kích thước mỗi chiều : cũng là một giá trị nguyên dương cố
định nên cũng được biểu diễn bằng một hằng số nguyên dương
Kiểu phần tử mảng : là kiểu dữ liệu của mỗi phần tử (kiểu
mảng)
Trang 41 Kiểu mảng
Các thao tác cơ bản trên một đối tượng dữ liệu kiểu mảng gồm có:
Khai báo : xác định các đặc trưng của mảng như số
chiều, kích thước mỗi chiều, kiểu mảng
Truy nhập vào các phần tử của mảng: theo một
trong hai cách :
Truy nhập gián tiếp: bằng cách sử dụng chỉ số
Truy nhập trực tiếp: thông qua con trỏ
Trang 5Trong đó: N phải là một hằng số nguyên dương
v1,v2,…,vn là các giá trị khởi tạo tương ứng cho các phần tử của mảng
Trang 71.Kiểu mảng - Mảng một chiều
- Khai báo hằng mảng: với cú pháp như sau:
const kiểu_dữ_liệu tên_biến [N] = {v1,v2,…,vn};
kiểu_dữ_liệu const tên_biến [] = {v1,v2,…,vn};
Hằng mảng là mảng các hằng số, tức là tất cả các phần tử trong mảng đều là hằng số
Việc khởi tạo giá trị ban đầu cho các phần tử khi khai báo là bắt buộc
VD: const int a[3] = {1,2,3};
a[1] = 5 ; //error
Trang 8- Chỉ số của một phần tử : Sau khi khai báo một đối tượng dữ liệu
mảng, các phần tử trong mảng sẽ có một số hiệu duy nhất được gọi là chỉ số của phần tử đó Chỉ số này vừa có vai trò tên gọi, vừa có vai trò xác định địa chỉ tương đối của một phần tử trong mảng
- Cách đánh chỉ số: trong C/C++ quy ước phần tử thứ i (1 ≤ i ≤ N) trong mảng có chỉ số là i-1 Tức là phần tử đầu tiên có chỉ số là 0, phần tử thứ N có chỉ số là N-1
- Truy nhập bằng chỉ số: để truy nhập vào một phần tử có chỉ số i ta
dùng cú pháp tên_mảng[i]
Trang 9VD : chương trình sắp xếp một dãy N số theo trật tự tăng dần bằng giải thuật sắp xếp nổi bọt
Trang 10- Khai báo hằng mảng : tương tự như hằng mảng 1 chiều, việc
khai báo hằng mảng hai chiều sẽ phải thêm từ khoá const và
khởi tạo giá trị ban đầu cho các phần tử của mảng
Trang 11VD : khai báo mảng 2 chiều
int a[2][] ; //error
int a[2][] = {1,2,3,4,5}; //error
Trang 12- Để truy nhập vào phần tử có chỉ số (i,j) ta dùng cú pháp tên_mảng[i][j]
- Từ việc khai báo và sử dụng mảng một chiều và hai chiều,chúng ta có thể dễ
Trang 131 Kiểu mảng
1.4 Tự định nghĩa kiểu dữ liệu mới kiểu mảng
Trong C/C++ cho phép người sử dụng có thể tự định nghĩa các kiểu dữ liệu mới dựa trên các kiểu dữ liệu đã có hay định nghĩa
lại tên của các kiểu dữ liệu đã có bằng từ khoá typedef (viết tắt
của type definition)
- Cú pháp của lệnh typedef:
typedef định_nghĩa_kiểu tên_kiểu ;
- Trong đó: định_nghĩa_kiểu là phần xác định loại, cấu trúc của kiểu dữ liệu mới Nó thường là định nghĩa cấu trúc các kiểu dữ liệu mới như các cấu trúc mảng, cấu trúc bản ghi (struct)
Trang 141 Kiểu mảng
Tự định nghĩa kiểu dữ liệu mới kiểu mảng
VD: định nghĩa lại kiểu int với tên mới là integer như trong
Pascal
typedef int integer ;
integer i, j ;
- Định nghĩa một kiểu mảng 1 chiều:
typedef kiểu_dữ_liệu tên_kiểu[N] ;
VD: typedef char ten[30] ;
ten t1=”An”,t2=”Binh”,t3;
Nếu không sử dụng định nghĩa kiểu mới ta phải khai báo như sau:
Trang 151 Kiểu mảng
Tự định nghĩa kiểu dữ liệu mới kiểu mảng
- Định nghĩa một kiểu mảng hai chiều:
typedef kiểu_dữ_liệu tên_kiểu[M][N] ;
VD: typedef float matran[M][N] ;
Trang 172 Kiểu con trỏ
Vai trò: con trỏ được sử dụng trong một số ứng dụng sau:
Quản lý các đối tượng DL động và cấu trúc lưu trữ động (như CTLT
móc nối) để cài đặt lưu trữ các CTDL động như danh sách, cây,…
Định vị, truy nhập vào các thành phần của các kiểu DL có cấu trúc nhằm tăng tốc độ thực hiện và độ linh hoạt trong xử lý Ta hay dùng con trỏ để truy nhập vào mảng, bản ghi (struct).
Tổ chức các tham số đóng vai trò đầu ra của các chương trình con (hàm con) Trong C, điều này là bắt buộc, còn trong C++ ta có thể dùng con trỏ hoặc kiểu tham chiếu.
Trang 182 Kiểu con trỏ - Khai báo
Khai báo biến con trỏ
int * pi = &i, *pj=pi;
float * pf[20]; //Mảng các con trỏ kiểu float float (*pf)[20]; //Con trỏ kiểu mảng
void * p; //Con trỏ tổng quát.
Trang 192 Kiểu con trỏ - Khai báo
Khai báo hằng con trỏ
const T * cons1 = <exp>; //Con trỏ đến một hằng số
T * const cons2 = <exp> ; //Hằng con trỏ
const T * const cons3 = <exp>; //Hằng con trỏ trỏ đến hằng số
const char* pc= “abcd” ;
Trang 20Các thao tác cơ bản trên kiểu con trỏ
Phép gán
Truy nhập vào đối tượng được trỏ
Phép tăng/giảm địa chỉ
Trang 21Phép gán
Sử dụng phép gán ‘=’ để gán giá trị cho con trỏ
Cú pháp: p= <bt>;
Với p là con trỏ, bt là biểu thức vế phải, cũng phải là kiểu con trỏ
Nếu kiểu con trỏ của p và của bt không giống nhau, ta thường phải sử dụng phép ép chuyển kiểu Toán tử ‘&’ hay được dùng để lấy địa chỉ đối tượng trong bt để gán cho con trỏ.
p = pa; //Không cần ép chuyển kiểu
p = pc; //Không cần ép chuyển kiểu
Trang 22Truy nhập vào đối tượng được trỏ
Khi một con trỏ p đang trỏ vào một đối tượng A, ta có thể truy nhập vào A thông qua một trong các toán tử truy nhập Trong
C có nhiều toán tử truy nhập khác nhau, thường phụ thuộc vào kiểu DL của đối tượng A
Toán tử *: áp dụng khi A là đối tượng DL thuộc một trong các
kiểu DL cơ bản (kí tự, số nguyên, số thực) Cú pháp: “*p”
Toán tử []: áp dụng khi A là dữ liệu kiểu mảng Cú pháp:
p[N], với N là một biểu thức nhận giá trị nguyên
Toán tử : áp dụng khi A là DL kiểu struct Cú pháp: pfn, với fn là tên trường trong cấu trúc struct mà ta muốn truy nhập
Trang 23Truy nhập vào đối tượng được trỏ
Trang 253 Mối quan hệ giữa mảng và con trỏ
Bản thân mảng là một con trỏ, trỏ đến dãy phần tử của mảng Nó là hằng con trỏ ( như không thể gán cho tên mảng, cũng như không thực hiện được các phép
tăng/giảm địa chỉ )
Biến con trỏ có thể được dùng để truy nhập vào các phần
tử của mảng giống như mảng
Trang 263 Mối quan hệ giữa mảng và con trỏ
Trang 274 Cấp phát động bộ nhớ
Thư viện <malloc.h> cung cấp một số hàm để quản lý vùng nhớ động:
void * malloc(int size);
Hàm cấp phát vùng nhớ động kích thước size, rồi trả về địa chỉ của ngăn nhớ đầu tiên của vùng nhớ đó Hàm trả về NULL nếu cấp phát không thành công
Cấp phát vùng nhớ kích thước nItems * size_item
Cấp phát lại một vùng nhớ mới kích thước new_size cho vùng nhớ cũ trong block,
có copy dữ liệu từ vùng nhớ cũ sang vùng nhớ mới.
void free (void * p);
Hàm giải phóng vùng nhớ động đã được cấp phát tại địa chỉ p
Trang 28} for (i=0;i<N;i++) { printf("%d ",p[i]);
} //Giai phong vung nho dong da cap
free(p);
} //end main
Trang 29Tóm tắt nội dung chính
Kiểu mảng
Số chiều: 1 hay nhiều chiều
Các thao tác cơ bản: khai báo, định nghĩa, truy nhập
Bản chất: là một hằng con trỏ trỏ vào một dãy các phần tử
Trang 30Cảm ơn!
Trang 31Bài tập
100) số nguyên khác 0 từ bàn phím (nhập số 0 để báo kết thúc việc nhập) Sau đó in ra số lượng các số âm và số dương đã nhập được.
các số thực từ bàn phím, rồi tính tổng các phần tử theo từng cột rồi in ra.
100) nguyên, sau đó sắp xếp các số theo trật tự tăng dần, rồi in dãy trước và sau khi sắp xếp ra màn hình.
rồi tính tích của 2 ma trận đó Sau đó in toàn bộ các ma trận đó ra