невозможно инициализировать массив в c | предупреждение: преобразование в long без знака из long - PullRequest
2 голосов
/ 26 января 2020

Я пытаюсь написать программу, которая начинает с создания двумерного массива, который будет представлять график (обратите внимание, что размеры графика будут заданы в качестве входных данных).

Я хочу инициализировать этот массив в 0 и после поиска в Google я обнаружил, что вы должны сделать это с помощью memset (), потому что память для массива будет динамически выделяться из входного файла.

Ниже приведена небольшая часть моей программы, поэтому far:

long int N;

int main(int argc, char *argv[]) {
    long int i;

    FILE * txt;
    txt = fopen(argv[1], "r");
    if (txt == NULL) {
        printf("There was an error trying to open the file.\n");
        return 0;
    }

    fscanf(txt, "%li", &N);

    long int graph[N][N];
    memset(graph, 0, N*N*sizeof(long int));

    return 1;
}

Когда я компилирую его с помощью g cc -Wconversion, я получаю следующее предупреждение:

предупреждение: преобразование в 'long unsigned int' из 'long int' может изменить знак результата [-Wsign-преобразование] memset (graph, 0, N * N * sizeof (long int));

Я не могу понять в в какой точке кода компилятор пытается преобразовать long int в unsigned. Я искал его, и у людей была та же самая проблема, только когда у них были смешанные переменные разных типов.

Любая помощь будет оценена!

--- EDIT ---

С помощью с помощью «Влада из Москвы» мне удалось решить вышеупомянутое предупреждение (мне пришлось изменить N на тип size_t, чтобы правильно вызвать memset ()), но теперь я хочу инициализировать еще один длинный массив int в LONG_MAX, и я получаю другой:

memset(dist, LONG_MAX, N*sizeof(long int));

предупреждение: переполнение при неявном преобразовании констант [-Woverflow]

Ответы [ 2 ]

1 голос
/ 26 января 2020

Функция memset ожидает третий аргумент типа size_t. Поэтому объявите переменную N как

size_t N;

и напишите

fscanf(txt, "%zu", &N);

Второе предупреждение связано со вторым аргументом вызова memset

memset(dist, LONG_MAX, N*sizeof(long int));

который ожидает его типа int, который внутри функции преобразуется в тип unsigned char.

Вот описание функции.

void *memset(void *s, int c, size_t n);

Обычно единственное применение функции заключается в инициализации массива с нуля.

0 голосов
/ 26 января 2020

size_t может интерпретироваться как unsigned int или как unsigned long int; зависит от машины.

Нет необходимости использовать memset () для заполнения массива нулями, вы можете передать этот материал компилятору. Просто назначьте 0 первому элементу, а компилятор назначит 0 всем неинициализированным элементам!

long int graph[N][N] = {0};

Вы пытаетесь использовать memset () в неправильном месте! memset () устанавливает хранилище в «байтовом порядке».

void * memset (s, c, n) -> помещает символ c в первые n символов s, возвращает s

обратите внимание, что c является символом, а не целым числом.

Итак, как инициализировать массив с помощью LONG_MAX?

Использование al oop:

 for(long i = 0; i < N; ++i)
   dist[i] = LONG_MAX;
...