C Программа с побитовыми операторами работает правильно только с операторами отладки - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь решить эту задачу:

Задача: Учитывая набор S = {1, 2, 3, ... n}, найти:

  • максимальное значение a & b , которое меньше заданного целого числа k , где a и b - два целых числа из набора s .
  • максимальное значение a | b , что меньше заданного целого числа k , где a и b - два целых числа из набора s .
  • максимальное значение a ^ b , которое меньше заданного целого числа k , где a и b - два целых числа из набора s .

Формат ввода: Единственная строка содержит 2 целых числа, разделенных пробелами, n и k , соответственно.

Я написал эту C программу, чтобы попытаться ее решить.

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

void calculate_the_maximum(int n, int k) {
    int i, j = 1;
    int maxAND, maxOR, maxXOR = 0;
    int AND, OR, XOR = 0;

    for (i = 1; i <= n; i++) {
        for (j = i + 1; j <= n; j++) {
            AND = (i & j); OR = (i | j); XOR = (i ^ j);
            if (AND > maxAND && AND < k) { maxAND = AND; }
            if (OR > maxOR && OR < k) { maxOR = OR; }
            if (XOR > maxXOR && XOR < k) { maxXOR = XOR; }
        }
    }

    printf("%d\n%d\n%d", maxAND, maxOR, maxXOR);
}

int main() {
    int n, k;

    scanf("%d %d", &n, &k);
    calculate_the_maximum(n, k);

    return 0;
}

Кажется для меня, как это должно работать, к сожалению, он печатает

2
24
3

вместо моего ожидаемого

2
3
3

Еще более странно, иногда программа печатает кажущееся случайным число для maxAND, и будет выглядеть как

1910024400
24
3

Вот что: программа распечатывает то, что я ожидаю, каждый раз, когда я включаю операторы отладки. Если я добавлю это

printf("I: %d J: %d OR: %d\n", i, j, OR);
в строку 13, программа теперь выведет
I: 1 J: 2 OR: 3
I: 1 J: 3 OR: 3
I: 1 J: 4 OR: 5
I: 1 J: 5 OR: 5
I: 2 J: 3 OR: 3
I: 2 J: 4 OR: 6
I: 2 J: 5 OR: 7
I: 3 J: 4 OR: 7
I: 3 J: 5 OR: 7
I: 4 J: 5 OR: 5
2
3
3

Что именно то, чего я ожидал. Есть идеи, почему эта программа выводит только то, что я ожидаю, с включением дополнительных printf?

Ответы [ 2 ]

1 голос
/ 27 мая 2020

В вашем определении переменных

int maxAND, maxOR, maxXOR = 0;

вы инициализируете только maxXOR с помощью 0, но maxAND и maxOR остаются неинициализированными. Доступ к таким значениям позже приводит к неопределенному поведению. Это то, что вы наблюдаете.

Напишите ...

int maxAND = 0, maxOR = 0, maxXOR = 0;
int AND = 0, OR = 0, XOR = 0;

или что-то в этом роде, и он должен работать стабильно.

Обратите внимание, что вы не должны полагаться на компилятор «присвоить» неинициализированным переменным значение 0; это может случиться, может быть, если вы строите без оптимизации, но это поведение может измениться непредсказуемым образом, иногда просто путем добавления другой совершенно не связанной переменной. Доступ к неинициализированным переменным: всегда «неопределенное поведение».

1 голос
/ 27 мая 2020

Ваши max переменные не инициализируются перед запуском l oop. Это должно быть:

void calculate_the_maximum(int n, int k) {
    int i, j = 1;
    int maxAND = 0, maxOR = 0, maxXOR = 0;
    int AND, OR, XOR = 0;

    for (i = 1; i <= n; i++) {
        for (j = i + 1; j <= n; j++) {
            AND = (i & j); OR = (i | j); XOR = (i ^ j);
            if (AND > maxAND && AND < k) { maxAND = AND; }
            if (OR > maxOR && OR < k) { maxOR = OR; }
            if (XOR > maxXOR && XOR < k) { maxXOR = XOR; }
        }
    }

    printf("%d\n%d\n%d", maxAND, maxOR, maxXOR);
}
...