Tính toán con trỏ

Một phần của tài liệu các bài tập passcal cơ bản (Trang 77 - 80)

II Nhị hạng Trái tới phải ? ; Tam hạng Trái tới phả

5.5.Tính toán con trỏ

2 61 34 1 17 4 I 3 I 19 13 8 I 38 I 5 0 hàng đầu hàng hai hàng ba

5.5.Tính toán con trỏ

Trong C++ chúng ta có thế thực hiện cộng hay trừ số nguyên trên con trỏ. Điều này thường xuyên được sử dụng bởi các lập tr.nh viên được gọi là các tính toán con trỏ. Tính toán con trở th. không giống như là tính toán số nguyên bởi v. kết quả phụ thuộc vào kích thước của đối tượng được trỏ tới. Ví dụ, một kiểu int được biểu diễn bởi 4 byte. Bây giờ chúng ta có

char *str="HELLO"; int nunisQ = {10,20,30,40};

int *ptr=&nums[0]; //tó tới phần tử đầu tiên

Str-M- tăng str lên một char (nghĩa là 1 byte) sao cho nó trỏ tới kỷ tự thứ hai của chuỗi "HELLO" nhưng ngược lại ptr-H- tăng ptr lên một int (nghĩa là 4 bytes) sao cho nó trỏ tới phần tử thứ hai của nums. H.nh 5.3 minh họa sơ lược điều này. H.nh 5.3 Tính toán con trỏ. H E L L 0 \0 10 . w . o 30 40 str _£ỈL str++ ptr+

V. thế, các phần tư của chuỗi "HELLO" có thể được tham khảo tới như

*str, *(str+1), *(str+2), vâng vâng. Tương tự, các phần tử của nums có thế được tham khảo tới như *ptr, *(ptr+1), *(ptr+2), và *(ptr+3).

Một h.nh thức khác của tính toán con trỏ được cho phép trong C++ liên quan đến trừ hai con trỏ của cùng kiểu. Ví dụ:

int *ptrl = &nums[l]; int*ptr2=&nums[3]; intn=ptr2-ptrl; //nừủt.iành2

Chapter 5: Mảng, con trỏ, và tham chiếu 66

Tính toán con trỏ cần khéo léo khi xử l. các phần tử của mảng. Danh

sách 5.5 tr.nh bày ví dụ một hàm sao chép chuồi tương tự như hàm định nghĩa sẵn strcpy.

1 2 3 4

Chú giải

3 Điều kiện của v.ng lặp này gán nội dung của chuỗi src cho nội dung của chuỗi dest và sau đó tăng cả hai con trỏ. Điều kiện này trở thành 0 khi k. tự null kết thúc của chuồi src được chép tới chuồi dest

Một biến mảng (như nums) chính nó là địa chỉ của phần từ đầu tiên của mảng mà nó đại diện. V. thế các phần tử của mảng nums cũng có thể được tham khảo tới bằng cách sử dụng tính toán con trở trên nums, nghĩa là numsỊỊ] tương đương với *(nums + Ị). Khác nhau giữa nums và ptr ở chồ niuns là một hằng v. thế nó không thể được tạo ra đế trỏ tới bất cứ thứ g. nữa trong khi ptr là một biến và có thể được tạo ra đế trỏ tới các số nguyên bất kỳ.

Danh sách 5.6 tr.nh bày hàm HighestTemp (đ. được tr.nh bày trước đó trong Danh sách 5.3) có thể được cải tiến như thế nào bằng cách sử dụng tínli toán con trỏ. Danh sách 5.6 1 2 3 4 567 8 9 Chú giải

1 Thay v. truyền một mảng tới hàm, chúng ta truyền một con trỏ int và hai tham số thêm vào đặc tả kích cỡ của mảng. Theo cách này th. hàm không bị hạn chế tới một kích thước mảng cụ thế.

6 Biếu thức *(temp + i * columns +j) tương đương với temp[i][j] trong phiên bản hàm trước.

int HighestTemp (const int *temp, const int rows, coast int columns) {

int highest=0;

for (register i=0; i < rows; ++i) for (register j = 0; j < columns; -Hj) if (*(temp+i * columns + j) > highest) highest= *(temp+i * columns + j); return highest;

1________ ____________________________________ void CopyString (char *dest, char *src)

{

while (*dest++= *src++) ; }

Chapter 5: Mảng, con trỏ, và tham chiếu 67

Hàm HighestTemp có thế được đơn giản hóa hơn nữa bằng cách xem temp như là một mảng một chiều của row * column số nguyên. Điều này được tr.nh bày trong Danh sách 5.7.

Danh sách 5.7 1 23 4 567 8 5.6. Con trỏ hàm

Chúng ta có thế lấy địa chỉ một hàm và lưu vào trong một con trỏ hàm. Sau đó con trỏ có thế được sử dụng đế gọi gián tiếp hàm. Ví dụ,

int (*CompareXcoast char*, coast char*);

định nghĩa một con trỏ hàm tên là Compare có thể giữ địa chỉ của bất kỳ hàm nào nhận hai con trỏ k. tự hằng như là các đối số và trả về một số nguyên. Ví dụ hàm thư viện so sánh chuồi stranpthực hiện như thế. V. thế:

Toán tử & không cần thiết và có thế bổ qua: (adsbygoogle = window.adsbygoogle || []).push({});

Compare= strcmp; //Compare tr. tói hàm strcmp

Một lựa chọn khác là con trở có thể được định nghĩa và khởi tạo một lần:

int (*CompareXcoast char*, coast char*)= strcmp;

Khi địa chỉ hàm được gán tới con trỏ hàm th. hai kiểu phải khớp với nhau. Định nghĩa trên là họp lệ bởi v. hàm strcmp có một nguyên mầu hàm khớp với hàm.

int strcmp(const char*, coast char*);

Với định nghĩa trên của Compare th. hàm strcmp hoặc có thế được gọi trực tiếp hoặc có thể được gọi gián tiếp thông qua Compare. Ba lời gọi hàm sau là tương đương:

strcmp("Tom", 'Tim"); // gọi trực tiếp (*CompareX'TomVTim"); //gọi gian tiếp

Compare("Tom", "Tim"); // gọi gián tiep (ngắn gọn)

Cách sử dụng chung của con trỏ hàm là truyền nó như một đối số tới một hàm khác; bởi v. thông thường các hàm sau yêu cầu các phiên bản khác nhau của hàm trước trong các t.nh huống khác nhau. Một ví dụ đỗ hiểu là hàm t.m

int HighestTemp (coast int *temp, coast int rows, coast int columns)

{

int highest=0;

for (register i=0; i < rows * columas; ++i) if (*(temp+ i) > highest)

highest= *(temp+ i); return highest;

J ______________________________________________

Chapter 5: Mảng, con trỏ, và tham chiếu 68

kiếm nhị phân thông qua một mảng sắp xếp các chuỗi. Hàm này có thế sử dụng một hàm so sánh (như là strcmp) để so sánh chuỗi t.m kiếm ngược lại chuồi của màng. Điều này có thể không thích hợp đối với tất cả các trường hợp. Ví dụ, hàm strcmp là phân biệt chữ hoa hay chữ thường. Neu chúng ta thực hiện t.m kiếm theo cách không phân biệt dạng chữ sau đó một hàm so sánh khác sẽ được cần.

Như được tr.nh bày trong Danh sách 5.8 bằng cách để cho hàm so sánh một tham số của hàm t.m kiếm, chúng ta có thế làm cho hàm t.m kiếm độc lập với hàm so sánh. Danh sách 5.8 1 234 56 7 8 9 10 11 12 13 14 15 16 17 Chú giải

1 T.m kiếm nhị phân là một giải thuật nổi tiếng để t.m kiếm thông qua một danh sách các hạng mục đ. được sắp xếp. Danh sách t.m kiếm được biểu diễn bởi table - một mảng các chuồi có kích thước a Hạng mục t.m kiếm được biếu thị bởi item.

2 Compare là con trỏ hàm được sử dụng để so sánh item với các phần tử của mảng.

7 Ớ mồi v.ng lặp, việc t.m kiếm được giảm đi phân nữa. Điều này được lặp lại cho tới khi hai đầu t.m kiếm giao nhau (được biểu thị bởi bot và top) hoặc cho tới khi một so khớp được t.m thấy.

9 Hạng mục được so sánh với mục ở giữa của mảng.

nữa thấp hơn của mảng.

14 Neu item lớn hơn hạng mục giữa th. sau đó t.m kiếm được giới hạn tới nữa cao hơn của máng..

int BinSearch (char *item, char *tableQ, int ạ int (*CompareXconst char*, coast char*))

{

intbot=0; inttop=n-1; intmid,cmp; while (bot<= top) { mid=(bot+top)/2;

if ((cmp= Compare(item,table[mid])) 0)

return mid; //travechisohanggmuc

eLseif(cmp<0) (adsbygoogle = window.adsbygoogle || []).push({});

top=mid-l; //gioi hạn tim kiern toi nua thap hon else

bot=mid+l; //gioi han tim kiem toi nua cao hon

} (1 .

retum-1; //khong tim thay

Chapter 5: Mảng, con trỏ, và tham chiếu 69

16 Trả về -1 đế chỉ định rằng không có một hạng mục so khớp.

Ví dụ sau tr.nh bày hàm BinScarch có thể được gọi với strcmp được truyền như hàm so sánh như thế nào:

char*cities[] = {"Boston", "London", "Sydney", ’Tokyo"}; cout« BinSearehfSydney", cities, 4, strcmp)« Vi';

Điều này sẽ xuất ra 2 như được mong đợi.

Một phần của tài liệu các bài tập passcal cơ bản (Trang 77 - 80)