Để mở rộng một chút về một số câu trả lời ở đây ...Trong C, khi một định danh mảng xuất hiện trong một ngữ cảnh không phải là toán hạng cho & hoặc sizeof, loại định danh được chuyển đổi hoàn toàn từ "phần tử N thành phần của T" thành "con trỏ đến T", và giá trị của nó được đặt ngầm định đến địa chỉ của phần tử đầu tiên trong mảng (giống như địa chỉ của chính mảng đó). Đó là lý do tại sao khi bạn chỉ chuyển định danh mảng làm đối số cho một hàm, hàm nhận một con trỏ tới kiểu cơ sở, chứ không phải là một mảng. Vì bạn không thể biết được một mảng lớn như thế nào chỉ bằng cách nhìn vào con trỏ đến phần tử đầu tiên, bạn phải chuyển kích thước thành một tham số riêng biệt.
struct Coordinate { int x; int y; };
void SomeMethod(struct Coordinate *coordinates, size_t numCoordinates)
{
...
coordinates[i].x = ...;
coordinates[i].y = ...;
...
}
int main (void)
{
struct Coordinate coordinates[10];
...
SomeMethod (coordinates, sizeof coordinates/sizeof *coordinates);
...
}
Có một số cách thay thế để chuyển mảng vào chức năng.
Có một điều như một con trỏ đến một mảng của T, như trái ngược với một con trỏ tới T. Bạn sẽ khai báo một con trỏ như
T (*p)[N];
Trong trường hợp này, p là một con trỏ đến một Mảng phần tử N của T (ngược với T * p [N], trong đó p là mảng phần tử N của con trỏ tới T). Vì vậy, bạn có thể vượt qua một con trỏ đến mảng như trái ngược với một con trỏ đến phần tử đầu tiên:
struct Coordinate { int x; int y };
void SomeMethod(struct Coordinate (*coordinates)[10])
{
...
(*coordinates)[i].x = ...;
(*coordinates)[i].y = ...;
...
}
int main(void)
{
struct Coordinate coordinates[10];
...
SomeMethod(&coordinates);
...
}
Những bất lợi của phương pháp này là kích thước mảng là cố định, vì một con trỏ đến một mảng 10 phần tử của T là một loại khác nhau từ một con trỏ đến một mảng 20 phần tử của T.
một phương pháp thứ ba là để bọc mảng trong một cấu trúc:
struct Coordinate { int x; int y; };
struct CoordinateWrapper { struct Coordinate coordinates[10]; };
void SomeMethod(struct CoordinateWrapper wrapper)
{
...
wrapper.coordinates[i].x = ...;
wrapper.coordinates[i].y = ...;
...
}
int main(void)
{
struct CoordinateWrapper wrapper;
...
SomeMethod(wrapper);
...
}
Ưu điểm của phương pháp này là bạn không mút xung quanh với con trỏ. Điểm bất lợi là kích thước mảng được cố định (một lần nữa, một mảng 10 phần tử của T là một kiểu khác với một mảng 20 phần tử của T).
sử dụng bộ nhớ (mảng, 0, mảng sizeof); thay vì cho() chu kỳ bên trong thiết lập lại :) – rodi
@rodi: Đó là một điểm thú vị, xem xét rằng bạn đã giới thiệu một lỗi :) Tôi đã cập nhật mã để sử dụng 'memset' vì nó nên được sử dụng:' memset (array, 0, size * sizeof * array) '-' sizeof (mảng) 'trong trường hợp này là kích thước của một con trỏ * *, không phải là dữ liệu nhọn. –
Thực hành tốt ** không ** loại bỏ giá trị trả về của malloc. xem [ở đây] (https: // stackoverflow.com/questions/605845/do-i-cast-the-kết quả-of-malloc) – Aka