Почему я получаю неверную ошибку инициализатора? - PullRequest
2 голосов
/ 09 ноября 2019

Я относительно новичок в C и пытаюсь написать простой код, который проверяет, является ли год високосным или нет. Это мой код:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int year;
    printf("%s","Please enter a year: ");
    scanf("%d",&year);
    char leapYear[] = ((year % 4) == 0) ? ((year / 100 % 4)==0 ? "y": "n"):"n" ;
    printf("%s", leapYear);

}

Я получаю неверную ошибку инициализатора и не знаю почему.

Ответы [ 2 ]

4 голосов
/ 09 ноября 2019

В этом выражении

((year % 4) == 0) ? ((year / 100 % 4)==0 ? "y": "n"):"n"

строковые литералы преобразуются в указатели на их первые элементы, и вы не можете инициализировать массив символов указателями.

Чтобы сделать его более понятным, рассмотримследующая демонстрационная программа

#include <stdio.h>

int main(void) 
{
    char s1[] = "y";
    char s2[] = "y" + 0;
}

Первое объявление массива

    char s1[] = "y";

будет успешно скомпилировано. Для инициализации массива используется строковый литерал.

Второе объявление массива

    char s2[] = "y" + 0;

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

Используйте вместо этого следующий подход

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    int year;
    printf("%s","Please enter a year: ");
    scanf("%d",&year);
    char leapYear[2];
    strcpy( leapYear, ( (year % 4 ) == 0) ? ((year / 100 % 4)==0 ? "y": "n"):"n" );
    printf("%s", leapYear);
}

И, как Пол Огилви написал в комментарии вместо массива, вы можете определить указатель наподобие

const char *leapYear = ((year % 4) == 0) ? ((year / 100 % 4)==0 ? "y": "n"):"n" ;
0 голосов
/ 09 ноября 2019

Если размер не указан, компилятор оценивает размер c-строки по заданному выражению const string, которого нет в вашем коде (значение строки leapYear зависит от заданного условия).

Итак, вы должны предварительно установить размер массива, если вы хотите указать условия в одной строке:

char leapYear[2];
leapYear[0] = ((year % 4) == 0) ? ((year / 100 % 4) == 0 ? 'y' : 'n') : 'n' ;
leapYear[1] = '\0'; // so that you don't get garbage in your terminal

РЕДАКТИРОВАТЬ :

Iзабыл про strcpy() так вот (спасибо @Vlad):

char leapYear[2];
strcpy(leapYear, ((year % 4 ) == 0) ? ((year / 100 % 4) == 0 ? "y" : "n") : "n");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...