Bài giảng Kỹ thuật lập trình - Chương 2: Quản lý bộ nhớ

Chương 2:  
Quản lý bộ nhớ  
Biến: tên biến, vùng nhớ và giá trị biến  
• Mỗi biến trong C có tên và giá trị tương ứng. Khi một biến  
được khai bá o, một vùng nhớ trong má y tí nh sẽ được cấp  
phá t để lưu giá trị của biến. Kí ch thước vùng nhớ phu thuộc  
kiểu của biến, ví dụ 4 byte cho kiểu int  
int x = 10;  
• Khi lệnh này được thực hiện, trì nh biên dịch sẽ thiết lập để  
4 byte vùng nhớ này lưu giá trị 10.  
• Phé p toá n & trả về địa chỉ của x, nghĩa là địa chỉ của ô nhớ  
đầu tiên trong vùng nhớ lưu trữ giá trị của x.  
2
Biến: tên biến, vùng nhớ và giá trị biến  
• Mỗi biến trong C có tên và giá trị tương ứng. Khi một biến  
được khai bá o, một vùng nhớ trong má y tí nh sẽ được cấp  
phá t để lưu giá trị của biến. Kí ch thước vùng nhớ phu thuộc  
kiểu của biến, ví dụ 4 byte cho kiểu int  
int x = 10;  
• Khi lệnh này được thực hiện, trì nh biên dịch sẽ thiết lập để  
4 byte vùng nhớ này lưu giá trị 10.  
• Phé p toá n & trả về địa chỉ của x, nghĩa là địa chỉ của ô nhớ  
đầu tiên trong vùng nhớ lưu trữ giá trị của x.  
3
Biến: tên biến, vùng nhớ và giá trị biến  
Tên biến x  
tham chiếu đến vị trí vùng  
nhớ  
65329  
Giá trị được lưu trong  
vùng nhớ  
10  
Địa chỉ của vị trí vùng nhớ  
65325  
65324  
• int x = 10;  
• xbiểu diễn tên biến  
(e.g. an assigned name for a memory location )  
• &xbiểu diễn địa chỉ ô nhớ đầu tiền thuộc vùng nhớ  
của x, tức là 65325  
• *(&x) or x biểu diễn giá trị được lưu trong vùng nhớ  
của x, tức là 10  
4
Chương trì nh ví dụ  
#include<stdio.h>  
int main() {  
int x = 10;  
printf("Value of x is %d\n",x);  
printf("Address of x in Hex is %p\n",&x);  
printf("Address of x in decimal is  
%lu\n",&x);  
printf("Value at address of x is  
%d\n",*(&x));  
return 0;  
}
Value of x is 10  
Address of x in Hex is 0061FF0C  
Address of x in decimal is 6422284  
Value at address of x is 10  
5
Khá i niệm con trỏ  
• Con trỏ là một biến chứa địa chỉ vùng nhớ của một  
biến khá c.  
• Cú phá p chung khai bá o biến con trỏ  
data_type* ptr_name;  
• Ký hiệu '*’ thô ng bá o cho trì nh biên dịch rằng  
ptr_name là một biến con trỏ và data_type chỉ định  
rằng con trỏ này sẽ trỏ tới địa chỉ vùng nhớ của một  
biến kiểu data_type.  
6
Tham chiếu ngược (dereference) biến con trỏ  
▪ Chúng ta có thể “tham chiếu ngược" một con trỏ, nghĩa  
là lấy giá trị của biến mà con trỏ đang trỏ vào bằng  
cá ch dùng phá p toá n ‘*’, chẳng hạn *ptr.  
▪ Do đó, *ptr có giá trị 10, vì 10 đang là giá trị của x.  
7
Ví dụ con trỏ  
int x = 10;  
int *p = &x;  
Nếu con trỏ pgiữ địa chỉ của biến a, ta nó i ptrỏ tới biến  
a
*p biểu diễn giá trị lưu tại địa chỉ p  
*p được gọi là “tham chiếu ngược” của con trỏ p  
• Con trỏ được dùng để lấy địa chỉ của biến nó trỏ vào,  
đồng thời cũng có thể lấy giá trị của biến đó  
8
Con trỏ  
int x = 10;  
int *ptr;  
ptr = &x;  
65329  
10  
65325  
65324  
Tên biến  
x
65325  
*ptr  
65320  
ptr  
Tên biến con trỏ  
9
Biến và con trỏ  
65329  
Con trỏ  
Biến  
int *p; p được khai báo là con trỏ int  
p = &a; p giữ giá trị địa chỉ a, i.e.65325  
*p biểu diễn giá trị lưu tại p, ie.10  
int b = *p; b có giá trị 10.  
*p = 20; a có giá trị 20.  
int x = 10;  
10  
&x biểu diễn địa chỉ của x  
x biểu diễn giá trị lưu tại địa  
chỉ &x  
65325  
65324  
int *p;  
*p = 10; // this is not correct.  
10  
Ví dụ con trỏ  
#include<stdio.h>  
int main() {  
int x = 10;  
int *ptr;  
ptr = &x;  
printf("Value of x is %d\n", x);  
printf("Address of x is %lu\n", (unsigned long int) &x);  
printf("Value of pointer ptr is %lu\n", (unsigned long int)  
ptr);  
printf("Address of pointer ptr is %lu\n", (unsigned long int)  
&ptr);  
printf("Ptr pointing value is %d\n",*ptr);  
return 0;  
Value of x is 10  
}
Address of x is 6422284  
Value of pointer ptr is 6422284  
Address of pointer ptr is 6422280  
Ptr pointing value is 10  
11  
Cá c phé p toá n trên con trỏ  
• Cộng hoặc trừ với 1 số nguyên n trả về 1 con trỏ  
cùng kiểu, là địa chỉ mới trỏ tới 1 đối tượng khác  
nằm cách đối tượng đang bị trỏ n phần tử  
• Trừ 2 con trỏ cho ta khoảng cách (số phần tử)  
giữa 2 con trỏ  
• KHÔ NG có phép cộng, nhân, chia 2 con trỏ  
• Có thể dùng các phép gán, so sánh các con trỏ  
▫ Chú ý đến sự tương thích về kiểu.  
12  
Ví dụ  
char *pchar; short *pshort; long *plong;  
pchar ++; pshort ++; plong ++;  
Giả sử các địa chỉ ban đầu tương ứng của 3 con  
trỏ là 100, 200 và 300, kết quả ta có các giá trị  
101, 202 và 304 tương ứng  
Nếu viết tiếp  
plong += 5; => plong = 324  
pchar -=10; => pchar = 91  
pshort +=5; => pshort = 212  
13  
Chú ý  
++và -- có độ ưu tiên cao hơn * nên *p++  
tương đương với *(p++) tức là tăng địa chỉ mà  
nó trỏ tới chứ không phải tăng giá trị mà nó chứa.  
*p++ = *q++ sẽ tương đương với  
*p = *q;  
p=p+1;  
q=q+1;  
14  
Con trỏ *void  
• Là con trỏ không định kiểu. Nó có thể trỏ  
tới bất kì một loại biến nào.  
• Thực chất một con trỏ voidchỉ chứa  
một địa chỉ bộ nhớ mà không biết rằng  
tại địa chỉ đó có đối tượng kiểu dữ liệu gì.  
Do đó không thể truy cập nội dung của  
một đối tượng thông qua con trỏ void.  
• Để truy cập được đối tượng thì trước hết  
phải ép kiểu biến trỏ void thành biến trỏ  
có định kiểu của kiểu đối tượng  
15  
Con trỏ *void  
float x; int y;  
void *p; // khai báo con trỏ void  
p = &x; // p chứa địa chỉ số thực x  
*p = 2.5; // báo lỗi vì p là con trỏ void  
/* cần phải ép kiểu con trỏ void trước khi  
truy cập đối tượng qua con trỏ */  
*((float*)p) = 2.5; // x = 2.5  
p = &y; // p chứa địa chỉ số nguyên y  
*((int*)p) = 2; // y = 2  
16  
Con trỏ và mảng  
• Giả sử ta có int a[30]; thì &a[0]là  
địa chỉ phần tử đầu tiên của mảng đó,  
đồng thời là địa chỉ của mảng.  
• Trong C, tên của mảng chí nh là một hằng  
địa chỉ bằng địa chỉ của phần tử đầu tiên  
của mảng  
a = &a[0];  
a+i = &a[i];  
17  
Con trỏ và mảng  
Tuy vậy cần chú ý rằng alà 1 hằng nên  
khô ng thể dùng nó trong câu lệnh gán hay  
toán tử tăng, giảm như a++;  
• Xé t con trỏ: int *pa;  
pa = &a[0];  
Khi đó pa trỏ vào phần tử thứ nhất của  
mảng và  
pa +1sẽ trỏ vào phần tử thứ 2 của mảng  
*(pa+i) sẽ là nội dung của a[i]  
18  
Con trỏ và xâ u  
• Ta có char tinhthanh[30] =“Da Lat”;  
• Tương đương :  
char *tinhthanh;  
tinhthanh=“Da lat”;  
Hoặc: char *tinhthanh =“Da lat”;  
• Ngoài ra các thao tác trên xâu cũng tương tự  
như trên mảng  
*(tinhthanh+3) = “l”  
• Chú ý : với xâu thường thì không thể gán trực  
tiếp như dòng thứ 3  
19  
Mảng cá c con trỏ  
• Con trỏ cũng là một loại dữ liệu nên ta có thể  
tạo một mảng các phần tử là con trỏ theo dạng  
thức.  
<kiểu> *<mảng con trỏ>[số phần tử];  
Ví dụ: char *ds[10];  
▫ ds là 1 mảng gồm 10 phần tử, mỗi phần tử là  
1 con trỏ kiểu char, được dùng để lưu trữ được  
của 10 xâu ký tự nào đó  
• Cũng có thẻ khởi tạo trực tiếp các giá trị khi  
khai bá o  
char * ma[10] = {“mot”,”hai”,”ba”...};  
20  
Tải về để xem bản đầy đủ
pdf 32 trang Thùy Anh 19300 Free
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kỹ thuật lập trình - Chương 2: Quản lý bộ nhớ", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfbai_giang_ky_thuat_lap_trinh_chuong_2_quan_ly_bo_nho.pdf