2015-11-03 22 views
10

Trong một chương trình c bình thường/C++ chúng ta viết hàm main là một trong haiSự khác nhau giữa con trỏ đôi và mảng các con trỏ

int main(int c, char **argv) 

hoặc

int main(int c, char *argv[]) 

Đây argv đại diện cho một loạt các con trỏ nhưng chúng tôi thậm chí đại diện con trỏ kép (con trỏ đến con trỏ) bằng cách sử dụng **.

ví dụ:

char p,*q,**r; 
q=&p; 
r=&q; 

đây r là một con trỏ đôi và không mảng của con trỏ.

Có thể giải thích sự khác biệt nào không?

+0

Tôi đã tìm thấy câu trả lời này đây [1. Câu trả lời đầu tiên] (http://stackoverflow.com/questions/18273370/the- đúng-way-to-initialize-a-năng động-con trỏ-to-a-đa chiều-mảng? answerertab = cũ nhất # tab-top) [2. Câu trả lời thứ hai] (http://stackoverflow.com/questions/16001803/pointer -to-pointer-dynamic-hai chiều-mảng? answerertab = cũ nhất # tab-top) –

Trả lời

4

Khi được sử dụng như một tham số chức năng

char a[] // compiler interpret it as pointer to char 

được tương đương với

char *a 

và tương tự, trong chữ ký main 's, char *argv[] tương đương với char **argv. Lưu ý rằng trong cả hai trường hợp char *argv[]char **argv, argv là loại char ** (không phải là một mảng con trỏ!).

Điều này cũng không đúng đối với việc kê khai

char **r; 
char *a[10]; 

Trong trường hợp này, r là loại con trỏ đến con trỏ đến char khi a là loại mảng các con trỏ để char.
Việc chuyển nhượng

r = a; // equivalent to r = &a[0] => r = &*(a + 0) => r = a 

là hợp lệ vì trong biểu thức này một lần nữa mảng kiểu a sẽ được chuyển đổi sang con trỏ đến phần tử đầu tiên của nó và do đó loại char **.

Luôn nhớ rằng các mảng và con trỏ là hai loại khác nhau. Các con trỏ và mảng tương đương có nghĩa là số học con trỏ và chỉ mục mảng là tương đương.

đọc Đề xuất:

3

argv là một đối số để mảng bị phân rã thành con trỏ và không có cách nào khác ngoài kích thước (int c) để phân biệt.

Khi một con trỏ kép và mảng con trỏ không phải là đối số, cú pháp của chúng có thể giống nhau nhưng kiểu của chúng khác nhau và do đó trình biên dịch tạo ra các loại mã khác nhau cho cả hai.

Khi biến quan tâm không phải là đối số hàm, sizeof sẽ cung cấp kích thước khác nhau cho con trỏ tới con trỏ và mảng con trỏ.

Câu hỏi có liên quan một chút: extern declaration, T* v/s T[]

+0

Tôi nghĩ rằng điều này đi xuống như o ne của các câu trả lời khó hiểu nhất được chấp nhận mà tôi đã nhìn thấy ở đây trong một thời gian công bằng! – mrtimdog

+0

@mrtimdog Cảm ơn bạn đã bình luận. Tôi mời bạn chỉnh sửa câu trả lời hoặc chỉ ra những nơi cần chỉnh sửa. –

0

Hãy nhìn! con trỏ kép thực sự lưu trữ như
này Chúng ta hãy nói

int p,*q,**r; 
p=50; 

để cho các địa chỉ của p400 (&p400) nếu chúng ta viết q=p và in q chúng tôi sẽ nhận được 400 là câu trả lời từ q đề cập đến địa chỉ của p*p sẽ hiển thị 50 làm đầu ra từ operator * là "giá trị tại địa chỉ". Bây giờ, chúng ta hãy nói q có địa chỉ 500 (&q đầu ra 500) do đó khi chúng ta làm như thế này: r=q các r chứa giá trị 500 và tiền tố r với * đó là *r đầu ra sẽ 400r ám chỉ rằng giá trị của q lưu trữ địa chỉ p là biến con trỏ.

do đó,
nếu trong một chương trình C chúng tôi chạy đoạn mã sau

int main() 
{ 
    int p,*q,**r; //assume the address of p to be 400 
       //assume the address of q to be 500 
    p=50; 
    q=p; 
    r=q; 

printf("Value of p-->%d",p); 
printf("\nValue of q-->%d",q); 
printf("\nValue at address of q \"in the address displayed above\"-->%d",*p); 
printf("\nValue of r \"which will be the address of q\"-->%d",r); 
printf("\nValue of r \"which will be the adddress of p-->%d",*r); 
printf("\nValue of r \"which will be the value of p\"-->%d",**r); 
/* 
Please change the format specifiers and replace the specifier from %d to %u in case the address value is not being displayed 
*/ 
return 0; 
} 

OUTPUT
-------
Giá trị của p -> 50
Giá trị của q -> 400
Giá trị tại địa chỉ q "trong địa chỉ được hiển thị ở trên" -> 50
Giá trị của r "sẽ là địa chỉ q" -> 500
Giá trị của r "sẽ là phần bổ sung của p "-> 400
Giá trị của r "sẽ là giá trị của p" -> 50

Thông qua ví dụ trên, tôi chỉ cố gắng giải thích việc sử dụng con trỏ kép. Có lẽ bạn có thể biết điều này Tuy nhiên tôi đã làm cho điểm sống động

Bây giờ sử dụng ví dụ trên với mảng.
Hãy xem
Mảng đã là con trỏ vì chúng có thể được đóng vai trò tham chiếu là * (a + 1) hoặc [1].
Vì vậy, con trỏ kép có thể có nghĩa là mảng con trỏ hoặc một chuỗi chuỗi theo câu hỏi của bạn. Việc sử dụng ký hiệu con trỏ kép phụ thuộc vào tình huống.
Trong câu hỏi mà bạn đã đăng ở trên _TCHAR ** argv hoặc đơn giản là char ** argv là mảng ký tự cho đầu vào bảng điều khiển luôn được chấp nhận dưới dạng luồng ký tự.
Trong java, chúng ta sử dụng một cái gì đó tương tự như public static void main (String argv [])
Điều này cho thấy rõ ràng rằng phương thức chính chấp nhận đầu vào là mảng mảng char (hoặc Strings là ít bit chung).
Hy vọng bạn đã hiểu sự khác biệt. Nếu không vui lòng bình luận. Tôi sẽ giải thích nó cho bạn.
Cảm ơn bạn

+0

Bài đăng này có vấn đề về định dạng, nghĩa là các dấu sao ('*') mà bạn đã sử dụng cho con trỏ đã được hiểu là Markdown cho in nghiêng hoặc in đậm. Đoạn đầu tiên của bạn hoàn toàn in đậm. Vui lòng chỉnh sửa bài đăng của bạn và sửa lỗi. Cách dễ nhất có lẽ là bọc tất cả các con trỏ của bạn bằng định dạng mã (ctrl-k), để mã bên trong in nghiêng và in đậm bị tắt. –

+0

Đoạn đầu tiên được cố ý giữ đậm để tập trung mọi sự chú ý vào các khái niệm cốt lõi của con trỏ kép và nói về khối mã: Mã có thể chứa vài lỗi in khi bạn chạy vì tôi chưa kiểm tra hoặc chạy mã. Tôi đã sử dụng các khái niệm của mình đúng với kiến ​​thức của mình. Về vấn đề định dạng, tôi không thấy bất kỳ sự cố nào trong khối mã –

+0

Tôi sẽ cố gắng tập trung sự chú ý của bạn vào nhận xét trong khối mã "Vui lòng thay đổi định dạng specifier và thay thế specifier từ% d thành% u trong trường hợp giá trị địa chỉ không được hiển thị " –

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