Почему мои результаты не совпадают с результатами урока, даже при копировании / вставке? - PullRequest
0 голосов
/ 20 января 2020

Я учусь C на этом сайте . Однако, когда я подхожу к этому уроку , я, кажется, получаю странные результаты. Сайт рекомендовал попытаться создать код, не глядя сначала на пример, поэтому я попытался ввести этот код.

#include <stdio.h>
int main()
{
    printf("The \"long\" keyword is pretty useful!\n");

    int a=5;
    long int la=5;
    long long int lla=5;
    double b=5;
    long double lb=5;
    printf("%d (as a normal int) is %d bytes big!\n", a, sizeof(a));
    printf("%d (as a long int) is %d bytes big!\n",la, sizeof(la));
    printf("%d (as a long long int) is %d bytes big!\n",lla, sizeof(lla));
    printf("%lf (as a normal double) is %d bytes big!\n",b, sizeof(b));
    printf("%lf (as a long double) is %d bytes big!\n"),lb, sizeof(lb);
}

, и я получил этот ответ

The "long" keyword is pretty useful!
5 (as a normal int) is 4 bytes big!
5 (as a long int) is 4 bytes big!
5 (as a long long int) is 0 bytes big!
5.000000 (as a normal double) is 8 bytes big!
5.000000 (as a long double) is 8 bytes big!

Это не так имеет смысл, так что в итоге я посмотрел на пример и увидел, что он не объявляет никаких чисел, только переменные. Пропустив ошибку, которую я совершил в отношении вызова переменной, когда нет заданного номера, я попытался сделать это вместо:

    int a;
    long int la;
    long long int lla;
    double b;
    long double lb;
    printf("A normal int is %d bytes big!\n", sizeof(a));
    printf("A long int is %d bytes big!\n", sizeof(la));
    printf("A long long int is %d bytes big!\n", sizeof(lla));
    printf("A normal double is %d bytes big!\n", sizeof(b));
    printf("A long double is %d bytes big!\n"), sizeof(lb);

, к которой я получаю результат:

The "long" keyword is pretty useful!
A normal int is 4 bytes big!
A long int is 4 bytes big!
A long long int is 8 bytes big!
A normal double is 8 bytes big!
A long double is 8 bytes big!

Что почти ожидаемый результат, за исключением "long int", имеет размер 4 байта, такой же размер, как обычно объявленный int, по неизвестной причине. То же самое с "длинным двойным".

В конце концов я решил просто скопировать / вставить пример, приведенный на веб-сайте, чтобы убедиться, что я ошибаюсь или нет, а именно:

    #include <stdio.h>
    int main() {
        int a;
        long b;   // equivalent to long int b;
        long long c;  // equivalent to long long int c;
        double e;
        long double f;
        printf("Size of int = %ld bytes \n", sizeof(a));
        printf("Size of long int = %ld bytes\n", sizeof(b));
        printf("Size of long long int = %ld bytes\n", sizeof(c));
        printf("Size of double = %ld bytes\n", sizeof(e));
        printf("Size of long double = %ld bytes\n", sizeof(f));

        return 0;
    }

И сайт говорит, что пример должен вернуть

Size of int = 4 bytes 
Size of long int = 8 bytes
Size of long long int = 8 bytes
Size of double = 8 bytes
Size of long double = 16 bytes

Но для меня он возвращает:

Size of int = 4 bytes
Size of long int = 4 bytes
Size of long long int = 8 bytes
Size of double = 8 bytes
Size of long double = 12 bytes

Это единственная часть, которую я не могу найти ответ, почему это не так возвращая то же, что написано на сайте.

Я не имею ни малейшего представления о том, почему он это делает, и почему моя первая попытка, по-видимому, неправильно возвращает части "sizeof" (особенно третью строку, которая возвращает это long long int имеет размер 0 байт.) Кто-нибудь знает?

Ответы [ 2 ]

4 голосов
/ 21 января 2020

Проблема в том, что вы используете неправильные форматы для печати long int и long long int. %d только для int, а не для более длинных вариантов.

Поскольку используемый вами формат неверен, вы получаете неопределенное поведение. Он неправильно печатает размер long long int, поскольку неправильно извлекает параметры, поэтому показывает 0.

    printf("%d (as a normal int) is %ld bytes big!\n", a, sizeof(a));
    printf("%ld (as a long int) is %ld bytes big!\n",la, sizeof(la));
    printf("%lld (as a long long int) is %ld bytes big!\n",lla, sizeof(lla));

См. Как печатать длинную длинную

Вы также должны использовать %zu для значений size_t, но на практике это обычно работает с %ld. Вы должны всегда проверять предупреждения компилятора. Компилятор выдаст предупреждение, если вы используете неправильный спецификатор формата. Вам необходимо убедиться, что вы включили эти предупреждения и исправили их.

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

Ваша первая попытка:

printf("%d (as a long long int) is %d bytes big!\n",lla, sizeof(lla));

имеет проблему с передачей long long int и size_t в printf (), но ваш спецификатор формата - %d, что указывает на параметры int с. Правильные спецификаторы формата: %lld (long long int) и %zu (size_t). Результатом является неопределенное поведение, и программа может сделать что-нибудь в ответ (хотя обычно она либо взламывает sh, либо печатает ерунду).

Ваша вторая попытка

printf("A long int is %d bytes big!\n", sizeof(la));

достаточно близко, чтобы исправить возникшую проблему: размеры типов данных различаются в зависимости от процессоров, компиляторов и операционных систем. Исходя из результатов, которые вы и учебник видите, я предполагаю, что вы используете MSV C на (вероятно, 64-битной) Windows, в то время как учебник использует G CC на 64-битной Linux .

Это различие является одной из причин существования оператора sizeof. Стандарт C не определяет точные размеры для базовых типов данных c, только минимумы. Компиляторам разрешено увеличивать размеры по скорости, совместимости или другим причинам.

...