C - различать 0 и \0 в целочисленном массиве

Возможный дубликат:
нулевое завершение массива int

Я пытаюсь распечатать все элементы массива:

int numbers[100] = {10, 9, 0, 3, 4};
printArray(numbers); 

используя эту функцию:

void printArray(int array[]) {
    int i=0;
    while(array[i]!='\0') {
        printf("%d ", array[i]);
        i++;
    }
    printf("\n");
}

проблема в том, что, конечно, C не делает различий между еще одним нулевым элементом в массиве и концом массива, после которого все это 0 (также обозначается как \0).

Я знаю, что грамматически нет разницы между 0 и \0, поэтому я искал способ или хак для достижения этого:

10 9 0 3 4

вместо этого

10 9

Массив также может выглядеть так: {0, 0, 0, 0}, поэтому, конечно, вывод должен быть 0 0 0 0.

Любые идеи?


person Gal    schedule 30.11.2010    source источник
comment
спасибо, я увидел это и проголосовал за закрытие, я получил за это небольшой хак.   -  person Gal    schedule 01.12.2010
comment
Как правило, используйте '\0' в контексте символа, чтобы сослаться на нуль, и используйте 0 в контексте целого числа. Они почти одинаково обрабатываются компилятором, но имеют разное значение для программиста, читающего ваш код. Когда я вижу код, сравнивающий int i с '\0', у меня в голове появляются предупреждения. Как и присваивание *str = 0 вместо *str = '\0'.   -  person tomlogic    schedule 01.12.2010


Ответы (3)


Не завершайте массив значением, которое также может быть в массиве.

Вам нужно найти терминатор UNIQUE.

Поскольку вы не указали никаких отрицательных чисел в своем массиве, я рекомендую завершить с помощью -1:

int numbers[100] = {10, 9, 0, 3, 4, -1};

Если это не сработает, рассмотрите: INT_MAX или INT_MIN.

В крайнем случае закодируйте последовательность значений, которые гарантированно не будут в вашем массиве, например: -1, -2, -3, что указывает на завершение.

Нет ничего «особенного» в завершении с помощью 0 или \0. Завершите с тем, что работает для вашего случая.


Если ваш массив действительно может содержать ВСЕ значения в ЛЮБОМ порядке, то терминатор невозможен, и вам придется отслеживать длину массива.

Из вашего примера это будет выглядеть так:

int numbers[100] = {10, 9, 0, 3, 4};
int Count = 5;
int i;

for(i=0; i<Count; ++i)
{
    // do something with numbers[i]
}
person abelenky    schedule 30.11.2010
comment
Я думаю, что INT_MIN и INT_MAX - это имена макросов, которые вам нужны. - person dreamlax; 01.12.2010
comment
Массив также может содержать отрицательные числа. - person Gal; 01.12.2010
comment
Тогда рассмотрите другие темы, которые я предложил. Будет ли массив когда-либо содержать INT_MAX (вероятно, 2 147 483 647) или INT_MIN (–2 147 483 648)? Что представляют собой эти данные, и есть ли значение, которое можно найти только в конце? - person abelenky; 01.12.2010

Типичные способы реализации этого:

  • определить дозорное значение (которое предложили другие)
  • определите структуру с int (фактическое значение) и bool (указывает, является ли это дозорным) и вместо этого создайте массив из них
  • передать длину массива с помощью массива
  • определите структуру, содержащую как массив, так и длину, и передайте ее вместо этого

Обратите внимание, что первый и второй элементы почти идентичны.

person Gabe    schedule 30.11.2010

Для массива, объявленного как

int numbers[100] = {10, 9, 0, 3, 4};

абсолютно невозможно отличить явное 0 в инициализаторе от неявных нулей, используемых для инициализации хвостовой части массива. Это те же нули. Итак, то, что вы хотите сделать, не может быть сделано буквально.

Единственный способ сделать это — выбрать некоторое значение int в качестве зарезервированного выделенного значения терминатора и всегда явно добавлять его в конец массива. т.е. если вы выберете -42 в качестве значения терминатора, вам придется объявить его как

int numbers[100] = {10, 9, 0, 3, 4, -42};

и повторите до первого -42 в ваших циклах.

person AnT    schedule 30.11.2010