Несовместимые типы перечислений в C - PullRequest
1 голос
/ 30 сентября 2011

У меня есть вопрос о перечислениях и массивах.По сути, у меня есть массив перечислений "BIT", объявленных как тип перечисления "word".

typedef enum {
ZERO = (uint8_t) 0, ONE = (uint8_t) 1
} BIT;

typedef BIT word[16];

Как мне объяснили, "word" - это просто предопределенный массив из 16 битов.Однако, когда я пытаюсь присвоить объявленному слову, я просто получаю сообщение об ошибке, в котором говорится, что слово несовместимого типа и BIT.

BIT ten = ZERO;
word Bob;
Bob[10] = ten;

Могу ли я записать слово Bob только с другим словом, я бы подумал, поскольку«слово» - это массив «битов», которые я мог бы просто присвоить биту позиции в массиве «слово».

Ответы [ 2 ]

0 голосов
/ 30 сентября 2011

Контекст

В одну версию вопроса включен код:

Исходный файл logic.c

#include "logic.h"
void word_not(word *R, word *A)
{
    for (int i = 0; i<16; i++)
    {
        if ((A+i))
            {*(R+i) = ZERO;}
        else
            {*(R+i) = ONE; }
    }
}

заголовочный файл logic.h

#ifndef LOGIC_H_
#define LOGIC_H_

#include <stdint.h>

/**
 * Basic element of the LC-3 machine.
 *
 * BIT takes on values ZER0 (0) or ONE (1)
 */
typedef enum {
ZERO = (uint8_t) 0, ONE = (uint8_t) 1
} BIT;

/**
* A 16-"BIT" LC-3 word in big-endian format
*/
typedef BIT word[16];

void word_not(word *R, word *A);

#endif

Объяснение проблемы

Проблема в том, что аргументы word_not() являются указателями на массивы. Обозначения внутри должны быть соответствующим образом скорректированы:

void word_not(word *R, word *A)
{
    for (int i = 0; i < 16; i++)
    {
        if ((*A)[i])
            (*R)[i] = ZERO;
        else
            (*R)[i] = ONE;
    }
}

Хотя вы могли бы написать это более кратко, как:

void word_not(word *R, word *A)
{
    for (int i = 0; i < 16; i++)
        (*R)[i] = !(*A)[i];
}

Кроме того, вы можете просто переопределить функцию следующим образом:

void word_not(word R, word A)
{
    for (int i = 0; i < 16; i++)
    {
        if (A[i])
            R[i] = ZERO;
        else
            R[i] = ONE;
    }
}

Или, опять же, более кратко, как:

void word_not(word R, word A)
{
    for (int i = 0; i < 16; i++)
        R[i] = !A[i];
}

Компилируемый тестовый пример - вывод

0: 1 1 1 1
1: 0 0 0 0
0: 1 1 1 1
1: 0 0 0 0
1: 0 0 0 0
0: 1 1 1 1
1: 0 0 0 0
0: 1 1 1 1
0: 1 1 1 1
0: 1 1 1 1
1: 0 0 0 0
1: 0 0 0 0
1: 0 0 0 0
1: 0 0 0 0
0: 1 1 1 1
0: 1 1 1 1
sizeof(BIT) = 4; sizeof(word) = 64

Компилируемый тестовый пример - источник

#include "logic.h"

void word_not_1(word *R, word *A)
{
    for (int i = 0; i < 16; i++)
    {
        if ((*A)[i])
            (*R)[i] = ZERO;
        else
            (*R)[i] = ONE;
    }
}

void word_not_2(word *R, word *A)
{
    for (int i = 0; i < 16; i++)
        (*R)[i] = !(*A)[i];
}

void word_not_3(word R, word A)
{
    for (int i = 0; i < 16; i++)
    {
        if (A[i])
            R[i] = ZERO;
        else
            R[i] = ONE;
    }
}

void word_not_4(word R, word A)
{
    for (int i = 0; i < 16; i++)
        R[i] = !A[i];
}

#include <stdio.h>

int main(void)
{
    word in =
    {
        ZERO,  ONE, ZERO, ONE,
        ONE,  ZERO, ONE,  ZERO,
        ZERO, ZERO, ONE,  ONE,
        ONE,  ONE,  ZERO, ZERO,
    };
    word out1;
    word out2;
    word out3;
    word out4;

    word_not_1(&out1, &in);
    word_not_2(&out2, &in);
    word_not_3(out3, in);
    word_not_4(out4, in);

    for (int i = 0; i < 16; i++)
        printf("%d: %d %d %d %d\n", in[i], out1[i], out2[i], out3[i], out3[i]);

    printf("sizeof(BIT) = %zu; sizeof(word) = %zu\n", sizeof(BIT), sizeof(word));
    return 0;
}
0 голосов
/ 30 сентября 2011

Мне кажется, проблема в том, что вы пытаетесь выполнить назначение Bob[10] = ten; вне области действия, в области действия файла.Вы не можете сделать это.В области видимости файла вы не можете свободно индексировать вещи и не можете инициализировать переменные чем-либо, кроме константных значений, десять не является одним из них.

Теперь я немного неясен, почемуниже не хочет компилировать (используя gcc 3.4.4 и Open Watcom 1.9):

typedef enum {
ZERO = 0, ONE = 1
} BIT;

typedef BIT word[16];

const BIT ten = ZERO;

word Bob =
{
  ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
  ZERO, ZERO, ten, ZERO, ZERO, ZERO, ZERO, ZERO
};

int Bob2[] =
{
  ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO,
  ZERO, ZERO, ten, ZERO, ZERO, ZERO, ZERO, ZERO
};

int main(int argc, char** argv)
{
  return 0;
}

Оба компилятора говорят, что Bob [10] и Bob2 [10] не инициализируются с константами.

...