Trước tiên, ý của bạn là "typedef" not "typecast" trong câu hỏi của bạn.
Trong C, một con trỏ để gõ T
có thể trỏ đến một đối tượng kiểu T
:
int *pi;
int i;
pi = &i;
Trên đây là đơn giản để hiểu. Bây giờ, hãy làm cho nó phức tạp hơn một chút. Bạn dường như biết sự khác biệt giữa các mảng và con trỏ (tức là, bạn biết rằng các mảng không phải là con trỏ, mặc dù chúng hoạt động giống như chúng). Vì vậy, bạn sẽ có thể hiểu:
int a[3];
int *pa = a;
Nhưng cho đầy đủ vì: trong chuyển nhượng, tên a
tương đương với &a[0]
, ví dụ: một con trỏ đến phần tử đầu tiên của mảng a
. Nếu bạn không chắc chắn về cách thức và lý do tại sao các công trình này, có rất nhiều câu trả lời giải thích chính xác khi nào tên của một mảng "phân rã" tới con trỏ và khi nó không:
Tôi chắc chắn có nhiều câu hỏi và câu trả lời như vậy trên SO, tôi vừa đề cập đến một số câu hỏi mà tôi tìm thấy từ tìm kiếm.
Back to the topic: khi chúng ta có:
int foo[2][4];
foo
là loại "mảng [2]
của mảng [3]
của int
". Điều này có nghĩa là foo[0]
là một mảng gồm 3 int
s và foo[1]
là một mảng gồm 3 int
s.
Bây giờ, giả sử chúng tôi muốn khai báo một con trỏ và chúng tôi muốn gán con trỏ đó cho foo[0]
. Đó là, chúng tôi muốn làm:
/* declare p somehow */
p = foo[0];
Trên đây là không có khác nhau ở dạng vào dòng int *pa = a;
, bởi vì các loại a
và foo[0]
đều giống nhau. Vì vậy, chúng tôi cần int *p;
làm tuyên bố của chúng tôi về p
.
Bây giờ, điều chính cần nhớ về mảng là "quy tắc" về tên mảng phân rã thành con trỏ đến phần tử đầu tiên chỉ áp dụng một lần. Nếu bạn có một mảng của một mảng, sau đó trong bối cảnh giá trị, tên của mảng sẽ không phân rã thành loại "con trỏ trỏ tới con trỏ", mà là "con trỏ tới mảng". Trở lại với foo
:
/* What should be the type of q? */
q = foo;
Tên foo
trên là một con trỏ đến phần tử đầu tiên của foo
, ví dụ, chúng ta có thể viết ở trên như:
q = &foo[0];
Loại foo[0]
là "mảng [3]
của int
".Vì vậy, chúng ta cần q
là một con trỏ đến một "mảng [3]
của int
":
int (*q)[3];
Dấu ngoặc xung quanh q
là cần thiết vì []
liên kết chặt chẽ hơn *
trong C, vì vậy int *q[3]
tuyên bố q
như một mảng của con trỏ, và chúng tôi muốn một con trỏ đến một mảng. int *(q[3])
là, từ trên, tương đương với int *q[3]
, tức là một mảng gồm 3 con trỏ đến int
.
Hy vọng điều đó sẽ hữu ích. Bạn cũng nên đọc C for smarties: arrays and pointers để có hướng dẫn thực sự tốt về chủ đề này.
Giới thiệu về khai báo đọc nói chung: bạn đọc chúng "từ trong ra ngoài", bắt đầu bằng tên của "biến" (nếu có). Bạn đi càng xa càng tốt trừ khi có []
ở ngay bên phải và bạn luôn luôn tôn trọng dấu ngoặc đơn. cdecl
sẽ có thể giúp bạn đến một mức độ nào đó:
$ cdecl
cdecl> declare p as pointer to array 3 of int
int (*p)[3]
cdecl> explain int (*p)[3]
declare p as pointer to array 3 of int
Để đọc
int (*a)[3];
a # "a is"
(*) # parentheses, so precedence changes.
# "a pointer to"
[3] # "an array [3] of"
int ; # "int".
Đối
int *a[3];
a # "a is"
[3] # "an array [3] of"
* # can't go right, so go left.
# "pointer to"
int ; # "int".
Đối
char *(*(*a[])())()
a # "a is"
[] # "an array of"
* # "pointer to"
( )() # "function taking unspecified number of parameters"
(* ) # "and returning a pointer to"
() # "function"
char * # "returning pointer to char"
(Ví dụ từ c-faq question 1.21 Trong practi. ce, nếu bạn đang đọc một tuyên bố phức tạp như vậy, có điều gì đó nghiêm trọng sai với mã!)
Bạn có thể quan tâm đến việc đọc http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html. – sand
Chỉ một phần rất nhỏ của liên kết được cung cấp có liên quan đến câu hỏi ban đầu của tôi đã được trả lời chi tiết bằng các câu trả lời bên dưới. Cảm ơn câu trả lời của bạn anyway !! – fotNelton
Xem thêm [Khai báo kiểu đọc C] (http://unixwiz.net/techtips/reading-cdecl.html), [Đọc bản Tuyên bố C: Hướng dẫn cho Bí ẩn] (http://www.ericgiguere.com/articles /reading-c-declarations.html). – outis