Diễn đàn ITK36 - ĐH Sư phạm TPHCM

Diễn đàn ITK36 - ĐH Sư phạm TPHCM
Diễn đàn đang nâng cấp ...
 
IndexCalendarTrợ giúpTìm kiếmThành viênNhómĐăng kýĐăng Nhập

Share | 
 

 Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao

Xem chủ đề cũ hơn Xem chủ đề mới hơn Go down 
Tác giảThông điệp
Admin
Administrator


Nam
Tổng số bài gửi : 219
Điểm kinh nghiệm : 14176
Danh tiếng : 104
Ngày tham gia : 02/10/2010
Age : 24
Đến từ : Lớp CNTT K36
Tài sản : Ring of The Creator
Tài năng của Admin Danh vọng:219%/1000%
Tài năng:24%/100%


Bài gửiTiêu đề: Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao   Tue Oct 11, 2011 2:12 pm

Bài này do một thành viên của condongcviet viết, mình thấy hay nên post lại cho mọi người
Nguồn: http://diendan.congdongcviet.com/showthread.php?t=42977

Chap I : Bộ nhớ

Bộ nhớ vật lý


Bộ nhớ ảo




Hình 1 chúng ta thấy những thứ được gọi là bộ nhớ, bộ nhớ vật lý, sở nắm nghịch thoải mái ý hơ hơ, cái này là thiết bị bạn à
Hình 2 là mô hình bộ tổ chức bộ nhớ ảo mức khái niệm
Hình 3 là mình chụp lại các vùng của bộ nhớ ảo của 1 tiến trình quen thuộc Unikey


I. Bộ nhớ ảo là gì?

Quản lý bộ nhớ vật lý (cấp phát, thu hồi) là 1 vấn đề cực kì phức tạp trong hệ thống máy tính , để bảo đảm sự hiệu quả, đúng đắn, an toàn cho việc quản lý đó, hệ điều hành xây dựng lên các vùng nhớ ảo

Trong hệ thống máy tính, bộ nhớ ảo (tiếng Anh: virtual memory) là một kĩ thuật cho phép một chương trình ứng dụng tưởng rằng mình đang có một dải bộ nhớ liên tục (một không gian địa chỉ), trong khi thực ra phần bộ nhớ này có thể bị phân mảnh trong bộ nhớ vật lý và thậm chí có thể được lưu trữ cả trong đĩa cứng. So với các hệ thống không dùng kĩ thuật bộ nhớ ảo, các hệ thống dùng kĩ thuật này cho phép việc lập trình các ứng dụng lớn được dễ dàng hơn và sử dụng bộ nhớ vật lý thực (ví dụ RAM) hiệu quả hơn.

Lưu ý rằng khái niệm "bộ nhớ ảo" không chỉ có nghĩa "sử dụng không gian đĩa để mở rộng kích thước bộ nhớ vật lý" - nghĩa là chỉ mở rộng hệ thống bộ nhớ để bao gồm cả đĩa cứng. Việc mở rộng bộ nhớ tới các ổ đĩa chỉ là một hệ quả thông thường của việc sử dụng các kĩ thuật bộ nhớ ảo. Trong khi đó, việc mở rộng này có thể được thực hiện bằng các phương pháp khác như các kĩ thuật overlay hoặc chuyển toàn bộ các chương trình cùng dữ liệu của chúng ra khỏi bộ nhớ khi các chương trình này không ở trạng thái hoạt động. Định nghĩa của "bộ nhớ ảo" có nền tảng là việc định nghĩa lại không gian địa chỉ bằng một dải liên tục các địa chỉ bộ nhớ ảo để "đánh lừa" các chương trình rằng chúng đang dùng các khối lớn các địa chỉ liên tục.
(theo wiki)

II. Địa chỉ ảo là gì?


Trong cái vùng bộ nhớ ảo kia, để cho tiến trình dễ sử dụng, hệ điều hành dễ hiểu, 2 thằng này cùng nhau quy định rằng, chi nhỏ ra theo từng byte, và đánh số từ 1 đến hết
cái ô nhớ nào đó, đã được đánh số là i thì ta nói địa chỉ của cái ô nhớ đó là i

ok?!!!
giả sử tôi có biến a khai báo như sau
int a;
và a nằm trong cái ô thứ 452321 tại cái vùng nhớ trên, vậy a có địa chỉ là 452321

tiến trình hiểu là thế, còn hệ điều hành thì hiểu hơn 1 tí : "à, cái địa chỉ này tương ứng với cái ô nhớ nào trong thanh ram mà ta đang quản lý, he he he he he he"


thêm 1 tí nữa là : người ta ko dùng hệ thập phân (decimal, hệ đếm cơ số 10) để viết địa chỉ đâu, nên thui, chuyển qua hệ thập lục phân (hexadecimal , hệ đếm cơ số 16 nha )
452321 hệ cơ số 10, chuyển lại thành 6E6E1 ở hệ cơ số 16
ở trong C tôi viết là 0x6E6E1
ở ngôn ngữ ASM tôi viết là 6E6E1h << thêm chữ h vài cuối để hiểu hệ cơ số ấy mà
thôi viết là 0006E6E1h đi
tại sao vậy ? tại vì như này nè
trong windows 32bit (xp, vista, 7) thì địa chỉ ảo có độ dài là 32 bit, tương ứng với số hexa có 8 chữ số, thế à, nên tôi viết thêm 0 vào cho dễ hiểu ấy mà
Để ko bị loãng bài viết mình xin trình bày các điều cần nhớ sau đây :
+ Mỗi tiến trình có 1 vùng nhớ ảo riêng
+ Vùng nhớ ảo là 1 ko gian địa chỉ ảo trải dài từ thấp đến cao ( từ 0x0000 -> cao hơn)
+ Ở trong windows 32bit thì ko gian địa chỉ ảo có địa chỉ từ 00000000h trải dài đến 7fffffffh
+ Bạn cần hiểu nó chỉ là ảo, ko phải vùng nào cũng có bộ nhớ vật lý thật đâu nhá,
+ Khái niệm về bộ nhớ phân đoạn : segment offset bạn hãy bỏ qua đi, vì nó quá cũ rồi


III. Ví dụ vui về địa chỉ ảo
để làm ví dụ vui này bạn cần 2 cái đó là
+ pokemon : http://forums.congdongcviet.com/atta...3&d=1282105506
+ armoney active code là dot68 : http://forums.congdongcviet.com/atta...1&d=1282119896

Khi chơi game, ta thấy điểm hiện lên trên màn hình, vậy thì chắc chắn nó sẽ được lưu trữ ở đâu đó trong bộ nhớ và sẽ có địa chỉ VA cụ thể. Dân lập trình chúng ta gọi chúng là biến, và có địa chỉ cụ thể, hj hj

Để thay đổi điểm từ phía app của mình, đầu tiên chúng ta phải tìm được địa chỉ VA của biến điểm này đã nhỉ.

Để tìm được địa chỉ của biến này ko quá khó với 1 tool cơ bản như artmoney (Chưa có download ở đây, active code là dot68) :

Bước 1
Đầu tiên bật pikachu lên chơi lấy 20 điểm và bật artmoney lên,
đầu tiên là chọn tiến trình, pikachu ở đây có cái tên là D4S
rồi click vào Search lên 1 hộp thoại


Bước 2
click vào ... để chọn kiểu dữ liệu, mình hack nhiều lần rồi nên biết nó là kiểu float 4byte, nếu chưa hack bao giờ, các bạn có thể để ALL để tìm với mọi loại dữ liệu

Bước 3
chúng ta sẽ thu được 1 loạt địa chỉ đang chứa giá trị 20, bây giờ chúng ta vào trong game để chơi cho điểm trở thành 40 rồi vào artmoney, click vào nút Filter gõ giá trị mới là 40 rồi ok

Bước 4

Vậy là ta đã biết địa chỉ của biến điểm là 004B6088[/size]


Được sửa bởi Admin ngày Tue Oct 11, 2011 3:16 pm; sửa lần 1.
Về Đầu Trang Go down
Xem lý lịch thành viên http://cnttk36.forumotion.net
Admin
Administrator


Nam
Tổng số bài gửi : 219
Điểm kinh nghiệm : 14176
Danh tiếng : 104
Ngày tham gia : 02/10/2010
Age : 24
Đến từ : Lớp CNTT K36
Tài sản : Ring of The Creator
Tài năng của Admin Danh vọng:219%/1000%
Tài năng:24%/100%


Bài gửiTiêu đề: Re: Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao   Tue Oct 11, 2011 2:22 pm

Chap II : Tổng quan


I. Cái nhìn vấn đề
A: Con trỏ là gì, chả hiểu cái khỉ khô gì cả, nghe nói khó lắm….
B: Hoặc có bạn học 2,3 buổi xong nói , úi trời dễ ợt ấy mà,…………….

thứ 1 đối với A : Con trỏ dễ ợt ấy mà, chỉ cần bạn theo dõi đầy đủ tut này, làm theo hướng dẫn

thứ 2 đối với B : thôi đi nhé pa, đọc xong cái bài viết này đã, rồi hẵng kết luận nha

tôi xì pam linh tinh thế thôi
đi thẳng vào vấn đề đi
1. con trỏ chỉ là 1 biến nguyên bình thường
con trỏ chỉ là 1 biến nguyên bình thường như cân đường hộp sữa ý bạn à
nó là 1 biến, biến nguyên giá trị của nó là nguyên
nó chứa cái được gọi là địa chỉ ảo mà ta đã nói ở bên trên đó bạn
ví dụ như là : 0x6E6E1 hoặc 0x4B6088 hoặc 454321
đó bạn à
sau này nha
dù bạn khai báo
Trích dẫn :

void *p;
char *p;
hay là
Trích dẫn :

double *p;
long *p;

thì p vẫn là 1 biến, nó là 1 biến, biến nguyên,

2. trong hệ điều hành 32bit thì nó có độ dài là 32 bit,
trong windows 32bit (xp, vista, 7) thì địa chỉ ảo có độ dài là 32 bit, tương ứng với số hexa có 8 chữ số,

vì sao lại chỉ có 32bit ?
vì nó cần 32bit là vừa đủ để chỉ trỏ hết vùng nhớ ảo đó


II. Con trỏ dùng để làm gì?

Vâng, tôi chưa từng bao giờ nghĩ đến 1 câu hỏi đơn giản mà tuyệt vời như này vì tôi luôn …. Nói thế nào nhỉ, tôi luôn….. tôi cứ tiện tay là dùng, hợp lý tôi dùng, cần thiết tôi dùng mà cho đến nay tôi chưa hề nghĩ đến câu trả lời câu câu hỏi
Con trỏ dùng để làm gì nhỉ
+ à à, đơn giản, đúng như cái bản chất của nó thì nó để chỉ trỏ lung tung trong vùng nhớ ảo của tiến trình hiện tại
+ có người nói với tôi để dùng làm tham biến cho hàm, tôi hok nói gì cả, vì cái câu ni đúng thì đúng với các bạn mới thui, chứ đi sâu vào vấn đề thì lại sai lè ra ý (tại sao xem tiếp ở các cháp sau nha)
Tôi ko thể nói rõ 1 cách đơn giản ngay từ đây là con trỏ để làm gì cho bạn, thậm chí cả sau này cũng thế
Nhưng tôi tin chắc rằng mình sẽ mang lại cho các bạn những sự tuyệt vời mà tôi biến đến từ cách sử dụng con trỏ ……

À quên , có 1 điều này cực kì quan trọng : con trỏ chỉ là 1 công cụ, là 1 kiểu dữ liệu, để ta cài đặt các giải thuật, chứ ko phải là 1 giải thuật hay thuật toán, nên câu nói như là "dùng con trỏ để giải bài A", "giải bài tập B bằng con trỏ" là hoàn toàn sai.
Nói đúng phải là "giải bài tập C sử dụng con trỏ"


Được sửa bởi Admin ngày Tue Oct 11, 2011 3:20 pm; sửa lần 1.
Về Đầu Trang Go down
Xem lý lịch thành viên http://cnttk36.forumotion.net
Admin
Administrator


Nam
Tổng số bài gửi : 219
Điểm kinh nghiệm : 14176
Danh tiếng : 104
Ngày tham gia : 02/10/2010
Age : 24
Đến từ : Lớp CNTT K36
Tài sản : Ring of The Creator
Tài năng của Admin Danh vọng:219%/1000%
Tài năng:24%/100%


Bài gửiTiêu đề: Re: Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao   Tue Oct 11, 2011 3:07 pm

Chap III : Khai báo


Chà chà, dẫn nhập thật là dài dài, nhưng bạn ơi, hãy chắc chắn với tôi rằng bạn đã cảm thấy ok ở 2 chap đầu (xin đừng đọc lướt qua nó với vẻ thờ ơ) vì đó là tiền đề cực kì quan trọng để bạn có thể vượt qua khỏi mức cơ bản sau này

I. Cấu trúc khai báo
kieudulieu *tenConTro;

kiểu dữ liệu ở đây có thể là
+ kiểu dữ liệu có sẵn (built-in data type ) : int , char , void , double , long , ......
+ kiểu dữ liệu cấu trúc do người dùng định nghĩa (user-defined data type) : struct , union
+ kiểu dữ liệu là lớp do người dùng định nghĩa (C++)
+ kiểu dữ liệu dẫn xuất + kiểu con trỏ hàm (các cháp adv nhé)

nhắc lại lần nữa, kiểu dữ liệu này là kiểu dữ liệu của cái vùng nhớ mà nó trỏ đến nha


tenConTro : là tên của con trỏ nha
ra khỏi câu khai báo rồi thì tenConTro sẽ là tên của con trỏ,
Trích dẫn :

int *a;
ra khỏi câu khai báo này ta sẽ nói : a là con trỏ

II. Ví dụ
Trích dẫn :

int *a,*p;

ta sẽ được 2 con trỏ a, và p
xin chú ý đế cách tôi viết nhé
+ a, p là con trỏ
+ *a,*p không phải là con trỏ
+ kí tự * đứng gần a, đứng gần p, tại sao vậy?

III. Chú ý
Trích dẫn :

int *a,b; // thì a là con trỏ, b là biến nguyên
int* a,b; //thì a là con trỏ, b là biến nguyên
//và cách viết như này cực kì đáng ghét vì gây ra toàn hiểu lần đáng ghét

void *a;//đúng , hoàn toàn có con trỏ void nha





TO BE CONTINUE.............. Razz
Về Đầu Trang Go down
Xem lý lịch thành viên http://cnttk36.forumotion.net
Admin
Administrator


Nam
Tổng số bài gửi : 219
Điểm kinh nghiệm : 14176
Danh tiếng : 104
Ngày tham gia : 02/10/2010
Age : 24
Đến từ : Lớp CNTT K36
Tài sản : Ring of The Creator
Tài năng của Admin Danh vọng:219%/1000%
Tài năng:24%/100%


Bài gửiTiêu đề: Re: Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao   Wed Oct 12, 2011 1:43 pm

Chap IV : Khởi tạo

I. Khởi tạo là gì

Có 1 số bạn sẽ lạ lầm vì cái tiêu đề khai báo với khởi tạo nghe có vẻ giống nhau..... Nhưng bạn ơi, khai báo (declared, register) và khởi tạo(initialize) hoàn toàn khác nhau nha
Trích dẫn :

int a; // khai báo biến a
int b=2; //khai báo biến b và kết hợp với khởi tạo giá trị cho biến b bằng 2

Khi ta khai báo 1 biến thì câu lệnh đầu tiên thiết lập giá trị cho biến đó thì đó là khởi tạo. Trong C03, C++03 trở lên khi ta khai báo 1 biến local, chưa khởi tạo giá trị mà đã đem sử dụng thì sẽ phát sinh lỗi runtime .
Ví dụ đoạn code sau vẫn dịch được, vẫn run nhưng khi chạy sẽ tung ra lỗi "Run-Time Check Failure #3 - The variable 'a' is being used without being initialized."

Trích dẫn :

#include <iostream>
void main()
{

int
a;
if (a==2) printf("ok"); // có lỗi run-time sinh ra ở dòng này
}

II. Khởi tạo giá trị cho biến con trỏ
cấu trúc khởi tạo:
Code:

TênConTrỏ= ĐịaChỉ;

+ trong đó tên con trỏ là tên của biến con trỏ
+ địa chỉ là vùng địa chỉ mà ta muốn trỏ đến

Ví dụ

Chú ý 1: Bản thân p cũng là 1 biến (nguyên), p cũng nằm trong bộ nhớ, cũng có địa chỉ riêng đó bạn à

Chú ý 2: Toán tử & ở đây chính xác phải gọi là unary operator &, toán tử & 1 ngôi, nó hoàn toàn với toán tử & 2 ngôi (bitwise ). Toán tử & 1 ngôi này dùng để lấy địa chỉ của 1 biến . Trước khi động đến lý thuyết về con trỏ, chúng ta đã từng sử dụng toán tử này rồi đó
Code:
:scanf("%d",&a); .

Trích dẫn :

a=3&2 //toán tử & 2 ngôi, là toán tử dạng bitwise
p=&a; // toán tử & 1 ngôi, là toán tử lấy địa chỉ của 1 biến

Chú ý 3: Có thể viết ví dụ trên ngắn gọn lại thành
Trích dẫn :

int[colr=black] a=1987,p=&a;[/color]

III. Có được điều gì sau khi khởi tạo như ví dụ trên

+Khi giá trị nằm trong p là địa chỉ của a thì ta nói p trỏ vào a

+ Lúc này thì *p hoàn toàn tương đương với a , người ta coi *p là bí danh của a , thao tác với *p cũng như thao tác với a, thao tác với a cũng như thao tác với *p
ví dụ :
a. câu lệnh a=2; hoàn toàn tương đương với câu lệnh *p=2;
b. câu lệnh a++; hoàn toàn tương đương với (*p)++
// chú ý khác với *p++ nhé, phải cho *p vào trong đóng mở ngoặc vì toán tử * có độ ưu tiên thấp hơn ++
c. câu lệnh b=a+c-9; hoàn toàn tương đương với câu lệnh b=(*p)+c-9;
d. câu lệnh (*p)=(*p) -1227; hoàn toàn tương đương với a=a-1227;

+Lúc này câu lệnh scanf("%d",&a); ta có thể thay bằng scanf("%d",p);


Chú ý : Toán tử *
Toán tử * ở đây là toán tử 1 ngôi , tác dụng là truy xuất đến ô nhớ mà con trỏ đang trỏ đến

Để tránh những hiểu lầm ko đáng có, khi có sự nhập nhằng mà bạn ko thể đoán được, bản hãy thêm cặp () nha
Trích dẫn :

(*p)++
a+(*p)*c
// thêm vào cho nó sáng sủa code ra
IV. Một số trường hợp

1. Hiểu lầm về cách cho p trỏ vào a

2. Cùng trỏ vào 1 biến

3. Con trỏ đa cấp

4. Con trỏ trỏ đến ô nhớ đã biết

5. Con trỏ void
Con trỏ void là 1 con trỏ đặc biệt, thích trỏ đi đâu thì trỏ
Trích dẫn :

int ham()
{

return 1;
}


void main()
{

int a;
void *p,*q;
p=ham;
q=&a;
}


Con trỏ voi khác với con trỏ hươu ở chỗ nào ? vui lòng đón xem ở các chap tiếp
Về Đầu Trang Go down
Xem lý lịch thành viên http://cnttk36.forumotion.net
chienthan_16_12
Member cấp 3


Nam
Tổng số bài gửi : 42
Điểm kinh nghiệm : 11440
Danh tiếng : 10
Ngày tham gia : 14/02/2011
Đến từ : Địa Ngục Trần Gian
Tài năng của chienthan_16_12 Danh vọng:42%/1000%
Tài năng:%/100%


Bài gửiTiêu đề: Re: Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao   Wed Oct 12, 2011 7:59 pm

Thích gọi con chó hơn con trỏ Wink)
Về Đầu Trang Go down
Xem lý lịch thành viên http://chienthan1612.com
Sponsored content



Tài năng của Sponsored content Danh vọng:%/1000%
Tài năng:%/100%


Bài gửiTiêu đề: Re: Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao   

Về Đầu Trang Go down

Bài viết mới cùng chuyên mục

Bài viết liên quan

 

Tìm hiểu bản chất của con trỏ - từ cơ bản đến nâng cao

Xem chủ đề cũ hơn Xem chủ đề mới hơn Về Đầu Trang 
Trang 1 trong tổng số 1 trang

Permissions in this forum:Bạn không có quyền trả lời bài viết
Diễn đàn ITK36 - ĐH Sư phạm TPHCM :: Góc học tập :: Tài liệu học tập-
Chuyển đến