значение null int в VC ++ - PullRequest
1 голос
/ 15 июля 2010

Я хочу, чтобы в моей программе было условие, которое определяет, есть ли в массиве значение NO. Обычно массив будет храниться с 4 значениями. В редких случаях он заполняется 6. Я хочу использовать оператор if, который говорит, что если exampleArray [5] не равен нулю, сделайте это

Что-то вроде ...

например. если (массив [5] -> Равно (NULL) { // Делаем вещи }

Проблема в том, что я не могу использовать 0, потому что есть большая вероятность, что int будет 0, и я не хочу, чтобы в этом случае выполнялся код (// делать вещи) Основы программы вращаются вокруг двумерного массива, и очень распространенное местоположение содержит 0 int

когда я читаю в сети, я обнаружил, что 0 является нулем для целого числа.

Как найти ноль без 0?

Ответы [ 7 ]

5 голосов
/ 15 июля 2010

Вместо использования массива вы можете использовать std::vector, который имеет метод size().Это делает написание условия if тривиальным.

1 голос
/ 15 июля 2010

Да, значения сигналов могут быть сложными. В NULL нет ничего особенного, когда вы говорите о не указателе. Столь же трудно найти дату, которая означает «нет даты», или строку, которая означает «нет строки», но не является пустой строкой. Вот почему использование значений сигналов редко встречается за пределами программирования баз данных, где популярность положительных целых чисел для идентификаторов и ключей делает -1 удобным значением сигнала.

Я вижу, что у вас есть три варианта. Во-первых, хранить указатели в вашем массиве. Нулевой указатель сильно отличается от указателя на целое число со значением ноль. Но это приводит к накладным расходам (удваивает объем памяти, который вам нужен) и может испортить вам голову или головы других. Во-вторых, используйте свой собственный класс для представления этой вещи, и пусть один член класса удерживает, есть ли 4 или 6 или любые другие значения, и используйте этот член в ваших операторах if. В-третьих, используйте легкодоступный контейнер растёт сам при добавлении одного, например std::vector, и используйте его свойства (например, size()) в своих операторах if. Это имеет тот недостаток, что вам нужно будет переписать код, который обращается к элементам массива. Поэтому я бы проголосовал за дверь № 2.

1 голос
/ 15 июля 2010

Что вы можете сделать, это вместо того, чтобы хранить целые числа напрямую, вы можете создать небольшой класс, в котором хранится целое число и флаг инициализации. Поэтому, когда объект создан, он не инициализирован. Когда он назначен, он инициализируется значением. Это был бы лучший способ, вы могли бы также просто заполнить массив некоторым значением, которое, черт возьми, вы точно не найдете, например, static const int NOT_INITIALIZED = -99999999 или что-то в этом роде, и протестировать его.

0 голосов
/ 15 июля 2010

Фундаментальная проблема заключается в том, что C ++ не имеет нулевого значения. Есть нулевые значения указателя, но это не одно и то же. В строке также есть нулевое окончание, но опять же это нечто иное.

Нет способа указать нулевое значение в целом, которое бы работало для C ++, учитывая его философию дизайна. Либо нулевое значение должно быть каким-то недопустимым значением, либо должен быть какой-то внешний флаг - иными словами, избыточная память, на которую нужно ссылаться, чтобы использовать переменную. Ни один из них не подходит для языка низкого уровня, который требует эффективности.

Будет больше возможных значений указателя, чем сам процесс может использовать сам, поэтому, как правило, нет необходимости требовать указанного неверного значения. Это не должно быть все биты ноль, хотя это самый распространенный случай; ноль - это просто имя указателя. (Да, я с нетерпением жду nullptr.) Точно так же кодировки текста не используют весь возможный диапазон значений для символов, поэтому резервирование одного для чего-то определенно не символа работает достаточно хорошо. Это не относится к числам или любому другому виду данных, в которых все значения действительны.

0 голосов
/ 15 июля 2010

OK.Первое, что я хочу пояснить здесь, это то, что массивы C ++ не имеют длины. Они могут иметь выделенный размер, но нет никакого способа программно выяснить, что этоявляется.По определению каждый элемент в массиве C ++ имеет значение.Это может быть мусором (если вы его еще не инициализировали), но он есть и доступен.Черт возьми, вы даже можете получить доступ к элементам вне вашего массива.Ваша ОС может остановить вас, но C ++ не остановит.

Если вы хотите, чтобы массивы имели логический размер (которые отслеживают объем данных «в» них), у вас естьтри реальных варианта:

  • Сделайте это сами со значением часового. Выберите какое-то значение, которое никогда не будет законно появляться в вашем массиве, и используйте его для обозначения «конца данных».Если вы сделаете это, вы должны быть осторожны, чтобы объявить (или выделить) массив, достаточно большой, чтобы вместить все данные, которые вы когда-либо захотите, плюс еще одно место для стража .Вы также должны быть очень осторожны, чтобы не забыть держать дозорного в курсе, иначе вы получите множество аварий.Вычисление длины требует обхода всего массива, поэтому он может быть медленным (если вы ничего не испортили, и он вообще прекратится).Это подход, принятый C-строками.
  • Сделайте это самостоятельно с отдельной переменной длины. Это будет прекрасно работать, если вы не забудете сохранить длину в актуальном состоянии.Если вы испортите это, вы, скорее всего, просто получите тонкие ошибки, а не впечатляющие сбои, но у этого есть свои недостатки.Кроме того, вы должны передать всю длину массива всем подпрограммам.Однако самая большая проблема заключается в том, что C ++ в значительной степени сделает это за вас, если вы воспользуетесь приведенным ниже методом, поэтому написание всего дополнительного кода для выполнения этого вручную довольно глупо.
  • Использовать std::vector вместотупой массив. Это дает вам все преимущества массива и все преимущества контейнера без всякой работы по отслеживанию логических и выделенных длин.Он даже перераспределит массив для вас, если вам не хватит места!Единственным реальным недостатком здесь является то, что, поскольку он очень похож на массив, легко забыть, что для изменения его логического размера нужно использовать такие подпрограммы, как .push_back() и .pop_back().
0 голосов
/ 15 июля 2010

Говоря о массиве с 4 или 5 элементами, я предполагаю, что у вас нет проблем с размером памяти. Почему бы не зарезервировать одно место в массиве для счетчика? Это было бы чем-то вроде решения "Вектор бедняка". В идеале можно использовать местоположение 0 в массиве для счетчика, но если у вас много кода, который верит в индексы, начинающиеся с 0, вы можете поместить свой счетчик на противоположном конце, скажем, в месте 6 или 7. Этот элемент массив будет содержать количество элементов, содержащихся в массиве.

Объявление «неинициализированного» значения и поиск в массиве для него возможно, но довольно неэлегатное решение. С одной стороны, цикл и поиск обходятся дольше, чем просто просмотр одного значения.

В идеале, этот счетчик даже не должен быть в вашем массиве; он должен быть в отдельной переменной (мы снова приближаемся к классу Vector, предложенному другими). Но помещение его в массив, вероятно, приведет к более простым изменениям. Просто обратите внимание на возможность сохранения в массиве значений, превышающих ожидаемые, и растоптывания по вашему счетчику!

0 голосов
/ 15 июля 2010

У вас есть несколько вариантов.

Вы можете хранить 'int *' в массиве (делая сам массив int**).Это приводит к дополнительным накладным расходам на необходимость дополнительного управления памятью, но позволяет однозначно хранить NULL.Я не предлагаю этого.

Лучше было бы вырвать STL.std::vector было бы идеально, я думаю.Вы можете изменить его размер динамически вместо того, чтобы хранить значения часового (или NULL).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...