nul завершает массив int - PullRequest
3 голосов
/ 08 июня 2010

gcc 4.4.4 c89

Я просто экспериментировал с массивом int. И что-то только что пришло мне в голову. Могу ли я прекратить это. Например, я использую 0 для прекращения nul. Тем не менее, 0 вполне может быть допустимым значением в этом массиве.

Код ниже прекратится после 5. Даже если я имею в виду 0, чтобы быть действительным числом. Тем не менее, я мог бы указать размер массива. Но в данном случае я не хочу этого, потому что меня интересует именно эта проблема.

Большое спасибо за любой совет,

#include <stdio.h>

static void test(int *p);

int main(void)
{
    int arr[] = {30, 450, 14, 5, 0, 10, '\0'};

    test(arr);

    return 0;
}

static void test(int *p)
{
    while(*p) {
        printf("Array values [ %d ]\n", *p++);
    }
}

Ответы [ 4 ]

14 голосов
/ 08 июня 2010

Короче, нет.Технически нуль-символы одинаково действительны и в строках, это просто соглашение, что мы используем их для пометки конца строки, и все стандартные библиотечные функции ожидают этого.Существуют строки с «двойным нулевым окончанием», которые заканчиваются на \0\0 для случаев, когда строка должна содержать \0, но, конечно, у вас возникает проблема невозможности сохранить \0\0 в строке.

Если вы не хотите хранить размер массива отдельно (или использовать хитрость, например sizeof), вам нужно придумать страж, который можно хранить в этом типе, но вы знаете, что не будете частьюмассива;вы можете использовать 45, если вы уверены, что arr не будет иметь это в качестве действительного значения, оно просто должно быть уникальным

3 голосов
/ 08 июня 2010

Проще говоря, \ 0 - это то же самое, что и 0, поэтому, если в вашем массиве есть ноль, ваш код будет ошибочно принят за конец массива:

int arr[] = {30, 450, 14, 5, 0, 10, '\0'};
                             ^ this is the end of the array

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

3 голосов
/ 08 июня 2010

Чтобы использовать значение дозорного, очевидно, вы должны найти значение, которое не является действительными данными. Это один из недостатков использования часового (другой - линейный поиск, необходимый для определения длины). Как у вас работает что-то вроде 0xFFFF?

Если бы это был C ++, я бы предложил создать класс со связанным членом длины (или еще лучше, просто используя std::vector). Для C вы, вероятно, должны просто сохранить отдельную переменную длины самостоятельно. Вы можете получить фантазию и поместить его и массив в структуру, если хотите.

1 голос
/ 07 декабря 2017

Ну, вы также можете изменить свой дозорный с \0 на \\0. И, соответственно, небольшое изменение условия для цикла while поможет вам решить вашу проблему.

while(*p != '\\0')

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

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