Определение параметров массивов в языке С
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.217.58] |
|
|
Определение параметров массивов в языке С
|
|
|
|
|
1. В книге Харбисона и Стила "Язык С с примерами" (2011 года, стр. 162) указывается, что запись функции вида:
void getArray(int nstr, int ncol, int a[nstr][ncol]) {...} является корректным. Я не очень понял, как тогда нужно объявлять массив "a" в основной программе для правильного вызова функции. 2. В книге по C, по-моему, Шилда указано, что в функциях можно использовать локальные массивы конструкции: ![]() ![]() void getArray(int nstr, int ncol) { int a[nstr][ncol]; } Ошибки ![]() ![]() error C2057: требуется константное выражение error C2466: невозможно выделить память для массива постоянного нулевого размера error C2057: требуется константное выражение error C2466: невозможно выделить память для массива постоянного нулевого размера error C2087: a: отсутствует индекс Прикреплённый файл My_ConsConly.zip (2.21 Кбайт, скачиваний: 135)
|
|
Сообщ.
#2
,
|
|
|
|
Цитата tumanovalex @ Или ты не так понял, или выкинь книгу. При объявлении массива nrow и ncol должны быть константами. 2. В книге по C, по-моему, Шилда указано, что в функциях можно использовать локальные массивы конструкции: |
|
Сообщ.
#3
,
|
|
|
|
В Стандарте C99 разрешаются локальные в функциях массивы с неконстанстными размерами. В Стандарте C++ такого нет за ненадобностью. Но по-любому массивы в параметрах функций сводятся к указателям. Оно является коррекным в любой ревизии C/C++, но будет игнорироваться.
|
|
Сообщ.
#4
,
|
|
|
|
Цитата Adil @ Цитата tumanovalex @ Или ты не так понял, или выкинь книгу. При объявлении массива nrow и ncol должны быть константами.2. В книге по C, по-моему, Шилда указано, что в функциях можно использовать локальные массивы конструкции: В С++. В С - можно и не константами(в C99). Кстати, новый же стандарт C++ хотели привести в соответствие с C99 |
|
Сообщ.
#5
,
|
|
|
|
Цитата D_KEY @ C99 так и не стал основным стандартом C. Все еще существуют компиляторы не поддерживаюшие этот стандарт, и это считается нормальным.Кстати, новый же стандарт C++ хотели привести в соответствие с C99 Учитывая, что в C++ и массивы C89 с константным размером считаются плохим тоном, то становится понятным, почему в стандарт C++ не стали вводить массивы с неизвестным на момент компиляции размером. Тем более, что у C99 и C++ и так хватает несоответствий. Вдобавок подобная таким массивам конструкция, реализованная средствами C++, практически не отличается результатом компиляции. |
|
Сообщ.
#6
,
|
|
|
|
Цитата amk @ C99 так и не стал основным стандартом C А уже вышел C11... |
|
Сообщ.
#7
,
|
|
|
|
Цитата amk @ Вдобавок подобная таким массивам конструкция, реализованная средствами C++, практически не отличается результатом компиляции. Это какая же? Разве что извращаться через placement new. |
|
Сообщ.
#8
,
|
|
|
|
Зачем? std::vector<> на что?
|
|
Сообщ.
#9
,
|
|
|
|
Цитата Qraizer @ Зачем? std::vector<> на что? std::vector<> работает с динамической памятью. Можно, конечно, заставить его работать со стэком, но это уже извращение. ИМХО. |
|
Сообщ.
#10
,
|
|
|
|
Ну и что? Контракты те же.
|
|
Сообщ.
#11
,
|
|
|
|
Цитата Qraizer @ Ну и что? Контракты те же. "Контракты" даже лучше у вектора Тут же работа со стэком и ключевая особенность variable-length массивов именно в этом.Разговор изначально вообще-то о С был. Но я так и не понял, почему в новом стандарте С++ все-таки отказались от обещанной совместимости с C99? |
|
Сообщ.
#12
,
|
|
|
|
Цитата tumanovalex @ 1. В книге Харбисона и Стила "Язык С с примерами" (2011 года, стр. 162) указывается, что запись функции вида: void getArray(int nstr, int ncol, int a[nstr][ncol]) {...} является корректным. Я не очень понял, как тогда нужно объявлять массив "a" в основной программе для правильного вызова функции. 2. В книге по C, по-моему, Шилда указано, что в функциях можно использовать локальные массивы конструкции: ![]() ![]() void getArray(int nstr, int ncol) { int a[nstr][ncol]; } Ошибки Может быть я неправильно понял изложенное в этих книгах? Прикрепляю проект, который компилировал и как С++, и как С. 1. В книге Харбисона и Стила "Язык С с примерами" (2011 года, стр. 162) указывается, что запись функции вида: void getArray(int nstr, int ncol, int a[nstr][ncol]) {...} является корректным. Я не очень понял, как тогда нужно объявлять массив "a" в основной программе для правильного вызова функции. 2. В книге по C, по-моему, Шилда указано, что в функциях можно использовать локальные массивы конструкции: ![]() ![]() void getArray(int nstr, int ncol) { int a[nstr][ncol]; } Ошибки Может быть я неправильно понял изложенное в этих книгах? Прикрепляю проект, который компилировал и как С++, и как С. Первый ваш вопрос. Для вызова функции getArray нужно в первых двух параметрах указать размеррности массива, передаваемого в качестве третьего аргумента. Например, ![]() ![]() int main( void ) { int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; getArray( 2, 3, a ); } Второй ваш вопрос. ваш компилятор выдает сообщения об ошибке, так как он, скорей всего, просто не поддерживает стандарт языка С99. Если вы программируете на С, то вам очевидно нужно использовать компилятор, который поддерживает стандарт С99. |
|
Сообщ.
#13
,
|
|
|
|
Цитата D_KEY @ Да ну? А я всегда считал, что это не цель, а средство её достижения. А целью является "локальность" выделяемой памяти. Когда-то этим занималась _alloca(), и такие массивы являются результатом её стандартизации. Тут же работа со стэком и ключевая особенность variable-length массивов именно в этом. |
|
Сообщ.
#14
,
|
|
|
|
Цитата Qraizer @ Цитата D_KEY @ Да ну? А я всегда считал, что это не цель, а средство её достижения. А целью является "локальность" выделяемой памяти.Тут же работа со стэком и ключевая особенность variable-length массивов именно в этом. Я одного не понял, с чем ты спорил? Стэк == локальная память. |
|
Сообщ.
#15
,
|
|
|
|
С тем, что std::vector<> якобы не является заменой. Является. Поэтому эта C99-фича в Плюсах не нужна.
|
|
Сообщ.
#16
,
|
|
|
|
Цитата Qraizer @ С тем, что std::vector<> якобы не является заменой. Является. Поэтому эта C99-фича в Плюсах не нужна. Она нужна в плюсах исключительно для совместимости с C99. Добавлено Цитата Qraizer @ С тем, что std::vector<> якобы не является заменой. Является. Не совсем. Одно из свойств "локальной" памяти - более быстрая работа и локальный контекст распределения(т.е. нас не волнуют вопросы распределения и освобождения, проблемы многопоточной среды и т.п.). Вектор же не работает с автоматической памятью, он просто автоматически освобождает динамическую. |
|
Сообщ.
#17
,
|
|
|
|
Цитата Вектор же не работает с автоматической памятью, он просто автоматически освобождает динамическую. А мы vector<int, pool_allocator_or_whatever<int>> возмём, и он тоже будет работать с локальной памятью. Не на стеке, конечно, но от этого суть дела не меняется. Добавлено Цитата catr @ А мы vector<int, pool_allocator_or_whatever<int>> возмём, и он тоже будет работать с локальной памятью. Не на стеке, конечно, но от этого суть дела не меняется. Причём это будет даже лучше размещения массива на стеке, так как переполнение стека черевато крахом программы, а нехватка памяти в пуле может привести всего-лишь к исключению. |
|
Сообщ.
#18
,
|
|
|
|
Цитата catr @ Цитата Вектор же не работает с автоматической памятью, он просто автоматически освобождает динамическую. А мы vector<int, pool_allocator_or_whatever<int>> возмём, и он тоже будет работать с локальной памятью. Не на стеке, конечно, но от этого суть дела не меняется. Добавлено Цитата catr @ А мы vector<int, pool_allocator_or_whatever<int>> возмём, и он тоже будет работать с локальной памятью. Не на стеке, конечно, но от этого суть дела не меняется. Причём это будет даже лучше размещения массива на стеке, так как переполнение стека черевато крахом программы, а нехватка памяти в пуле может привести всего-лишь к исключению. Так с этим-то никто не спорит. |