2011-10-03 61 views
18

Dựa trên sự hiểu biết của tôi về con trỏ đến con trỏ đến một mảng kí tự,Con trỏ trỏ tới con trỏ với argv

% ./pointer one two 

argv   
+----+   +----+ 
| . | ---> | . | ---> "./pointer\0" 
+----+   +----+ 
       | . | ---> "one\0" 
       +----+ 
       | . | ---> "two\0" 
       +----+ 

Từ mã:

int main(int argc, char **argv) { 
    printf("Value of argv[1]: %s", argv[1]); 
} 

Câu hỏi của tôi là, Tại sao là argv [1] chấp nhận được? Tại sao nó không giống như (* argv) [1]?

bước hiểu biết của tôi:

  1. Hãy argv, dereference nó.
  2. Nó sẽ trả về địa chỉ của mảng con trỏ tới ký tự.
  3. Sử dụng con trỏ arithmetics để truy cập các phần tử của mảng.
+3

+1 cho biểu đồ. :) – Mysticial

Trả lời

14

Đó là thuận tiện hơn để nghĩ về [] như một nhà điều hành cho con trỏ chứ không phải là mảng; nó được sử dụng với cả hai, nhưng kể từ khi mảng phân rã để trỏ chỉ mục mảng vẫn có ý nghĩa nếu nó nhìn theo cách này. Vì vậy, về cơ bản nó offsets, sau đó dereferences, một con trỏ.

Vì vậy, với argv[1], những gì bạn thực sự có được là *(argv + 1) được thể hiện với cú pháp thuận tiện hơn. Điều này cung cấp cho bạn số char * thứ hai trong khối bộ nhớ được chỉ định bởi argv, vì char * là loại argv trỏ đến và [1] số bù argv theo số sizeof(char *) byte rồi hủy kết quả.

(*argv)[1] sẽ dereference argv đầu tiên với * để có được con trỏ đầu tiên char, sau đó bù đắp điều đó bằng cách 1 * sizeof(char) byte, sau đó dereferences rằng để có được một char. Điều này cho biết ký tự thứ hai trong chuỗi đầu tiên của nhóm các chuỗi được chỉ ra bởi argv, mà rõ ràng không giống với argv[1].

Vì vậy, hãy suy nghĩ về biến mảng được lập chỉ mục như một con trỏ đang được vận hành bởi toán tử "bù đắp sau đó dereference một con trỏ".

+0

Vâng, tôi đã có sự nhầm lẫn về lý do tại sao chúng tôi không cần phải derefrence argv, đầu tiên nhưng nó quay ra tôi quên rằng nó bằng * (argv + n), trong đó n là chỉ số chỉ số. –

10

argv là một con trỏ đến con trỏ đến char, nó sau đó argv[1] là một con trỏ đến char. Định dạng print()%s mong đợi một con trỏ tới đối số char và in mảng ký tự null kết thúc mà đối số trỏ tới. Vì argv[1] không phải là một con trỏ rỗng, không có vấn đề gì.

(*argv)[1] cũng có giá trị C, nhưng (*argv) tương đương với argv[0] và là một con trỏ đến char, vì vậy (*argv)[1] là nhân vật thứ hai của argv[0], đó là / trong ví dụ của bạn.

4

Lập chỉ mục một con trỏ dưới dạng một mảng ẩn hoàn toàn. p[0]*p, p[1]*(p + 1) vv

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