Slide bài giảng Lập trình C++ - Lương Trần Hy Hiến - Con trỏ

Nội dung

Tổchức của chương trình

Địa chỉ

Biến con trỏ

Các thao tác trên biến con trỏ

Biến tĩnh và biến động

Cấp phát và hủy biến động

pdf7 trang | Chuyên mục: C/C++ | Chia sẻ: dkS00TYs | Lượt xem: 1857 | Lượt tải: 1download
Tóm tắt nội dung Slide bài giảng Lập trình C++ - Lương Trần Hy Hiến - Con trỏ, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
HIENLTH, C++ - 2010
Nội dung
 Tổ chức của chương trình
 Địa chỉ
 Biến con trỏ
HIENLTH, C++ - 2010
 Các thao tác trên biến con trỏ
 Biến tĩnh và biến động
 Cấp phát và hủy biến động
2
Tổ chức của chương trình
 Một chương trình được chia ra thành nhiều phân 
đoạn (segment).
 Mỗi segment có thể xem như là một mảng một 
chiều.
HIENLTH, C++ - 2010
 Mỗi segment lưu một loại dữ liệu nhất định.
 Data Segment: lưu các biến toàn cục
 Stack Segment: lưu các biến cục bộ của các hàm và 
các thông tin khác
 Heap Segment: lưu các biến động
 Code Segment: lưu các chỉ thị đoạn mã của chương 
trình
3
Địa chỉ
 Một ô nhớ bất kỳ (một biến bất kỳ) trong chương 
trình có một địa chỉ duy nhất.
 Mỗi địa chỉ gồm có hai thành phần:
Tên segment l u biến
HIENLTH, C++ - 2010
 ư
 Vị trí của biến trong segment
 Địa chỉ thường được ký hiệu là segment:offset
 Segment có thể là Data, Heap, Code, Stack
 Offset là vị trí của biến trong segment tương ứng
4
Ví dụ
int a;
void main()
{
16
12
16
12
HIENLTH, C++ - 2010 5
int b;
double c;
…
}
8
4
0 a
Stack Data
8 c
4
0 b
Con trỏ – Một số lý do nên sử dụng
 Con trỏ là kiểu dữ liệu lưu trữ địa chỉ của các vùng 
dữ liệu trong bộ nhớ máy tính
 Kiểu con trỏ cho phép:
Truyền tham số kiểu địa chỉ
HIENLTH, C++ - 2010

 Biểu diễn các kiểu, cấu trúc dữ liệu động
 Lưu trữ dữ liệu trong vùng nhớ heap
Biến con trỏ
 Là biến dùng để lưu giá trị địa chỉ
 Cú pháp khai báo một biến con trỏ
Kiểu* tên-biến;
 Ý nghĩa: khai báo một biến con trỏ dùng để lưu địa chỉ của 
HIENLTH, C++ - 2010
các biến thuộc kiểu đã chỉ ra.
 Biến con trỏ có kích thước 4 bytes (hệ điều hành 32 bit)
 Ví dụ:
 int* pint; // khai báo một biến con trỏ dùng để lưu địa chỉ 
của các biến thuộc kiểu int.
 double* pd; // khai báo một biến con trỏ dùng để lưu địa chỉ 
của các biến thuộc kiểu double.
7
Con trỏ – Khai báo trong C++
int *pi;
long int *p;
fl t* f
HIENLTH, C++ - 2010 8
oa p ;
char c, d, *pc; /* c và d kiểu char
pc là con trỏ đến char */
double* pd, e, f; /* pd là con trỏ đến double
e and f are double */
char *start, *end;
Các thao tác trên con trỏ
 Phép lấy địa chỉ:
 Kí hiệu: &
 Cú pháp: &tên-biến
 Ý nghĩa: lấy địa chỉ của biến đi kèm. Biến được lấy địa 
HIENLTH, C++ - 2010
chỉ phải thuộc kiểu mà con trỏ có thể lưu địa chỉ.
 Ví dụ: 
int a = 5;
int* pa = &a; // pa sẽ lưu địa chỉ của biến a
int **pb = &pa;//pb lưu địa chỉ của con trỏ pa
9
Con trỏ - Toán tử “&”
 Địa chỉ của tất cả các biến trong chương trình đều 
đã được chỉ định từ khi khai báo.
char g = 'z';
p c
HIENLTH, C++ - 2010 10
0x91A2
0x1132
void main()
{
char c = 'a';
char *p;
p = &c;
p = &g;
}
'a'
0x1132
p g
'z'
0x91A2
Con trỏ - Toán tử *
 Phép khử địa chỉ
 Kí hiệu: *
 Cú pháp: *tên-biến-con-trỏ
Ý ngh a: truy xuất ến vùng nh có a chỉ ang c 
HIENLTH, C++ - 2010
 ĩ đ ớ đị đ đượ
lưu bởi biến con trỏ đi kèm
 Ví dụ:
int a = 5;
int* pa = &a;
*pa = 6;
cout << *pa;
11
Con trỏ - Toán tử *
#include 
using namespace std;
char g = 'z';
void main()
a
z
0x1132
p c
'a'
0x1132
HIENLTH, C++ - 2010 12
{
char c = 'a';
char *p;
p = &c;
cout<<*p<<"\n";
p = &g;
cout<<*p<<"\n";
}
xuất giá trị do p đang 
quản lý
0x91A2
p g
'z'
0x91A2
Con trỏ - Truyền tham số địa chỉ 
#include 
using namespace std;
void change(int *v);
void main()
HIENLTH, C++ - 2010 13
{
int var = 5;
change(&var);
cout<<"main: var = “<<var<<endl;
}
void change(int *v)
{
(*v) *= 100;
cout<<“change: *v = “<< (*v)<<endl;
}
Con trỏ - Truyền tham số địa chỉ
void Swap(int *a, int *b)
{
int t = *a; *a = *b; *b = t;
}
HIENLTH, C++ - 2010
void main()
{
int m = 5, n = 7;
cout<<“m = “<<m<<“, n = “<<n<<endl;
Swap(&m, &n);
cout<<“m = “<<m<<“, n = “<<n<<endl;
}
14
Con trỏ NULL
 Giá trị đặc biệt để chỉ rằng con trỏ không quản lý 
vùng nào. Giá trị này thường được dùng để chỉ một 
con trỏ không hợp lệ.
#i l d i t
HIENLTH, C++ - 2010 15
nc u e 
using namespace std;
void main()
{
int i = 13;
short *p = NULL;
if (p == NULL)
cout<<“Con trỏ không hợp lệ!\n";
else
cout<<“Giá trị : “<<*p<<“\n";
}
Con trỏ - Toán tử gán “=” 
 Có sự khác biệt rất quan trọng khi thực hiện các 
phép gán:
0x15A0int i = 10, j = 14;
int* p = &i;
p i
10
0x15A0
14
HIENLTH, C++ - 2010 16
0x15A0
0x15A4
int *q = &j;
*p = *q;
int i = 10, j = 14;
int *p = &i;
int *q = &j;
p = q;
và:
q j
0x15A4
14
p i
10
0x15A0q j
0x15A4
0x15A4
14
0x15A4
Luyện tập – Điền vào ô trống
void main()
{
inti = 10, j = 14, k;
int*p = &i;
i
0x2100
j
0x2104
HIENLTH, C++ - 2010 17
int*q = &j;
*p += 1;
p = &k;
*p = *q;
p = q;
*p = *q;
}
k
0x1208
p
0x120B
q
0x1210
Con trỏ và mảng
 Tên mảng được coi như là một con trỏ trỏ tới phần 
tử đầu tiên của mảng.
int A[6] = {2, 4, 6, 8, 10, 12};
HIENLTH, C++ - 2010 18
int *P;
P = A;
Con trỏ và Mảng
 Biến kiểu mảng là địa chỉ tĩnh của một vùng nhớ, được 
xác định khi khai báo, không thay đổi trong suốt chu kỳ 
sống.
 Biến con trỏ là địa chỉ động của một vùng nhớ, được xác 
HIENLTH, C++ - 2010
định qua phép gán địa chỉ khi chương trình thực thi.
19
#include 
using namespace std;
void main()
{
int a[10] = {1, 3, 4, 2, 0};
int *p;
p = a; //a = p: sai
cout<<a<<a[0]<<p<<*p<<endl;
}
Ví dụ con trỏ và mảng
Bắt đầu:
HIENLTH, C++ - 2010 20
Thực hiện P = &A[2];
Bây giờ, P[0] là A[2],
P[1] là A[3], …
Con trỏ - Toán tử “+” với số nguyên
34
#include 
using namespace std;
void main()
{
short a[10] = {1, 3, 5, 2, 0};
1
5
a
0x15A0
HIENLTH, C++ - 2010 21
0x15A02
short *p = a; 
cout<<a<<a[0]<<p<<*p<<endl;
p ++;
cout<<a<<a[0]<<p<<*p<<endl;
(*p) ++;
cout<<a<<a[0]<<p<<*p<<endl;
}
2
0
…
p0x16B2
Con trỏ và mảng
Giả sử con trỏ ptr trỏ tới phần tử a[i] nào đó của mảng 
a, thì:
 ptr + j chỉ đến phần tử thứ j sau a[i], tức a[i+j]
ptr - j chỉ đến phần tử thứ j tr ớc a[i], tức a[i-j]
HIENLTH, C++ - 2010
 ư
22
Các phép toán trên con trỏ
HIENLTH, C++ - 2010 23
Con trỏ - Luyện tập
void main()
{
int a[10] = {2, 3, 5, 1, 4, 
7, 0};
2 2
3 1
1 9
1 3
HIENLTH, C++ - 2010 24
int *p = a; 
cout<< a[0] << *p <<endl;
p ++;
cout<< *p << p[2] <<endl;
p ++; a[2] = 9;
cout<< p[1] << *p;
p -= 2;
cout<< p[3] << p[1] <<endl;
}
Biến tĩnh và biến động
Biến tĩnh Biến động
Có tên Không có tên
HIENLTH, C++ - 2010
Kích thước cố định Kích thước không cố định
Được cấp phát tự động trong Data 
Segment hoặc Stack Segment
Được cấp phát trong Heap 
Segment
Phạm vi sử dụng từ lúc khai báo đến 
hết khối gần nhất chứa nó.
Phạm vi sử dụng bắt đầu từ lúc 
được tạo ra và kết thúc khi bị hủy.
Tự động giải phóng khi hết phạm vi 
sử dụng
Không tự động giải phóng. Lập 
trình viên phải lo việc này.
25
Cấp phát biến động
 Không có tên, chỉ có địa chỉ  dùng biến con trỏ để 
lưu địa chỉ.
 Cú pháp:
Biế t ỏ Kiể
HIENLTH, C++ - 2010
 n-con- r = new u;
 Biến-con-trỏ = new Kiểu[số phần tử];
 Ví dụ:
 int* p = new int;
 double* pd = new double[10];
26
Hủy biến động
 Thông qua biến con trỏ lưu địa chỉ của biến động.
 Cú pháp:
 delete biến-con-trỏ;
ế
HIENLTH, C++ - 2010
 delete [] bi n-con-trỏ;
 Ví dụ:
 delete p;
 delete [] pd;
27
Câu hỏi và thảo luận
HIENLTH, C++ - 2010 28

File đính kèm:

  • pdfSlide bài giảng Lập trình C++ - Lương Trần Hy Hiến - Con trỏ.pdf
Tài liệu liên quan