Hanya *
, []
, dan ()
operator memiliki makna dalam deklarasi (C ++ menambahkan &
, tapi kami tidak akan masuk ke sini).
Dalam deklarasi
int *p;
yang int
-ness dari p
ditentukan oleh jenis specifier int
, sedangkan pointer-ness p
ditentukan oleh deklarator *p
.
The tipe dari p
adalah "pointer ke int
"; tipe ini sepenuhnya ditentukan oleh kombinasi specifier tipe int
plus deklarator *p
.
Dalam deklarasi, deklarator memperkenalkan nama hal yang dideklarasikan ( p
) bersama dengan informasi tipe tambahan yang tidak diberikan oleh specifier tipe ("pointer ke"):
T v; // v is a single object of type T, for any type T
T *p; // p is a pointer to T, for any type T
T a[N]; // a is an N-element array of T, for any type T
T f(); // f is a function returning T, for any type T
Ini penting - pointer-ness, array-ness, dan function-ness ditentukan sebagai bagian dari deklarator, bukan tipe specifier 1 . Jika kamu menulis
int* a, b, c;
itu akan diuraikan sebagai
int (*a), b, c;
jadi hanya a
akan dinyatakan sebagai pointer ke int
; b
dan c
dinyatakan sebagai int
s biasa .
The *
, []
, dan ()
operator dapat dikombinasikan untuk membuat jenis sewenang-wenang kompleks:
T *a[N]; // a is an N-element array of pointers to T
T (*a)[N]; // a is a pointer to an N-element array of T
T *(*f[N])(); // f is an N-element array of pointers to functions
// returning pointer to T
T *(*(*(*f)[N])())[M] // f is a pointer to an N-element array of pointers
// to functions returning pointers to M-element
// arrays of pointers to T
Perhatikan bahwa *
,, []
dan ()
patuhi aturan prioritas yang sama dalam deklarasi yang mereka lakukan dalam ekspresi. *a[N]
diuraikan seperti *(a[N])
dalam deklarasi dan ekspresi.
Hal yang sangat penting untuk disadari dalam hal ini adalah bahwa bentuk deklarasi cocok dengan bentuk ekspresi dalam kode. Kembali ke contoh asli kami, kami memiliki pointer ke integer bernama p
. Jika kami ingin mengambil nilai integer itu, kami menggunakan *
operator untuk dereferensi p
, seperti:
x = *p;
Jenis ungkapannya *p
adalah int
, yang mengikuti dari deklarasi
int *p;
Demikian pula, jika kita memiliki array pointer double
dan kita ingin mengambil nilai tertentu, kita indeks ke dalam array dan melakukan dereferensi hasilnya:
y = *ap[i];
Sekali lagi, jenis ungkapannya *ap[i]
adalah double
, yang mengikuti dari deklarasi
double *ap[N];
Jadi mengapa tidak ++
berperan dalam deklarasi seperti *
, []
, atau ()
? Atau operator lain seperti +
atau ->
atau &&
?
Yah, pada dasarnya, karena definisi bahasa mengatakannya. Itu hanya mengesampingkan *
,, []
dan ()
untuk memainkan peran apa pun dalam deklarasi, karena Anda harus dapat menentukan jenis pointer, array, dan fungsi. Tidak ada tipe "increment-this" yang terpisah, jadi tidak perlu ++
menjadi bagian dari deklarasi. Tidak ada "bitwise-ini" jenis, sehingga tidak perlu untuk unary &
, |
, ^
, atau ~
menjadi bagian dari deklarasi baik. Untuk jenis yang menggunakan .
operator pemilihan anggota, kami menggunakan struct
dan union
tag dalam deklarasi. Untuk jenis yang menggunakan ->
operator, kami menggunakan tag struct
dan union
bersama dengan *
operator di deklarator.
- Tentu saja, Anda bisa membuat nama typedef untuk tipe pointer, array, dan fungsi
typedef int *iptr;
iptr a,b,c; // all three of a, b, and c are pointers to int
tapi sekali lagi, itu adalah deklarator *iptr
yang menentukan pointer-ness dari nama typedef.
void move(int *units) { ... }
, itu adalah operator tidak langsung. Dianggap sebagai bagian dari tipe, itu juga dapat ditulisvoid move(int* units) { ... }
, meskipun saya lebih suka gaya sebelumnya. Anda membaca keduanya sebagai "int pointer." Lihat juga stackoverflow.com/a/8911253