#arrays #c #initialization
#массивы #c #инициализация
Вопрос:
Я использую memset
для заполнения массива всеми нулями, но я думаю memset
, что он работает неправильно (когда я отлаживаю его в компиляторе, он не заполняет его всеми нулями (IDK ПОЧЕМУ?)).
Когда я использую, например B[n] = { 0 }
, я получаю сообщение об ошибке:
variable-sized object may not be initialized
Код:
#include <stdio.h>
int main()
{
int m, n;
scanf("%d%d", amp;m, amp;n);
int A[m][n];
int B[n];
int redici = 0, koloni = 0, vkupno = 0;
//memset(B, 0, n);
B[n] = { 0 };
int popolnetaR[m], popolnetaK[n];
memset(popolnetaR, 0, m - 1);
memset(popolnetaK, 0, n - 1);
return 0;
}
Ответ №1:
Прежде всего, не используйте объявление таблицы с переменным размером int A[m][n]
, потому что его поведение не указано в каждой ситуации — я настоятельно рекомендую вам прочитать это сообщение в блоге. В C99 это было разрешено, но поскольку C11 это не является частью стандарта, это необязательная функция.
Чтобы решить вашу проблему, memset принимает Number of bytes to be set to the value.
в качестве третьего num
аргумента. Итак, вы не хотите использовать
memset(B, 0, n);
но
memset(B, 0, n * sizeof(int));
Ошибка, которую вы получаете, в основном говорит о том, что этот «трюк» с ={0}
работает только с массивами постоянного размера.
Комментарии:
1. Re » потому что это не в языковом стандарте «, вы уверены в этом? В документе, на который вы ссылались, очень четко указано, что они являются частью стандарта C99. /// Говоря, все, что это говорит о том, что у вас может закончиться место в стеке, если вы его используете. Ну, то же самое можно сказать и о вызове функции, особенно рекурсивных. Вы не видите, чтобы мы избегали их, не так ли? Небольшие VLA неплохие. Но да, большие могут вызвать у вас проблемы.
2. Прежде всего, не используйте объявление таблицы с переменным размером, используя int A[m][n] , потому что в стандарте языка это не совсем неправильно . Я буду откровенен: если вы не можете правильно использовать VLAS, вам все равно не следует писать код на C. И как вы планируете динамически выделять 2-мерный массив переменного размера без VLAS? (Нет, массив указателей на несколько одномерных массивов не является 2-мерным массивом)
3. AFAIK нет, «alloca() зависит от компьютера и компилятора; его использование не рекомендуется». <- от man alloca . Блог посвящен возможным ловушкам при использовании VLA в C99.
4. Я добавил небольшое редактирование, чтобы уточнить, что я имел в виду 🙂
5. Это то, что написал этот блоггер: «ВЛАс путается в моей мысленной картине происходящего, потому что объявление переменной зависит от выполняемого кода». Этому блоггеру лучше никогда не использовать что-то подобное
realloc()
. И это: «Я склонен помещать все объявления переменных в начало функций. Это может быть пережитком времен C89, но для меня это также облегчает понимание того, что происходит в стеке;» Серьезно? Это какой-то авторитет на C?for ( int i = 0; i < count; i ) ...
ему трудно «понять, что происходит в стеке»?
Ответ №2:
Вот несколько объяснений:
B[n] = { 0 };
это синтаксическая ошибкаint B[n] = { 0 };
это нарушение ограничений, какB
и массив переменной длины, а стандарт C указывает, что VLAS не может иметь инициализатора.memset(B, 0, n);
устанавливает толькоn
байты0
, которые не охватывают весь диапазон массиваB
. Вместо этого вы должны написать:memset(B, 0, sizeof(*B) * n);
Или просто:
memset(B, 0, sizeof B);
- то же замечание относится и к
popolnetaR
andpopolnetaK
.
Вот модифицированная версия:
#include <stdio.h>
int main() {
int m, n;
if (scanf("%d%d", amp;m, amp;n) != 0 || m <= 0 || n <= 0)
return 1;
int A[m][n];
int B[n];
int popolnetaR[m], popolnetaK[n];
int redici = 0, koloni = 0, vkupno = 0;
memset(A, 0, size A);
memset(B, 0, size B);
memset(popolnetaR, 0, sizeof popolnetaR);
memset(popolnetaK, 0, sizeof popolnetaK);
// ...
return 0;
}
Однако обратите внимание, что выделение слишком большого пространства при автоматическом хранении может привести к переполнению стека, что произойдет при умеренно больших значениях m
и / или n
.
Комментарии:
1. Большое вам спасибо за объяснение. Я очень ценю!