01/10/2018, 15:19

AddTail - AddHead - Danh sách liên kết đơn

ở 2 dòng em đặt dấu chấm hỏi thì theo em hiểu p->pNextl.pTail->pNext sẽ là một biến con trỏ và giá trị nó chứa sẽ là địa chỉ của node tiếp theo. Còn p là 1 con trỏ kiểu Node, tức là p sẽ trỏ đến ô gồm con trỏ pNext và giá trị của p. Vậy tại sao sau khi dùng p->pNext = l.pHeadl.pTail->pNext=p lại có nghĩa là p->pNext và l.pTail được gán là địa chỉ của l.pHead và p. Muốn một con trỏ chứa địa chỉ một ô nào đó ta phải dùng & chứ. Nhưng khi em dùng & thì chương trình lại báo lỗi. Hy vọng anh chị có thể giải đáp thắc mắc của em.

//Gan node vao dslk - AddNode vao dau dslk
    void AddHead(List &l, Node *p) {
    	if (l.pHead == NULL)
    		l.pHead = l.pTail = p;
    	else {
    		p->pNext = l.pHead;  //????
    		l.pHead = p;
    	}
    }


//Gan node vao dslk - AddNode vao cuoi dslk
void AddTail(List &l, Node*p) {
	if(l.pTail==NULL)
		l.pHead = l.pTail = p;
	else {
		l.pTail->pNext=p; //?????
		l.pTail = p;
	}
}
Quân viết 17:25 ngày 01/10/2018

Vì nó đã là con trỏ rồi, bạn dùng & thì lại là lấy địa chỉ của con trỏ nên lỗi là phải rồi

Thược Nguyễn viết 17:32 ngày 01/10/2018

Bác dùng con trỏ thì thuần con trỏ thôi. Đừng dùng lẫn lộn con trỏ và ref

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

Vậy tại sao sau khi dùng p->pNext = l.pHeadl.pTail->pNext=p lại có nghĩa là p->pNext và l.pTail được gán là địa chỉ của l.pHead và p

Thực ra phải gọi là địa chỉ của *p và *l.pHead (có *) mới đúng, mà p và pHead đều là con trỏ rồi nên gán thẳng luôn.

Tsuki_Tsuki viết 17:35 ngày 01/10/2018

ý của bạn là dấu & phải không. Theo mình nhớ dấu * là truy cập giá trị, còn & mới dùng truy cập địa chỉ. Cảm ơn bạn rất nhiều, mình đã hiểu.

Tsuki_Tsuki viết 17:31 ngày 01/10/2018

Theo mình biết, con trỏ nó cũng là một biến nhưng nó đặc biệt vì giá trị nó chứa là địa chỉ một biến khác. Riêng nó cũng tồn tạo một địa chỉ riêng. Vậy tại sao khi mình dùng & để gán một con trỏ mang địa chỉ một con trỏ khác lại bị sai. Mong bạn giải thích rõ hơn dùm mình.

Quân viết 17:27 ngày 01/10/2018

Khi bạn tạo 1 con trỏ tới 1 con trỏ trỏ tới con trỏ kiểu Node thì con trỏ mới được tạo ra sẽ là con trỏ cấp 2 hoặc có thể nghĩ đơn giản nó sẽ là con trỏ của kiểu con trỏ. Tất nhiên là k thể gán cho con trỏ của kiểu Node rồi (khác kiểu dữ liệu mà). Nên compile báo lỗi cho bạn để bạn biết đường mà tránh.
Bạn để ý cú pháp Node * p nhé. Nó có nghĩa là con trỏ kiểu Node. Khi bạn &(con trỏ p) thì nó thành Node **p đâu thể giống với Node *p được.

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

Vậy là chưa hiểu rồi. Địa chỉ của *p (nếu p hợp lệ) có giá trị là p, hay &(*p) == p.

Quân viết 17:25 ngày 01/10/2018

hình như phát biểu của bạn có chút vấn đề, bạn review lại và sửa lại nhé [quote=“rogp10, post:8, topic:66034”]
Địa chỉ của *p (nếu p hợp lệ) chính là p, hay &(*p) = p       => Sai
[/quote]

Nguyễn Phú Thành viết 17:20 ngày 01/10/2018

con trỏ cấp 1 thì ko thể nào gán địa chỉ 1 con trỏ khác đc
đọc sao ghi vậy int *a con trỏ chứa địa chỉ 1 biến int
con trỏ cấp 2 int **a (dấu * thứ 1) con trỏ này cần đc gán địa chỉ của 1 biến con trỏ(dấu * thứ 2) rồi mới gán cho 1 biến int bình thường

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

Mình cảm ơn các bạn nhiều

Bài liên quan
0