Должен ли я поместить назначение в цикл for или из него? - PullRequest
0 голосов
/ 25 сентября 2018
#include <stdio.h>
void print1(int m, int n, double (*p)[m][n]);
void print2(int m, int n, double (*p)[m][n]);
void print3(int m, int n, double (*p)[m][n]);
void print4(int m, int n, double (*p)[m][n]);
void print5(int m, int n, double (*p)[m][n]);
int main(void)
{
    double a[3][2] = {{1, 2}, {3, 4}, {5, 6}};

    print1(3, 2, &a);
    print2(3, 2, &a);
    print3(3, 2, &a);
    print4(3, 2, &a);
    print5(3, 2, &a);

    return 0;
}
void print1(int m, int n, double (*p)[m][n])
{
    double subTotal;
    subTotal = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            subTotal += (*p)[j][i];
            printf("%lf~~~", subTotal);
        }
        printf("\n");
    }
    printf("******************\n");
}
void print2(int m, int n, double (*p)[m][n])
{
    double subTotal;
    for (int i = 0, subTotal = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            subTotal += (*p)[j][i];
            printf("%lf~~~", subTotal);
        }
        printf("\n");
    }
    printf("******************\n");
}
void print3(int m, int n, double (*p)[m][n])
{
    double subTotal;
    for (int i = 0; i < n; i++) {
        subTotal = 0;
        for (int j = 0; j < m; j++) {
            subTotal += (*p)[j][i];
            printf("%lf~~~", subTotal);
        }
        printf("\n");
    }
    printf("******************\n");
}
void print4(int m, int n, double (*p)[m][n])
{
    double subTotal;
    for (int i = 0; i < n; i++) {
        for (int j = 0, subTotal = 0; j < m; j++) {
            subTotal += (*p)[j][i];
            printf("%lf~~~", subTotal);
        }
        printf("\n");
    }
    printf("******************\n");
}
void print5(int m, int n, double (*p)[m][n])
{
    double subTotal;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            subTotal = 0;
            subTotal += (*p)[j][i];
            printf("%lf~~~", subTotal);
        }
        printf("\n");
    }
    printf("******************\n");
}

Посмотрите на приведенный выше код.Я написал пять функций C: print 1 ~ print 5.

Единственная разница между ними заключается в расположении subTotal = 0

Для меня print1, print3и print5 легко понять.

Я предполагаю, что print2 - то же самое, что print1, и print4 - то же самое, что print3.

Но вывод доказывает, что я ошибаюсь.Вот вывод:

1.000000~~~4.000000~~~9.000000~~~
11.000000~~~15.000000~~~21.000000~~~
******************
0.000000~~~0.000000~~~0.000000~~~
0.000000~~~0.000000~~~0.000000~~~
******************
1.000000~~~4.000000~~~9.000000~~~
2.000000~~~6.000000~~~12.000000~~~
******************
0.000000~~~0.000000~~~0.000000~~~
0.000000~~~0.000000~~~0.000000~~~
******************
1.000000~~~3.000000~~~5.000000~~~
2.000000~~~4.000000~~~6.000000~~~
******************

Я не могу понять, почему результаты печати print2 и print4 отличаются от моих ожиданий.

Почему я понял неправильно?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

На вопрос, почему печатаются 0 для print2 и print4:
Вы используете спецификатор формата %lf для печати целого числа subtotal, локального для цикла for.Проект комитета C по printf и fprintf гласит:

7.21.6 Отформатированные функции ввода / вывода
...
Если спецификация преобразования неверна, поведениене определено Если какой-либо аргумент не является правильным типом для соответствующей спецификации преобразования, поведение не определено.

0 голосов
/ 25 сентября 2018

Здесь for(int i = 0, subTotal = 0; ... определяет две переменные в операторе init цикла.Первый - int i, а второй - int subTotal, который скрывает double subTotal в верхней части функции (оставляя его неиспользованным).

Таким образом, print2 и print4использование спецификатора формата %lf для печати целого числа, которое является неопределенным поведением.

Добавление -Wall -Wextra -Wshadow к GCC создает предупреждение для всех этих эффектов.

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