Đối với sự hiểu biết sự khác biệt, chúng ta cần phải hiểu hai ngữ cảnh khác nhau.
- Trong giá trị bối cảnh, tên của một loạt các loại
T
là tương đương với một con trỏ để gõ T
, và tương đương với một con trỏ đến phần tử đầu tiên của mảng.
- Trong các đối tượng đối tượng, tên của một loại kiểu
T
không giảm xuống con trỏ.
Ngữ cảnh đối tượng là gì?
Trong a = b;
, a
nằm trong ngữ cảnh đối tượng. Khi bạn lấy địa chỉ của một biến, nó được sử dụng trong ngữ cảnh đối tượng. Cuối cùng, khi bạn sử dụng toán tử sizeof
trên một biến, nó được sử dụng trong ngữ cảnh đối tượng. Trong tất cả các trường hợp khác, một biến được sử dụng trong ngữ cảnh giá trị.
Bây giờ chúng ta có kiến thức này, khi chúng ta làm:
void f(int arr[4]);
Đó là chính xác tương đương với
void f(int *arr);
Như bạn phát hiện ra, chúng ta có thể bỏ qua các kích thước (4 ở trên) từ khai báo hàm. Điều này có nghĩa là bạn không thể biết kích thước của "mảng" được chuyển đến f()
.Sau đó, khi bạn làm:
int a[]={1,2,3,4};
f(a);
Trong cuộc gọi chức năng, tên a
là trong bối cảnh giá trị, vì vậy nó làm giảm đến một con trỏ đến int
. Điều này là tốt, bởi vì f
mong đợi một con trỏ đến một int
, do đó, định nghĩa chức năng và sử dụng phù hợp. Những gì được chuyển đến f()
là con trỏ đến phần tử đầu tiên của a
(&a[0]
).
Trong trường hợp của
int a[]={1,2,3,4};
int b[4] = a;
Tên b
được sử dụng trong một bối cảnh đối tượng, và không làm giảm tới một con trỏ. (Ngẫu nhiên, a
đây là trong bối cảnh giá trị, và giảm đến một con trỏ.)
Bây giờ, int b[4];
gán giá trị lưu trữ của 4 int
s và cung cấp cho các tên b
với nó. a
cũng được chỉ định bộ nhớ tương tự. Vì vậy, trên thực tế, nhiệm vụ trên có nghĩa là "Tôi muốn đặt vị trí lưu trữ giống như vị trí trước đó". Điều này không có ý nghĩa.
Nếu bạn muốn bản sao nội dung của a
vào b
, sau đó bạn có thể làm:
#include <string.h>
int b[4];
memcpy(b, a, sizeof b);
Hoặc, nếu bạn muốn có một con trỏ b
mà chỉ vào a
:
int *b = a;
Tại đây, a
có ngữ cảnh giá trị và giảm xuống con trỏ thành int
, vì vậy chúng tôi có thể gán a
cho an int *
.
Cuối cùng, khi khởi tạo một mảng, bạn có thể gán cho nó giá trị rõ ràng:
int a[] = {1, 2, 3, 4};
Ở đây, một đã 4 yếu tố, khởi tạo 1, 2, 3 và 4. Bạn cũng có thể làm :
int a[4] = {1, 2, 3, 4};
Nếu có ít yếu tố trong danh sách hơn số phần tử trong mảng, sau đó phần còn lại của các giá trị được đưa đến là 0:
int a[4] = {1, 2};
bộ a[2]
và a[3]
để 0.
Tiêu đề của câu hỏi cần phải được viết lại, tên hiện tại quá chung chung và chữ thường. –