01/10/2018, 17:29

Lỗi khi khởi tạo mảng 1 chiều

Chào các bạn, mình mới học về mảng trong C, và mình muốn làm như sau:

int n; scanf("%d",&n);
int array[n] = {0};  // bị báo lỗi

Các bạn có thể giải thích giùm mình tại sao không làm như vậy được k? và cách giải quyết khi mình muốn kích thước mảng là 1 biến có thể thay đổi khi hàm gọi tới. Xin cảm ơn

rogp10 viết 19:42 ngày 01/10/2018

Cái này là optional. malloc thôi.

Anh viết 19:42 ngày 01/10/2018

Mảng trong stack không khởi tạo động theo kiểu đấy được, nếu muốn sử dụng mảng động thì phải cấp phát động bằng malloc với C hoặc là sử dụng new với C++.

int n;
scanf("%d", &n);
int* array = new int[n];

à mà nhớ dùng ngoặc vuông [n] nhé, đừng dùng ngoặc tròn không là sai đấy. Hàm malloc thì lâu m không dùng nên không nhớ cách dùng nên k ghi vào, có gì b tìm hiểu thêm về phần cấp phát động sẽ rõ hơn

NBQ viết 19:41 ngày 01/10/2018

Từ C99 thì đã cho phép bạn có thể khai báo mảng với kích thước thay đổi, nhưng ở đây bạn lai muốn khởi tạo tất cả các phần tử của mảng có kích thước thay đổi bằng 0 thì không được phép.
Bạn có thể khai báo thế này:

int n; scanf("%d",&n);
int array[n];  // chỉ khai báo mà không khởi tạo giá trị các phần tử là 0
memset(array, 0, n); //khởi tạo giá trị 0 cho tất cả các phần tử của mảng.
Anh viết 19:30 ngày 01/10/2018

b code trên nền tảng nào thế b??? Theo lý thuyết thì biến được cấp phát trong stack thì sẽ không thể cấp phát động được, do trong stack sử dụng địa chỉ tương đối để truy cập tới các biến cục bộ, nếu biến nào mà kích thước động như thế này thì vị trí của các biến trong stack sẽ bị loạn hết.
m cũng vừa thử code theo code của b trên visual studio 13 nhưng vẫn bị báo lỗi. b có thể nói rõ phần này hơn đc k?

Anh viết 19:44 ngày 01/10/2018

m vừa tìm hiểu thêm trên mạng thì thấy hình như là kiểu code này chỉ hỗ trợ cho g++, còn theo chuẩn c++ thì không cho phép, k biết có đúng k? mong b giải thích thêm

NBQ viết 19:34 ngày 01/10/2018

Mình thử trên đây: https://www.onlinegdb.com/online_c_compiler (hình như là dùng gcc) và codeblock đều được (mingw).
Trên Visual Studio là Visual C++ nó đặt rule theo chuẩn riêng của Microsoft nên nó báo lỗi cũng không có gì lạ, mình chỉ dùng Visual Studio để code C++ chứ không dùng để code C.

Bạn tham khảo:
https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

en.wikipedia.org

Variable-length array

In computer programming, a variable-length array (VLA), also called variable-sized, runtime-sized, is an array data structure whose length is determined at run time (instead of at compile time). In C, the VLA is said to have a variably modified type that depends on a value (cf. dependent type). The main purpose of VLAs is to simplify programming of numerical algorithms. Programming languages that support VLAs include Ada, Algol 68 (for non-flexible rows), APL, C99 (although subsequently relegat...

Anh viết 19:29 ngày 01/10/2018

Tks b. Nhưng m có một thắc mắc là khi khai báo array[n] như vậy thì mảng đó có được cấp phát ở trong stack hay không? Hay là nó sẽ thành như một hàm new mới và thứ lưu trong stack chỉ là con trỏ tới mảng array? Bởi vì theo mình biết thì việc lưu trữ các biến local trong stack trên nền tảng windows thường sẽ phải khởi tạo cố định bởi vì các biến local này sử dụng địa chỉ tương đối so với stack base address nên rất khó để có thể tạo một mảng động trong stack được.

NBQ viết 19:44 ngày 01/10/2018

Ở đây bạn ấy tag câu hỏi ở tag C nên mình chỉ bàn về standard dành cho C thôi.
PS: g++ cũng chỉ là một trong các compiler hỗ trợ build code C++ chứ nó không phải là một chuẩn.

NBQ viết 19:39 ngày 01/10/2018

Một biến được khai báo là biến local thì sẽ được cấp phát trong stack. Cơ chế lưu trữ các biến local như bạn nói thì mình không biết, chắc phải tìm hiểu thêm.
Bạn có thể viết một chương trình để test lại theo ý tưởng của bạn.

Anh viết 19:41 ngày 01/10/2018

ok tks bạn nhiều, để m tìm hiểu thêm về phần này

rogp10 viết 19:43 ngày 01/10/2018

malloc với C hoặc là sử dụng new với C++

Đây là hai ngôn ngữ khác nhau nhé

no name viết 19:33 ngày 01/10/2018

Thanks các bạn đã trả lời giúp mình, vấn đề trên có lẽ mình sẽ phải dùng malloc. Mình học C# và code trên VS 2017 nhưng khi học giải thuật thầy giáo có code giải thuật bằng C++. Mình vẫn dùng VS 2017 để làm lại nhưng muốn sử dụng style C chứ không muốn code theo y chang như vậy giống cách học chính tả (mình không thích)

Bài liên quan
0