1. Trang chủ
  2. » Công Nghệ Thông Tin

Giáo trình Lập trình căn bản (Nghề: Lập trình máy tính - Trình độ CĐ/TC): Phần 2 - Trường Cao đẳng Nghề An Giang

43 8 0

Đ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 43
Dung lượng 525,06 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Mục tiêu của giáo trình Lập trình căn bản là phân tích chương trình: xác định nhiệm vụ chương trình (phải làm gì), xác định dữ liệu và cấu trúc dữ liệu của hệ thống. Phân tích và xây dựng thuật toán; Thiết kế chương trình: tìm giải pháp kỹ thuật (làm thế nào) đối với những công việc đã xác định trong giai đoạn phân tích. Mời các bạn cùng tham khảo nội dung phần 2 giáo trình dưới đây!

Trang 1

CHƯƠNG 5 HÀM Giới thiệu

Một chương trình viết trong ngôn ngữ C là một dãy các hàm Hàm chia các bài toán lớn thành các công việc nhỏ hơn, giúp thực hiện những công việc lặp lại nào đó một cách nhanh chóng mà không phải viết lại đoạn chương trình

Bài này sẽ trình bày cách viết chương trình theo cấu trúc hàm, cách truyền tham

số cho hàm trong lập trình, sử dụng đệ qui trong lập trình

Mục tiêu

- Viết chương trình theo cấu trúc hàm

- Vận dụng các cách truyền tham số cho hàm trong lập trình

- Sử dụng đệ qui trong lập trình

Nội dung chính

I KHÁI NIỆM

Một chương trình viết trong ngôn ngữ C là một dãy các hàm, trong đó có một

hàm chính (hàm main()) Hàm chia các bài toán lớn thành các công việc nhỏ hơn, giúp thực hiện những công việc lặp lại nào đó một cách nhanh chóng mà không phải viết lại đoạn chương trình Thứ tự các hàm trong chương trình là bất kỳ, song chương

trình bao giờ cũng đi thực hiện từ hàm main()

II KHAI BÁO HÀM

type tên hàm (khai báo các đối số)

Trang 2

Kiểu đối 1 tên đối 1, kiểu đối 2 tên đối 2, , kiểu đối n tên đối n

Thân hàm có thể sử dụng một câu lệnh return, có thể dùng nhiều câu lệnh return

ở các chỗ khác nhau, và cũng có thể không sử dụng câu lệnh này

Dạng tổng quát của nó là:

return [biểu thức];

Giá trị của biểu thức trong câu lệnh return sẽ được gán cho hàm

Ví dụ: Xét bài toán: Tìm giá trị lớn nhất của ba số mà giá trị mà giá trị của

chúng được đưa vào bàn phím

Xây dựng chương trình và tổ chức thành hai hàm: Hàm main() và hàm max3s Nhiệm vụ của hàm max3s là tính giá trị lớn nhất của ba số đọc vào, giả sử là a,b,c Nhiệm vụ của hàm main() là đọc ba giá trị vào từ bàn phím, rồi dùng hàm max3s để tính như trên, rồi đưa kết quả ra màn hình

Chương trình được viết như sau:

Trang 3

if (max<b) max=b;

if (max<c) max=c;

return(max);

} /* Kết thúc hàm max3s*/

Quy tắc hoạt động của hàm:

Một cách tổng quát lời gọi hàm có dạng sau:

tên hàm ([Danh sách các tham số thực])

Số các tham số thực tế thay vào trong danh sách các đối phải bằng số tham số hình thức và lần lượt chúng có kiểu tương ứng với nhau

Khi gặp một lời gọi hàm thì nó sẽ bắt đầu được thực hiện Nói cách khác, khi máy gặp lời gọi hàm ở một vị trí nào đó trong chương trình, máy sẽ tạm dời chỗ đó và chuyển đến hàm tương ứng Quá trình đó diễn ra theo trình tự sau:

Cấp phát bộ nhớ cho các biến cục bộ

Gán giá trị của các tham số thực cho các đối tương ứng

Thực hiện các câu lệnh trong thân hàm

Khi gặp câu lệnh return hoặc dấu } cuối cùng của thân hàm thì máy sẽ xoá các đối, biến cục bộ và ra khỏi hàm

Nếu trở về từ một câu lệnh return có chứa biểu thức thì giá trị của biểu thức được gán cho hàm Giá trị của hàm sẽ được sử dụng trong các biểu thức chứa nó

Các tham số thực, các đối và biến cục bộ:

Do đối và biến cục bộ đều có phạm vi hoạt động trong cùng một hàm nên đối

và biến cục bộ cần có tên khác nhau

Đối và biến cục bộ đều là các biến tự động Chúng được cấp phát bộ nhớ khi hàm được xét đến và bị xoá khi ra khỏi hàm nên ta không thể mang giá trị của đối ra khỏi hàm

Đối và biến cục bộ có thể trùng tên với các đại lượng ngoài hàm mà không gây

ra nhầm lẫn nào

Khi một hàm được gọi tới, việc đầu tiên là giá trị của các tham số thực được gán cho các đối (trong ví dụ trên hàm max3s, các tham số thực là x,y,z, các đối tương ứng là a,b,c) Như vậy các đối chính là các bản sao của các tham số thực Hàm chỉ làm việc trên các đối

Các đối có thể bị biến đổi trong thân hàm, còn các tham số thực thì không bị thay đổi

Chú ý:

Trang 4

Khi hàm khai báo không có kiểu ở trước nó thì nó được mặc định là kiểu int

Không nhất thiết phải khai báo nguyên mẫu hàm Nhưng nói chung nên có vì

nó cho phép chương trình biên dịch phát hiện lỗi khi gọi hàm hay tự động việc chuyển dạng

Nguyên mẫu của hàm thực chất là dòng đầu tiên của hàm thêm vào dấu ; Tuy nhiên trong nguyên mẫu có thể bỏ tên các đối

Hàm thường có một vài đối Ví dụ như hàm max3s có ba đối là a,b,c cả ba đối này đều có giá trị float Tuy nhiên, cũng có hàm không đối như hàm main

Hàm thường cho ta một giá trị nào đó Lẽ dĩ nhiên giá trị của hàm phụ thuộc vào giá trị các đối

III KẾT QUẢ TRẢ VỀ CỦA HÀM

- Hàm có thể nhận một hoặc nhiều giá trị đầu vào và trả về một giá trị thuộc kiểu

dữ liệu nào đó Kiểu dữ liệu được trả về của hàm được khai báo ở type

- Hàm có thề có hoặc không có giá trị trả về Nếu hàm không có nhận giá trị đầu

vào và không có giá trị trả về thì ở khai báo bằng từ khóa void

- Các biến hoặc biểu thức cung cấp giá trị đầu vào cho hàm được gọi là đối số Hàm có thể thay đổi các đối số của nó

IV CÁCH TRUYỀN THAM SỐ CHO HÀM

Cho đến nay, trong tất cả các hàm chúng ta đã biết, tất cả các tham số truyền cho

hàm đều được truyền theo giá trị Điều này có nghĩa là khi chúng ta gọi hàm với các tham số, những gì chúng ta truyền cho hàm là các giá trị chứ không phải bản thân các

biến Ví dụ, giả sử chúng ta gọi hàm addition như sau:

int x=5, y=3, z;

z = addition ( x , y );

Trong trường hợp này khi chúng ta gọi hàm addition thì các giá trị 5 and 3 được

truyền cho hàm, không phải là bản thân các biến

Điều đáng nói ở đây là khi chúng ta thay đổi giá trị của các biến a hay b bên trong hàm thì các biến x và y vẫn không thay đổi vì chúng đâu có được truyền cho

hàm chỉ có giá trị của chúng được truyền mà thôi

Trang 5

Hãy xét trường hợp cần thao tác với một biến ngoài ở bên trong một hàm Vì

vậy ta sẽ phải truyền tham số dưới dạng tham số biến như ở trong hàm duplicate

trong ví dụ dưới đây:

// passing parameters by reference

tham số biến chứ không phải tham số giá trị

Khi truyền tham số dưới dạng tham số biến chúng ta đang truyền bản thân biến

đó và bất kì sự thay đổi nào mà chúng ta thực hiện với tham số đó bên trong hàm sẽ ảnh hưởng trực tiếp đến biến đó

Trang 6

Trong ví dụ trên, chúng ta đã liên kết a, b và c với các tham số khi gọi hàm (x, y

và z) và mọi sự thay đổi với a bên trong hàm sẽ ảnh hưởng đến giá trị của x và hoàn toàn tương tự với b và y, c và z

Kiểu khai báo tham số theo dạng tham số biến sử dụng dấu và (&) chỉ có trong

C++ Trong ngôn ngữ C chúng ta phải sử dụng con trỏ để làm việc tương tự như thế Truyền tham số dưới dạng tham số biến cho phép một hàm trả về nhiều hơn một

Khi hàm gọi đệ qui đến chính nó, thì mỗi lần gọi máy sẽ tạo ra một tập các biến cục bộ mới hoàn toàn độc lập với tập các biến cục bộ đã được tạo ra trong các lần gọi trước

Để minh hoạ chi tiết những điều trên, ta xét một ví dụ về tính giai thừa của số nguyên dương n Khi không dùng phương pháp đệ qui hàm có thể được viết như sau:

long int gt(int n) /* Tính n! với n>=0*/

{

long int gtphu=1;

int i;

for (i=1;i<=n;++i) gtphu*=i;

long int gtdq(int n) {

if (n==0 || n==1) return 1;

Trang 7

else return(n*gtdq(n-1));

n*gtdq(n-1) (*)

Để tính biểu thức trên, máy cần gọi chính hàm gtdq vì thế lần gọi thứ hai sẽ thực hiện Máy sẽ tạo ra đối n mới, ta gọi đó là n thứ hai Giá trị của n-1 ở đây lại là đối của hàm , đƣợc truyền cho hàm và hiểu là n thứ hai, do vậy n thứ hai có giá trị là

2 Bây giờ, do n thứ hai vẫn chƣa thoả mãn điều kiện if nên máy lại tiếp tục tính biểu thức:

n*gtdq(n-1) (**) Biểu thức trên lại gọi hàm gtdq lần thứ ba Máy lại tạo ra đối n lần thứ ba và ở đây n thứ ba có giá trị bằng 1 Đối n=1 thứ ba lại đƣợc truyền cho hàm, lúc này điều kiện trong lệnh if đƣợc thoả mãn, máy đi thực hiện câu lệnh:

return 1=gtdq(1) (***) Bắt đầu từ đây, máy sẽ thực hiện ba lần ra khỏi hàm gtdq Lần ra khỏi hàm thứ nhất ứng với lần vào thứ ba Kết quả là đối n thứ ba đƣợc giải phóng, hàm gtdq(1) cho giá trị là 1 và máy trở về xét giá trị biểu thức

n*gtdq(1) đây là kết quả của (**)

ở đây, n là n thứ hai và có giá trị bằng 2 Theo câu lệnh return, máy sẽ thực hiện lần ra khỏi hàm lần thứ hai, đối n thứ hai sẽ đƣợc giải phóng, kết quả là biểu thức trong (**)

có giá trị là 2.1 Sau đó máy trở về biểu thức (*) lúc này là:

n*gtdq(2)=n*2*1

Trang 8

n lại hiểu là thứ nhất, nó có giá trị bằng 3, do vậy giá trị của biểu thức trong (*) là 3.2.1=6 Chính giá trị này được sử dụng trong câu lệnh printf của hàm main() nên kết quả in ra trên màn hình là:

3!=6

Chú ý:

Hàm đệ qui so với hàm có thể dùng vòng lặp thì đơn giản hơn, tuy nhiên với máy tính khi dùng hàm đệ qui sẽ dùng nhiều bộ nhớ trên ngăn xếp và có thể dẫn đến tràn ngăn xếp Vì vậy khi gặp một bài toán mà có thể có cách giải lặp (không dùng đệ qui) thì ta nên dùng cách lặp này Song vẫn tồn tại những bài toán chỉ có thể giải bằng

đệ qui

2 Các bài toán có thể dùng đệ qui

Phương pháp đệ qui thường áp dụng cho các bài toán phụ thuộc tham số có hai đặc điểm sau:

Bài toán dễ dàng giải quyết trong một số trường hợp riêng ứng với các giá trị đặc biệt của tham số Người ta thường gọi là trường hợp suy biến

Trong trường hợp tổng quát, bài toán có thể qui về một bài toán cùng dạng nhưng giá trị tham số thì bị thay đổi Sau một số hữu hạn bước biến đổi dệ qui nó sẽ dẫn tới trường hợp suy biến

Bài toán tính n giai thừa nêu trên thể hiện rõ nét đặc điểu này

Trang 9

Trong trường hợp suy biến, khi a=b thì USCLN của a và b chính là giá trị của chúng

Trang 10

putchar(n%10+'0');

}

BÀI TẬP

1 Sử dụng hàm viết lại các chương trình đã thực hiện ở các chương trước

2 Sử dụng hàm viết chương trình tính an (a: thực, n: nguyên dương) sử dụng đệ qui và không đệ qui

3 Tính phần tử thứn theo công thức truy hồi (đệ qui và không đệ qui)

Phần tử Fibonaci: F1=F2=1

Fn= Fn-1 + Fn-2 với n>2

Trang 11

CHƯƠNG 6 MẢNG Giới thiệu

Bài này sẽ trình bày cách khai báo và khởi tạo mảng, sử dụng mảng trong lập trình, sử dụng mảng làm tham số trong các bài toán

Một mảng là một tập hợp các phần tử dữ liệu có cùng kiểu Mỗi phần tử được

lưu trữ ở các vị trí kế tiếp nhau trong bộ nhớ chính Những phần tử này được gọi là

phần tử mảng

Mỗi phần tử của mảng được định danh bằng một chỉ mục hoặc chỉ số gán cho

nó Chiều của mảng được xác định bằng số chỉ số cần thiết để định danh duy nhất mỗi phần tử Một chỉ số là một số nguyên dương được bao bằng dấu ngoặc vuông [ ] đặt ngay sau tên mảng, không có khoảng trắng ở giữa Một chỉ số chứa các giá trị nguyên bắt đầu bằng 0 Vì vậy, một mảng player với 11 phần tử được biểu diễn như

sau:

player[0], player[1], player[2], , player[10]

II KHAI BÁO MẢNG

Một mảng có một vài đặc tính riêng biệt và phải được khai báo khi sử dụng chúng Những đặc tính này bao gồm:

 Lớp lưu trữ

 Kiểu dữ liệu của các phần tử mảng

 Tên mảng – xác định vị trí phần tử đầu tiên của mảng

 Kích thước mảng - một hằng số có giá trị nguyên dương

Một mảng được khai báo giống như cách khai báo một biến, ngoại trừ tên mảng được theo sau bởi một hoặc nhiều biểu thức, được đặt trong dấu ngoặc vuông [] xác định chiều dài của mảng Cú pháp tổng quát khai báo một mảng như sau:

lớp_lưu_trữ kiểu_dữ_liệu tên_mảng[biểu_thức_kích_thước]

Trang 12

Ở đây, biểu_thức_kích_thước là một biểu thức xác định số phần tử trong mảng và phải định ra một trị nguyên dương Lớp_lưu_trữ là một tùy chọn Mặc định lớp automatic được dùng cho mảng khai báo bên trong một hàm hoặc một khối lệnh,

và lớp external được dùng cho mảng khai báo bên ngoài một hàm Vì vậy mảng

player được khai báo như sau:

int player[11];

Nên nhớ rằng, trong khi khai báo mảng, kích thước của mảng sẽ là 11, tuy nhiên các chỉ số của từng phần tử bên trong mảng sẽ là từ 0 đến 10

Các qui tắc đặt tên mảng là giống với qui tắc đặt tên biến Một tên mảng và một tên

biến không được giống nhau, nó dẫn đến sự nhập nhằng Nếu một sự khai báo như

vậy xuất hiện trong chương trình, trình biên dịch sẽ hiển thị thông báo lỗi

 Một vài qui tắc với mảng:

 Tất cả các phần tử của một mảng có cùng kiểu Điều này có nghĩa là, nếu

một mảng được khai báo kiểu int, nó không thể chứa các phần tử có kiểu khác

 Mỗi phần tử của mảng có thể được sử dụng bất cứ nơi nào mà một biến được cho phép hay được yêu cầu

 Một phần tử của mảng có thể được tham chiếu đến bằng cách sử dụng một biến hoặc một biểu thức nguyên Sau đây là các tham chiếu hợp lệ:

player[i]; /*Ở đó i là một biến, tuy nhiên cần phải chú ý rằng i nằm trong miền

giới hạn của chỉ số đã được khai báo cho mảng player*/

player[3] = player[2] + 5;

player[0] += 2;

player[i / 2 + 1];

Kiểu dữ liệu của mảng có thể là int, char, float, hoặc double

III KHỞI TẠO MẢNG

Các mảng không được khởi tạo tự động, trừ khi mỗi phần tử mảng được gán một giá trị riêng lẻ Không nên dùng các mảng trước khi có sự khởi tạo thích hợp Điều này là bởi vì không gian lưu trữ của mảng không được khởi tạo tự động, do đó dễ gây

ra kết quả không lường trước Mỗi khi các phần tử của một mảng chưa khởi tạo được

sử dụng trong các biểu thức toán học, các giá trị đã tồn tại sẵn trong ô nhớ sẽ được sử dụng, các giá trị này không đảm bảo rằng có cùng kiểu như khai báo của mảng, trừ khi các phần tử của mảng được khởi tạo một cách rõ ràng Điều này đúng không chỉ cho các mảng mà còn cho các biến thông thường

Trong đoạn mã lệnh sau, các phần tử của mảng được gán giá trị bằng các dùng

vòng lặp for

Trang 13

int ary[20], i;

for(i=0; i<20; i++)

ary[i] = 0;

Khởi tạo một mảng sử dụng vòng lặp for có thể được thực hiện với một hằng giá

trị, hoặc các giá trị được sinh ra từ một cấp số cộng

Một vòng lặp for cũng có thể được sử dụng để khởi tạo một mảng các ký tự như

sau:

Ví dụ :

#include <stdio.h>

void main() {

char alpha[26];

int i, j;

for(i = 65, j = 0; i < 91; i++, j++) {

alpha[j] = i;

printf(“The character now assigned is %c\n”, alpha[j]);

} getchar();

} Một phần kết quả của chương trình trên như sau:

The character now assigned is A

The character now assigned is B

The character now assigned is C

Chương trình trên gán các mã ký tự ASCII cho các phần tử của mảng alpha Kết quả là khi in với định dạng %c, một chuỗi các ký tự được xuất ra màn hình Các

mảng cũng có thể được khởi tạo khi khai báo Điều này được thực hiện bằng việc gán

tên mảng với một danh sách các giá trị phân cách nhau bằng dấu phẩy (,) đặt trong cặp dấu ngoặc nhọn {} Các giá trị trong cặp dấu ngoặc nhọn {} được gán cho các

phần tử trong mảng theo đúng thứ tự xuất hiện

Trang 14

Ví dụ:

int deci[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

static float rates[4] = {0.0, -2.5, 13.75, 18.0};

char company[5] = {„A‟, „P‟, „P‟, „L‟, „E‟};

int marks[100] = {15, 13, 11, 9}

Các giá trị khởi tạo của mảng phải là các hằng, không thể là biến hoặc các biểu thức Một vài phần tử đầu tiên của mảng sẽ được khởi tạo nếu số lượng giá trị khởi tạo là ít hơn số phần tử mảng được khai báo Các phần tử còn lại sẽ được khởi tạo giá

trị 0 Ví dụ, trong mảng marks sau khi có sự khởi tạo như trên, bốn phần tử đầu tiên

(từ 0 đến 3) tương ứng được khởi tạo là 15, 13, 11 và 9 Các phần tử còn lại có giá trị

0 Không thể chỉ khởi tạo các phần tử từ 1 đến 4, hoặc từ 2 đến 4, hay từ 2 đến 5 khi

sự khởi tạo được thực hiện tại thời điểm khai báo Trong C không có khả năng lặp lại

sự khởi tạo giá trị

Trong trường hợp sự khởi tạo là tường minh, lớp extern hoặc static, các phần tử của mảng được đảm bảo khởi tạo là 0 (không giống lớp auto)

Không cần thiết khai báo kích thước của mảng đang được khởi tạo Nếu kích thước của mảng được bỏ qua khi khai báo, trình biên dịch sẽ xác định kích thước của mảng bằng cách đếm các giá trị đang được khởi tạo Ví dụ, sự khai báo mảng

external sau đây sẽ chỉ định kích thước của mảng ary là 5 vì có 5 giá trị khởi tạo

int ary[] = {1, 2, 3, 4, 5};

IV DÙNG MẢNG LÀM THAM SỐ

Trong C, khi một mảng được truyền vào hàm như một tham số, thì chỉ có địa chỉ của mảng được truyền vào Tên mảng không kèm theo chỉ số là địa chỉ của mảng Đoạn mã dưới đây mô tả cách truyền địa chỉ của mảng ary cho hàm fn_ary():

void main()

{ int ary[10];

fn_ary(ary);

}

Nếu tham số của hàm là mảng một chiều thì tham số có thể được khai báo theo một trong các cách sau:

fn_ary (int ary [10]) /* sized array */

Trang 15

{

: }

hoặc

fn_arry (int ary []) /*unsized array */

{

: }

Cả hai khai báo ở trên đều cho cùng kết quả Kiểu thứ nhất sử dụng cách khai báo mảng chuẩn, chỉ rõ ra kích thước của mảng Kiểu thứ hai chỉ ra rằng tham số là

một mảng kiểu int có kích thước bất kỳ

Chương trình sau đây nhận các số vào một mảng số nguyên Sau đó mảng này sẽ được truyền vào hàm sum_arr() Hàm sẽ tính toán và trả về tổng của các số nguyên trong mảng

Ví dụ 8:

#include <stdio.h>

void main()

{

int num[5], ctr, sum = 0;

int sum_arr(int num_arr[]); /* Function declaration */

Trang 16

sum = sum_arr(num); /* Invokes the function */

printf("\nThe sum of the array is %d", sum);

Chúng ta đã biết thế nào là mảng một chiều Điều này có nghĩa là các mảng chỉ

có một chỉ số Các mảng có thể có nhiều hơn một chiều Các mảng đa chiều giúp dễ

dàng trình bày các đối tượng đa chiều, chẳng hạn một đồ thị với các dòng và cột hay tọa độ màn hình của máy tính Các mảng đa chiều được khai báo giống như các mảng một chiều, ngoại trừ có thêm một cặp dấu ngoặc vuông [] trong trường hợp mảng hai chiều Một mảng ba chiều sẽ cần ba cặp dấu ngoặc vuông, Một cách tổng quát, một mảng đa chiều có thể được biểu diễn như sau:

Trang 17

storage_class data_type ary[exp1][exp2] [expN];

Ở đó, ary là một mảng có lớp là storage_class, kiểu dữ liệu là data_type, và

exp1, exp2, , expN là các biểu thức nguyên dương xác định số phần tử của mảng

được kết hợp với mỗi chiều

Dạng đơn giản nhất và thường được sử dụng nhất của các mảng đa chiều là

mảng hai chiều Một mảng hai chiều có thể xem như là một mảng của hai „mảng một

chiều‟ Một mảng hai chiều đặc trưng như bảng lịch trình của máy bay, xe lửa Để xác định thông tin, ta sẽ chỉ định dòng và cột cần thiết, và thông tin được đọc ra từ vị trí (dòng và cột) được tìm thấy Tương tự như vậy, một mảng hai chiều là một khung lưới chứa các dòng và cột trong đó mỗi phần tử được xác định duy nhất bằng toạ độ

dòng và cột của nó Một mảng hai chiều tmp có kiểu int với 2 dòng và 3 cột có thể

được khai báo như sau:

int tmp[2][3];

Mảng này sẽ chứa 2 x 3 (6) phần tử, và chúng có thể được biểu diễn như sau:

Dòng

Cột

Ở đó e1 – e6 biểu diễn cho các phần tử của mảng Cả dòng và cột được đánh số

từ 0 Phần tử e6 được xác định bằng dòng 1 và cột 2 Truy xuất đến phần tử này như sau:

int row, col;

for(row = 0; row < 2; row++)

Trang 18

for(row = 0; row < 2; row++)

- Xuất phần tử min, max

5 Viết chương trình nhập ma trận vuông n phần tử (n được nhập từ bàn phím)

- Xuất 2 đường chéo của ma trận

Trang 19

Con trỏ là biến chứa địa chỉ của một biến khác Con trỏ được sử dụng rất nhiều trong C, một phần là do chúng đôi khi là cách duy nhất để biểu diễn tính toán, và phần nữa do chúng thường làm cho chương trình ngắn gọn và có hiệu quả hơn các cách khác

Bài này sẽ trình bày cách khai báo và sử dụng được con trỏ, các phép toán trên con trỏ trong lập trình, phân biệt các kiểu con trỏ, cách sử dụng con trỏ trong lập trình

Trang 20

Mục tiêu

- Khai báo và sử dụng được con trỏ

- Vận dụng được các phép toán trên con trỏ trong lập trình

- Phân biệt được các kiểu con trỏ

Con trỏ có thể được sử dụng trong một số trường hợp sau:

 Để trả về nhiều hơn một giá trị từ một hàm

 Thuận tiện hơn trong việc truyền các mảng và chuỗi từ một hàm đến một hàm khác

 Sử dụng con trỏ để làm việc với các phần tử của mảng thay vì truy xuất trực tiếp vào các phần tử này

 Để cấp phát bộ nhớ động và truy xuất vào vùng nhớ được cấp phát này (dynamic memory allocation)

II CON TRỎ VÀ ĐỊA CHỈ

Vì con trỏ chứa địa chỉ của đối tượng nên nó có thể xâm nhập vào đối tượng gián tiếp qua con trỏ Giả sử x là một biến kiểu int, và giả sử px là con trỏ được tạo ra theo một cách nào đó

Phép toán một ngôi & sẽ cho địa chỉ của đối tượng, nên câu lệnh:

px=&x;

sẽ gán địa chỉ của biến x cho trỏ px, và px bây giờ được gọi là " trỏ tới biến x "

Phép toán một ngôi * coi là toán hạng của nó là đại chỉ cần xét và thâm nhập tới địa chỉ đó để lấy ra nội dung Nếu biến y có kiểu int thì thì lệnh:

Trang 21

y=x;

Các khai báo cho các biến con trỏ có dạng:

tên kiểu *tên con trỏ

Ví dụ: Như trong ví dụ trên, ta khai báo con trỏ px kiểu int:

int *px;

Trong khai báo trên ta đã ngụ ý nói rằng đó là một cách tượng trưng, rằng tổ hợp

*px có kiểu int, tức là nếu px xuất hiện trong ngữ cảnh *px thì nó cũng tương đương với biến có kiểu int

Con trỏ có thể xuất hiện trong các biểu thức Chẳng hạn, nếu px trỏ tới số nguyên x thì *px có thể xuất hiện trong bất kỳ ngữ cảnh nào mà x có thể xuất hiện

Ngày đăng: 01/09/2022, 10:41

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
1. Kỹ Thuật Lập Trình C – Cơ bàn và nâng cao – GS Phạm Văn Ất 2. Lập Trình C – Aptech Khác
3. Ngôn Ngữ Lập Trình C++ - Học viện Công Nghệ Bưu Chính Viễn Thông – GS.TS Trần Đình Quế, KS. Nguyễn Mạnh Hùng Khác
4. Giáo trình C++ - Đại học quốc gia Hà Nội Khác
5. Giáo trình Kỹ Thuật Lập Trình – Đại học Đà Lạt – Trần Tuấn Minh Trang web Khác
1. www.gnacademy.org/text/cc/Tutorial/tutorial.html 2. www.brpreiss.com/books/opus4/html/book.html Khác

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm