2013-07-14 72 views
7

Tôi biết điều này rất cơ bản nhưng hơi khó hiểu với tôi.
Tôi đã đọc:Sự khác biệt giữa con trỏ và biến con trỏ là gì?

một con trỏ là gì khác hơn là một địa chỉ , và một biến con trỏ chỉ là một biến thể cửa hàng một địa chỉ.
Khi chúng tôi lưu trữ địa chỉ của biến số i trong biến con trỏ p, chúng tôi nói rằng ptrỏ đếni.

int i, *p = &i; 

p điểm để i.

Để truy cập vào đối tượng mà con trỏ trỏ tới, chúng tôi sử dụng toán tử * (không gián đoạn).

Nếu plà một con trỏ sau đó *p đại diện cho đối tượng mà p hiện chỉ.

Bây giờ tôi bối rối rằng những gì tôi nên gọi p - con trỏ biến hoặc con trỏ?

Bổ sung: Con trỏ có luôn giống với địa chỉ không?

+1

đọc ["Điều gì" dereferencing "có nghĩa là con trỏ?"] (Http://stackoverflow.com/questions/4955198/what-does-dereferencing-a-pointer-mean) có thể hữu ích và tất nhiên là từ wiki: ["Con trỏ (lập trình máy tính)"] (http://en.wikipedia.org/wiki/Pointer_ (computer_programming)) –

+1

@GrijeshChauhan; Tôi đã đọc liên kết đầu tiên trước khi hỏi câu hỏi này :). Cảm ơn bạn đã liên kết thứ hai. – haccks

+0

@GrijeshChauhan; Cảm ơn bạn đã liên kết wiki. Nó giải thích dereferencing một cách rất đẹp (thực sự nó đã được câu hỏi tiếp theo của tôi nếu bạn không cung cấp liên kết :)). – haccks

Trả lời

5

Sự khác biệt giữa một giá trị con trỏ và một biến con trỏ được minh họa bằng:

int swap_int(int *i1, int *i2) 
{ 
    int t = *i1; 
    *i1 = *i2; 
    *i2 = t; 
} 

int main(void) 
{ 
    int v1 = 0; 
    int v2 = 37; 
    int *p2 = &v2; 
    printf("v1 = %d, v2 = %d\n", v1, v2); 
    swap_int(&v1, p2); 
    printf("v1 = %d, v2 = %d\n", v1, v2); 
    return 0; 
} 

Ở đây, p2 là một biến con trỏ; nó là một con trỏ đến int. Mặt khác, trong cuộc gọi đến swap_int(), đối số &v1 là giá trị con trỏ, nhưng nó không có nghĩa là một biến con trỏ (trong hàm gọi). Nó là một con trỏ tới một biến (và biến đó là v1), nhưng chỉ cần viết &v1 là không tạo ra một biến con trỏ. Bên trong hàm được gọi, giá trị của con trỏ &v1 được gán cho biến con trỏ cục bộ i1 và giá trị của biến con trỏ p2 được gán cho biến con trỏ cục bộ i2, nhưng điều đó không giống như nói rằng &v1 là một biến con trỏ (bởi vì nó không phải là một biến con trỏ, nó chỉ đơn giản là một giá trị con trỏ).

Tuy nhiên, với nhiều mục đích, sự khác biệt bị mờ. Mọi người sẽ nói 'p2 là một con trỏ' và điều đó là đủ; nó là một biến con trỏ, và giá trị của nó là một giá trị con trỏ, và *p2 là giá trị của đối tượng mà p2 trỏ tới. Bạn bị làm mờ cùng với 'v1 là một số int'; nó thực sự là biến số int và giá trị của nó là giá trị int.

+0

Và AFAIK tiêu chuẩn thậm chí không sử dụng thuật ngữ "biến" anyway. –

+0

@ H2CO3; Bạn có nghĩa là * biến con trỏ *? – haccks

+0

@haccks Không, khi tôi viết "biến", tôi có nghĩa là "biến". –

2

p là biến con trỏ trỏ đến biến số i. Chúng ta có thể gọi nó là con trỏ.

Một tuyên bố:

int* p; 
int i; 
p = &i; 

tuyên bố p như nhận diện của một đối tượng int loại. Điều này thường được tuyên bố ngắn gọn hơn là 'p is a pointer to i'. p có thể được sử dụng để tham chiếu biến int i sau biểu thức p = &i. Để truy cập giá trị của biến số i bằng cách sử dụng con trỏ p, bạn có thể sử dụng toán tử Dereference * (ví dụ: *p). Anf i = 10; tương đương với *p = 10;.

Cũng thông báo trong biểu thức p = &i; để đọc địa chỉ i Tôi đã sử dụng toán tử ký tự & còn được gọi là Address of operand.

Con trỏ chỉ là một địa chỉ hợp lý (một số nhận dạng mà một biến có thể được tham chiếu). Tiêu chuẩn C không xác định con trỏ nội bộ là gì và nó hoạt động như thế nào trong nội bộ.

Bạn muốn đọc: What exactly is a C pointer if not a memory address?
Ngoài ra, đọc: to Understand the purpose of pointers.

+0

Nhưng người ta nói rằng ** con trỏ không là gì hơn là địa chỉ ** – haccks

+0

Có. Cho tôi một chút, tôi sẽ trải qua nó. – haccks

+0

Jonathan giải thích rõ. Một lần nữa cảm ơn cho liên kết này. – haccks

0

Các thuật ngữ con trỏ và biến con trỏ thường được sử dụng đồng nghĩa.

0

Biến là nơi lưu trữ giá trị. Trong C, bất cứ khi nào bạn sử dụng biến trong ngữ cảnh cần giá trị, giá trị của biến được truy xuất, do đó, nói "p" trong ngữ cảnh đó giống như nói "giá trị của biến p":

int *q = p; // Copy the value of variable p into the variable q. 
      // aka: copy p into q. 
4

Hãy thay thế từ "con trỏ" với một kiểu dữ liệu đó là hy vọng quen thuộc hơn, giống như một int:

int n = 42; 

đây 42 là một giá trị int, và n là một biến chứa một int. Bạn có thể gọi n biến "int". Một int là một số như 42 hoặc -25315685 và biến số int giữ các số này. Một khi bạn có một biến, bạn có thể gán các số khác nhau cho nó. Không có gì khó hiểu cho đến nay?

A con trỏ giống như số int: một số. Nó sẽ xảy ra là một số xác định một vị trí bộ nhớ, và nếu một cái gì đó được lưu trữ trong vị trí bộ nhớ đó bạn có thể gọi nó là một địa chỉ . Giống như một int, một con trỏ có thể được lưu trữ trong một biến. Một biến lưu trữ một con trỏ có thể được gọi là một biến con trỏ.

Vì vậy, sự khác nhau giữa con trỏ và biến con trỏ là gì? Giá trị đầu tiên là một giá trị, giống như một số, cửa hàng thứ hai lưu các giá trị này. Nhưng mọi người thường đề cập đến các biến theo giá trị của chúng mà chúng lưu trữ; mọi người không gọi số n biến "int" nhưng chỉ int, mặc dù nó có thể vào các thời điểm khác nhau lưu trữ khác nhau int s.Trong văn bản này tôi sẽ làm như vậy và đôi khi viết con trỏ khi tôi có nghĩa là một biến con trỏ; hy vọng sự khác biệt sẽ rõ ràng.

Con trỏ có luôn là địa chỉ không? Đây là câu hỏi về ý nghĩa của từ "địa chỉ" hơn bất cứ thứ gì khác. Một con trỏ luôn luôn là một địa chỉ theo nghĩa nó tương ứng với một vị trí bộ nhớ theo cách này hay cách khác, đó là một "địa chỉ" cho vị trí bộ nhớ đó. Nhưng mặt khác, nếu vị trí bộ nhớ không thể truy cập được vào chương trình hoặc không có bất kỳ thứ gì được lưu trữ hữu ích trong đó, thì đó có phải là "địa chỉ" cho bất kỳ thứ gì không?

Bây giờ hãy điều tra đoạn mã sau:

int *p; 
p = &n; 

Dòng đầu tiên khai báo một biến con trỏ được gọi là p. Các con trỏ có thể được lưu trữ vào p là các vị trí bộ nhớ cho dữ liệu int; điều này là quan trọng vì những lý do mà chúng ta sẽ thấy sau này. Chúng tôi vẫn không cung cấp cho bất kỳ giá trị nào, vì vậy con trỏ nó lưu trữ là tùy ý. Nó chắc chắn không lưu trữ địa chỉ của bất cứ điều gì hữu ích; nó thậm chí có thể trỏ đến một khu vực bộ nhớ không thể truy cập vào chương trình.

Trong dòng thứ hai, chúng tôi lấy địa chỉ của biến số n với máy bay & và gán cho p. Hiện tại, p lưu trữ địa chỉ của n, vị trí bộ nhớ có giá trị là n được lưu trữ.

Chúng ta có thể làm gì với con trỏ? Chúng ta có thể đọc và ghi vào vị trí bộ nhớ mà con trỏ xác định. Để thực hiện điều này, chúng tôi "dereference" con trỏ với * -operator, và sau đó (*p) có thể được sử dụng giống như bạn có thể sử dụng n. Ví dụ, bạn có thể viết một giá trị mới vào n với điều này:

*p = 123; 

Đó là vào thời điểm này mà nó trở nên rõ ràng lý do tại sao chúng ta cần phải biết loại dữ liệu mà p có thể trỏ đến: nếu không bạn không thể biết những gì bạn có thể gán cho (*p).

Lý do khác khiến việc biết loại dữ liệu p có thể trỏ đến là số học con trỏ. Ví dụ: p+1 là con trỏ đến int được lưu trữ trong bộ nhớ ngay sau n; nếu p là một con trỏ trỏ đến một cấu trúc dữ liệu lớn, p+1 sẽ là một con trỏ trỏ đến một cấu trúc dữ liệu cùng loại được lưu trữ ngay sau nó. Đối với điều này trình biên dịch phải biết kích thước của những gì con trỏ trỏ đến.

+0

Cảm ơn bạn đã giải thích thêm (nhưng Tôi đã không nhận được lời giải thích của bạn hoàn toàn) +1. – haccks

+0

Bạn thấy khó theo dõi những phần nào? – Joni

+0

Phần điều tra của bạn thực sự tốt và nó giúp tôi hiểu một số điểm tốt nhưng nó không phải là câu hỏi cụ thể của tôi; ** Có phải con trỏ luôn là địa chỉ không? ** – haccks

-1

con trỏ: biến có giá trị là địa chỉ của một biến khác.

biến con trỏ: là một biến chứa vị trí hoặc địa chỉ bộ nhớ trong đó một biến, giá trị dữ liệu hoặc chức năng khác được lưu trữ.

+0

Bạn có thể đã cố gắng nói "con trỏ: địa chỉ của một biến khác". – lakesare

Các vấn đề liên quan