"Decay" dùng để chuyển đổi ngầm định một biểu thức từ kiểu mảng sang kiểu con trỏ. Trong hầu hết các bối cảnh, khi trình biên dịch nhìn thấy một biểu thức mảng, nó chuyển đổi loại biểu thức từ "mảng phần tử N của T" thành "con trỏ thành T" và đặt giá trị của biểu thức thành địa chỉ của phần tử đầu tiên của mảng . Các ngoại lệ cho quy tắc này là khi một mảng là toán hạng của toán tử sizeof
hoặc &
toán tử hoặc mảng là một chuỗi ký tự được sử dụng làm bộ khởi tạo trong khai báo.
Giả sử mã sau:
char a[80];
strcpy(a, "This is a test");
Biểu thức a
có kiểu "mảng 80 phần tử của char" và biểu thức "Đây là một bài kiểm tra" thuộc loại "mảng 16 phần tử của char" (trong C; trong chuỗi C ++ là các mảng của const char). Tuy nhiên, trong lệnh gọi strcpy()
, không biểu thức nào là toán hạng của sizeof
hoặc &
, do đó các kiểu của chúng được chuyển đổi hoàn toàn thành "con trỏ thành char" và các giá trị của chúng được đặt thành địa chỉ của phần tử đầu tiên trong mỗi. Những gì strcpy()
nhận được không phải là mảng, mà là con trỏ, như đã thấy trong nguyên mẫu của nó:
char *strcpy(char *dest, const char *src);
Đây không phải là điều tương tự như một con trỏ mảng. Ví dụ:
char a[80];
char *ptr_to_first_element = a;
char (*ptr_to_array)[80] = &a;
Cả hai ptr_to_first_element
và ptr_to_array
có cùng giá trị ; địa chỉ cơ sở của a. Tuy nhiên, chúng là các loại khác nhau và được xử lý khác nhau, như được hiển thị dưới đây:
a[i] == ptr_to_first_element[i] == (*ptr_to_array)[i] != *ptr_to_array[i] != ptr_to_array[i]
Hãy nhớ rằng biểu thức a[i]
được hiểu là *(a+i)
(chỉ hoạt động nếu kiểu mảng được chuyển đổi thành loại con trỏ), vì vậy cả hai a[i]
và ptr_to_first_element[i]
hoạt động như nhau. Biểu thức (*ptr_to_array)[i]
được hiểu là *(*a+i)
. Các biểu thức *ptr_to_array[i]
và ptr_to_array[i]
có thể dẫn đến cảnh báo trình biên dịch hoặc lỗi tùy thuộc vào ngữ cảnh; họ chắc chắn sẽ làm điều sai trái nếu bạn mong đợi họ đánh giá a[i]
.
sizeof a == sizeof *ptr_to_array == 80
Một lần nữa, khi một mảng là toán hạng của sizeof
nó, nó không được chuyển đổi thành kiểu con trỏ.
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
là một con trỏ đơn giản để char.
int a[10]; int b(void);
, sau đó+a
là một con trỏ int và+b
là một con trỏ hàm. Hữu ích nếu bạn muốn chuyển nó đến một mẫu chấp nhận tham chiếu.