Ngôn ngữ lập trình c&c++ ( Phạm Hồng Thái) P10

Chia sẻ: Yukogaru | Ngày: | Loại File: PDF | Số trang:6

0
78
lượt xem
19
download

Ngôn ngữ lập trình c&c++ ( Phạm Hồng Thái) P10

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Chương 4. Hàm và chương trình Con trỏ và số học địa chỉ Hàm Đệ qui Tổ chức chương trình I. CON TRỎ VÀ SỐ HỌC ĐỊA CHỈ Trước khi bàn về hàm và chương trình, trong phần này chúng ta sẽ nói về một loại biến mới gọi là con trỏ, ý nghĩa, công dụng và sử dụng nó như thế nào. Biến con trỏ là một đặc trưng mạnh của C++, nó cho phép chúng ta thâm nhập trực tiếp vào bộ nhớ để xử lý các bài toán khó bằng chỉ vài câu lệnh đơn giản của chương trình....

Chủ đề:
Lưu

Nội dung Text: Ngôn ngữ lập trình c&c++ ( Phạm Hồng Thái) P10

  1. Chương 4. Hàm và chương trình CHƯƠNG 4 HÀM VÀ CHƯƠNG TRÌNH Con trỏ và số học địa chỉ Hàm Đệ qui Tổ chức chương trình I. CON TRỎ VÀ SỐ HỌC ĐỊA CHỈ Trước khi bàn về hàm và chương trình, trong phần này chúng ta sẽ nói về một loại biến mới gọi là con trỏ, ý nghĩa, công dụng và sử dụng nó như thế nào. Biến con trỏ là một đặc trưng mạnh của C++, nó cho phép chúng ta thâm nhập trực tiếp vào bộ nhớ để xử lý các bài toán khó bằng chỉ vài câu lệnh đơn giản của chương trình. Điều này cũng góp phần làm cho C++ trở thành ngôn ngữ gần gũi với các ngôn ngữ cấp thấp như hợp ngữ. Tuy nhiên, vì tính đơn giản, ngắn gọn nên việc sử dụng con trỏ đòi hỏi tính cẩn thận cao và giàu kinh nghiệm của người lập trình. 1. Địa chỉ, phép toán & Mọi chương trình trước khi chạy đều phải bố trí các biến do NSD khai báo vào đâu đó trong bộ nhớ. Để tạo điều kiện truy nhập dễ dàng trở lại các biến này, bộ nhớ được đánh số, mỗi byte sẽ được ứng với một số nguyên, được gọi là địa chỉ của byte đó từ 0 đến hết bộ nhớ. Từ đó, mỗi biến (với tên biến) được gắn với một số nguyên là địa chỉ của byte đầu tiên mà biến đó được phân phối. Số lượng các byte phân phối cho biến là khác nhau (nhưng đặt liền nhau từ thấp đến cao) tuỳ thuộc kiểu dữ liệu của biến (và tuỳ thuộc vào quan niệm của từng NNLT), tuy nhiên chỉ cần biết tên biến hoặc địa chỉ của biến ta có thể đọc/viết dữ liệu vào/ra các biến đó. Từ đó ngoài việc thông qua tên biến chúng ta còn có thể thông qua địa chỉ của chúng để truy nhập vào nội dung. Tóm lại biến, ô nhớ và địa chỉ có quan hệ khăng khít với nhau. C++ cung cấp một toán tử một ngôi & để lấy địa chỉ của các biến (ngoại trừ biến mảng và xâu kí tự). Nếu x là một biến thì &x là địa chỉ của x. Từ đó câu lệnh sau cho ta biết x được bố trí ở đâu trong bộ nhớ: int x ; cout
  2. Chương 4. Hàm và chương trình Đối với biến kiểu mảng, thì tên mảng chính là địa chỉ của mảng, do đó không cần dùng đến toán tử &. Ví dụ địa chỉ của mảng a chính là a (không phải &a). Mặt khác địa chỉ của mảng a cũng chính là địa chỉ của byte đầu tiên mà mảng a chiếm và nó cũng chính là địa chỉ của phần tử đầu tiên của mảng a. Do vậy địa chỉ của mảng a là địa chỉ của phần tử a[0] tức &a[0]. Tóm lại, địa chỉ của mảng a là a hoặc &a[0]. Tóm lại, cần nhớ: int x; // khai báo biến nguyên x long y; // khai báo biến nguyên dài y cout
  3. Chương 4. Hàm và chương trình − Để làm việc với địa chỉ của các biến cần phải thông qua các biến con trỏ trỏ đến biến đó. b. Khai báo biến con trỏ ; Địa chỉ của một biến là địa chỉ byte nhớ đầu tiên của biến đó. Vì vậy để lấy được nội dung của biến, con trỏ phải biết được số byte của biến, tức kiểu của biến mà con trỏ sẽ trỏ tới. Kiểu này cũng được gọi là kiểu của con trỏ. Như vậy khai báo biến con trỏ cũng giống như khai báo một biến thường ngoại trừ cần thêm dấu * trước tên biến (hoặc sau tên kiểu). Ví dụ: int *p ; // khai báo biến p là biến con trỏ trỏ đến kiểu dữ liệu nguyên. float *q, *r ; // hai con trỏ thực q và r. c. Sử dụng con trỏ, phép toán * • Để con trỏ p trỏ đến biến x ta phải dùng phép gán p = địa chỉ của x. − Nếu x không phải là mảng ta viết: p = &x. − Nếu x là mảng ta viết: p = x hoặc p = &x[0]. • Không gán p cho một hằng địa chỉ cụ thể. Ví dụ viết p = 200 là sai. • Phép toán * cho phép lấy nội dung nơi p trỏ đến, ví dụ để gán nội dung nơi p trỏ đến cho biến f ta viết f = *p. • & và * là 2 phép toán ngược nhau. Cụ thể nếu p = &x thì x = *p. Từ đó nếu p trỏ đến x thì bất kỳ nơi nào xuất hiện x đều có thể thay được bởi *p và ngược lại. Ví dụ 1 : int i, j ; // khai báo 2 biến nguyên i, j int *p, *q ; // khai báo 2 con trỏ nguyên p, q p = &i; // cho p trỏ tới i q = &j; // cho q trỏ tới j cout
  4. Chương 4. Hàm và chương trình (*q)++ ; cout
  5. Chương 4. Hàm và chương trình Ví dụ 3 : int a[100] = { 1, 2, 3, 4, 5, 6, 7 }, *p, *q; p = a; cout
  6. Chương 4. Hàm và chương trình d. Hiệu của 2 con trỏ Phép toán này chỉ thực hiện được khi p và q là 2 con trỏ cùng trỏ đến các phần tử của một dãy dữ liệu nào đó trong bộ nhớ (ví dụ cùng trỏ đến 1 mảng dữ liệu). Khi đó hiệu p - q là số thành phần giữa p và q (chú ý p - q không phải là hiệu của 2 địa chỉ mà là số thành phần giữa p và q). Ví dụ: giả sử p và q là 2 con trỏ nguyên, p có địa chỉ 200 và q có địa chỉ 208. Khi đó p - q = −4 và q - p = 4 (4 là số thành phần nguyên từ địa chỉ 200 đến 208). e. Phép toán so sánh Các phép toán so sánh cũng được áp dụng đối với con trỏ, thực chất là so sánh giữa địa chỉ của hai nơi được trỏ bởi các con trỏ này. Thông thường các phép so sánh = chỉ áp dụng cho hai con trỏ trỏ đến phần tử của cùng một mảng dữ liệu nào đó. Thực chất của phép so sánh này chính là so sánh chỉ số của 2 phần tử được trỏ bởi 2 con trỏ đó. Ví dụ 5 : float a[100], *p, *q ; p=a; // p trỏ đến mảng (tức p trỏ đến a[0]) q = &a[3] ; // q trỏ đến phần tử thứ 3 (a[3]) của mảng cout
Đồng bộ tài khoản