01/10/2018, 08:22

Hỏi 1 đoạn nói về con trỏ trong cuốn Head First C

E đang đọc tới trang 88 của quyển Head First C thì có 1 đoạn như sau, em không hiểu nên nhờ mọi người dịch giúp:

The * and & operators are opposites. The & operator takes a piece of data and tells you where it’s stored. The * operator takes an address and tells you what’s stored there. Because pointers are sometimes called references, the * operator is said to dereference a pointer.

E cảm ơn trước

Shin viết 10:25 ngày 01/10/2018

đang đọc tới trang 88 của quyển Head First C thì có 1 đoạn như sau, em không hiểu nên nhờ mọi người dịch giúp:

Tạm dịch là thế này:
``
Dấu * và dấu & có tác dụng trái ngược nhau. Dấu & đi kèm với tên 1 biến và trả về địa chỉ mà biến đó được lưu trong bộ nhớ. Còn dấu * sẽ đi kèm với 1 địa chỉ và trả về dữ liệu mà địa chỉ đó lưu trữ. Vì con trỏ thỉnh thoảng đc gọi là tham chiếu, nên dấu * còn được gọi là dereference (từ này mình ko biết dịch sao) của 1 con trỏ.

Long Dragon viết 10:31 ngày 01/10/2018

Vì con trỏ thỉnh thoảng đc gọi là tham chiếu, nên dấu * còn được gọi là dereference (từ này mình ko biết dịch sao) của 1 con trỏ.

Anh có thể giải thích cho em cụ thể câu này không ? Mặc dù đã translate sang TV nhưng em vẫn chưa hiểu ý nghĩa của câu đó

Shin viết 10:25 ngày 01/10/2018

Giả sử có đoạn code sau:

int a = 0;
int *p= &a;   // Gán địa chỉ của a cho con trỏ p
int b = *p;   // b sẽ có giá trị = 0 vì (*p) tương đương với a
*p = 1;       // a bây h sẽ có giá trị là 1

Thì p là con trỏ chứa địa chỉ nơi mà biến a được lưu trong bộ nhớ. p chứa địa chỉ của a nên p còn được gọi là tham chiếu đến a( trỏ đến a). *p có tác dụng lấy giá trị mà biến a có ra(ở đây là 0) hoặc dùng để thay đổi giá trị của biến a vì thế nên * đc gọi là dereference( ngược với reference).

Long Dragon viết 10:24 ngày 01/10/2018

À, anh @Shin có thể dịch hiểu giùm em thêm 3 đoạn này với ạ:

The computer will allocate space to store the array, but it won’t allocate any memory to store the array variable. The compiler simply plugs in the address of the start of the array. But because array variables don’t have allocated storage, it means you can’t point them at anything else.

If you assign an array to a pointer variable, then the pointer variable will only contain the address of the array. The pointer doesn’t know anything about the size of the array, so a little information has been lost. That loss of information is called decay.

Every time you pass an array to a function, you’ll decay to a pointer, so it’s unavoidable. But you need to keep track of where arrays decay in your code because it can cause very subtle bugs.

Về cơ bản thì e vẫn dịch sang TV được nhưng lại ko hiểu ý muốn nói của nó là gì :):

Rem viết 10:38 ngày 01/10/2018

Mình cũng đang đọc cuốn này Mình không chắc lắm nhưng bạn có thể tham khảo
Đoạn thứ nhất thì mình cũng k hiểu lắm :))còn đoạn này

If you assign an array to a pointer variable, then the pointer variable will only contain the address of the array. The pointer doesn’t know anything about the size of the array, so a little information has been lost. That loss of information is called decay.

ví dụ như:

char a[]=“Hello!”;
char *p=a;
printf("%d\n",sizeof(a));//==7
printf("%d",sizeof§);//==8

trỏ p tới mảng a, thì sizeof(a) sẽ cho ta kích thức(số phần tử) của mảng, còn sizeof§ cho ta số kích thức bộ nhớ để lưu trữ con trỏ.

Every time you pass an array to a function, you’ll decay to a pointer, so it’s unavoidable. But you need to keep track of where arrays decay in your code because it can cause very subtle bugs.

Khi truyền một mảng vào hàm như;

int dem(int a[]);

a thực chất là con trỏ(trỏ tới mảng truyền vào), nên nếu dùng sizeof() để tích kích thức mảng truyền vào thì sẽ k chính xác vì thực chất là đang tính kích thức của con trỏ.

Shin viết 10:38 ngày 01/10/2018

The computer will allocate space to store the array, but it won’t allocate any memory to store the array variable. The compiler simply plugs in the address of the start of the array. But because array variables don’t have allocated storage, it means you can’t point them at anything else.

Máy tính chỉ cấp pháp vùng nhớ để lưu trữ mảng mà không cấp phát vùng nhớ nào lưu trữ array variable (biến mảng). Trình biên dịch sẽ gắn địa chỉ của địa chỉ đầu tiên của mảng vào biến mảng. Vì lí do biến mảng ko đc cấp phát vùng lưu trữ nên nó ko thể trỏ tới bất kỳ nơi nào khác

int a = 0; // khi đó a sẽ được lưu trữ tại vùng nhớ 0xABCDEF00 (cái này là giả sử) trong bộ nhớ
int b[2];  // khi đó b[0] đc lưu ở 0xFEABCD00 và b[1] được lưu ở vùng nhớ 0xFEABCD04(giả sử int là 32 bit)
// còn b thì là tên mảng nó sẽ đc compiler gán với địa chỉ của b[0] 1 cách tự động và b ko đc lưu trữ trong memory nên ko thể gán b= 0xXXXXX (1 địa chỉ khác)

If you assign an array to a pointer variable, then the pointer variable will only contain the address of the array. The pointer doesn’t know anything about the size of the array, so a little information has been lost. That loss of information is called decay.

Every time you pass an array to a function, you’ll decay to a pointer, so it’s unavoidable. But you need to keep track of where arrays decay in your code because it can cause very subtle bugs.

2 ý này thì gần như bạn trên trả lời, con trỏ chỉ có tác dụng lưu trữ địa chỉ nên nếu nó chứa địa chỉ của mảng thì nó chỉ đơn thuần là địa chỉ của phần tử đầu tiên của mảng, còn biến mảng như “b” trong ví dụ thì sẽ đc kèm theo kích thước của mảng đó.
Khi truyền array vào 1 hàm thì thực chất nó là truyền địa chỉ vào 1 con trỏ trong hàm đó thôi, nên làm mất đi khả năng kiểm tra kích thước của mảng, Khi đó bạn cần chú ý cẩn thận vì nếu mất kiểm soát về kích thước có thể gây lỗi.(ví dụ mảng có 3 phần tử nhưng mà truy cập vào phần tử thứ 4 thông qua con trỏ thì sẽ rất nguy hiểm).

Long Dragon viết 10:25 ngày 01/10/2018

Em còn hơi lơ tơ mơ chỗ này:

// còn b thì là tên mảng nó sẽ đc compiler gán với địa chỉ của b[0] 1 cách tự động và b ko đc lưu trữ trữ trong memory nên ko thể gán b= 0xXXXXX (1 địa chỉ khác)

ko dc lưu trữ trong memoryko thể gán b cho 1 địa chỉ khác nghĩa là sao anh ?
VD:

int a;
int *x = &a;

Khi mình khai báo con trỏ x nhưng chưa cấp phát cho nó thì vẫn có thể trỏ đến biến khác. Vậy thì lúc này, con trỏ x có “được lưu trữ trong memory” không anh ?

rogp10 viết 10:28 ngày 01/10/2018

Nếu bạn đọc hiểu được assembly thì đoạn đó bạn sẽ hiểu liền

Tức là địa chỉ mảng chỉ tồn tại trong câu lệnh truy cập thôi. Còn mỗi con trỏ là một ô nhớ.

Long Dragon viết 10:26 ngày 01/10/2018

Rất tiếc là em không có học assembly anh ơi

Shin viết 10:33 ngày 01/10/2018

Có đoạn code sau (mấy cái địa chỉ là mình giả sử thôi nhé):

int a; // a được lưu ở địa chỉ 0x0000AB00 và giá trị nó chưa đc khởi tạo nên là ngẫu nhiễn
a = 2; // a vẫn đc lưu ở 0x0000AB00 và giá trị của nó lúc này là 2
int *b; // b được lưu ở địa chỉ 0x0000CD00 và giá trị của nó cũng ngẫu nhiên.
b = &a; // b vẫn đc lưu ở địa chỉ 0x0000CD00 và giá trị mà nó lưu trữ là 0x0000AB00
int c = 3; // c đc lưu ở địa chỉ 0x0000EF00 và giá trị mà nó lưu trữ là 3.
b = &c; // bây h giá trị của b sẽ là 0x0000EF00 và địa chỉ nó vẫn ko đổi: 0x0000CD00
int arr[2] // arr[0] và arr[1] sẽ được lưu trữ ở 0x0000FFE0 và 0x0000FFE4 (giả sử int là 4 byte)
// arr là biến mảng chỉ được sử dụng trước khi biên dịch sau khi biên dịch thì chỉ có arr[0] và arr[1]
// ko có vùng nhớ nào tương ứng với biến arr cả.
b = arr; // lệnh này tương đương b = &(arr[0]);
// lúc này b sẽ có giá trị là 0x0000FFE0, b có thể trỏ tới bất kỳ vùng nhớ nào tùy ý.
// nhưng arr thì lại ko thể như thế.
arr = &a; // lệnh này sẽ bị lỗi vì arr là tên mảng tương đương 1 hằng con trỏ.
Long Dragon viết 10:32 ngày 01/10/2018

Ừm, cũng hiểu được xíu

Nhân tiện, anh @Shin cho em hỏi là: ptr = &var; có nghĩa là cho con trỏ ptr cho đến biến var, vậy nó có còn đúng khi mình để &var = ptr; và vì sao ?

Reoteu Ray viết 10:35 ngày 01/10/2018

bạn mở ide lên và chạy lệnh thử xem kq là biết mà , &a là lấy địa chỉ của biến a , p =&a nếu p là con trỏ thì nó sẽ trỏ đến biến a , còn nếu nó là 1 biến int thì nó sẽ lưu địa chỉ của biến a ( địa chỉ của các biến được lưu bằng int) , còn &a = p thì sai nếu p là 1 con trỏ còn p là 1 biến cùng kiểu với a thì đó gọi là tham chiếu lúc này a và p có cùng vùng nhớ…

dnh-cpp

4.4 Địa chỉ của biến

cout << "Value of var: " << var << endl; cout << "Value of var_reference: " << var_reference << endl;…

Shin viết 10:28 ngày 01/10/2018

&var sẽ lấy địa chỉ của var ra, và đây là 1 hằng số cho đến khi var được giải phóng và cấp phát lại. điều đó nghĩa là bạn ko thể chuyển địa chỉ của var thành giá trị mà bạn lưu trong ptr.
Ví dụ như thế này, var là tên 1 ngôi nhà thì &var là địa chỉ của nó trong danh sách quản lý đất đai. Bạn có thể thực hiện var2=var, tức là xây 1 ngôi nhà khác giống y chang ngôi nhà tên là var. Nhưng việc &var = ptr thì tương đương bạn bưng ngôi nhà đó đến đặt ở 1 chỗ khác có địa chỉ là ptr(điều này ko đc phép).

Bài liên quan
0