如果我必须在单个数组中表示整数和字符,那么在 C 中执行此操作的可接受方法是什么?



我可以声明一个int数组,然后用字符初始化它吗?我试图在每次移动后打印出游戏的状态,因此最初数组将充满字符,然后每次移动都会将一个条目更新为int。

我认为答案是肯定的,这是允许的,并且会起作用,因为int是32位,char是8位。我假设每个字符在内存中会相互偏移24位,因为数组中第n+1个位置的地址将是n+32位,并且字符只使用前8位。

这不是一个家庭作业问题,只是我在做家庭作业时出现的问题。也许我完全错了,它甚至不会按照我设置的方式编译?

编辑:根据这篇文章的标题,我没有在一个数组中表示它们。我想不出更简单的方法了。

您还可以创建一个并集数组,其中每个元素都是char或int的并集。这样一来,您就可以避免必须进行某种类型转换来将一个元素视为另一个元素,也不必担心东西的大小。

intchar是数字类型,char保证小于int(因此,在预期int的情况下提供char是安全的),所以简而言之,是的,您可以做到这一点。

是的,因为char可以隐式转换为int

"我认为答案是肯定的,这是允许的,而且会起作用,因为int是32位,char是8位。"这是错误的,int并不总是32位。此外,sizeof(char)是1,但不一定是8比特。

如前所述,char是兼容int的类型。

根据您的解释,您最初可能会从一个int数组开始,该数组的值为char,然后随着游戏的进行,char值将不再相关,而变为int值。对

IMHO问题不在于将char放入int中,这是有效的,并且内置于语言中。

IMHO使用并集来允许同一块空间用于存储任何一种类型,这有帮助,但并不重要。除非你使用的是一个非常小的微控制器,否则节省空间可能并不重要。

我能理解为什么你可能想让写棋盘变得容易,但我认为这只是写游戏的一小部分,最好在游戏的其余部分保持简单,而不是专注于前几行代码。

让我们想想这个节目;考虑一下如何印制电路板。

一开始可能是:

for (int i=0; i<states; ++i) {
    printf("%c ", game_state[i]);
}

然后,随着游戏的进行,其中一些值将为int

需要考虑的问题是"打印‘单元格’中的值需要哪种格式?"。%c格式打印一个字符。我想您希望看到int值以不同于普通打印字符的方式打印?例如,您想将int值视为整数,即十进制(或十六进制)数字字符串?这需要"%d"格式。

在我的Mac上,我这样做了:

#include <stdio.h>
#define MAX_STATE (90)
int main (int argc, const char * argv[]) {
    int game_state[MAX_STATE];
    int state;
    int states;
    for (states=0; states<MAX_STATE; ++states) {
        game_state[states] = states+256+32;
    }
    for (int i=0; i<states; ++i) {
        printf("%c ", game_state[i]);
    }
    return 0;
}

表达式states+256+32保证输出字符代码不是ASCII,甚至不是ISO-8859-1,并且它们不是控制代码。它们只是整数。输出为:

  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [  ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y 

当值为初始字符(%c格式)时,我认为您希望打印原始字符(无数据转换),但您确实希望看到数据转换,从二进制数字到数字字符串(%d或相对格式)。对

那么程序将如何判断哪个是哪个呢?

您可以确保int值不是字符(就像我的程序所做的那样)。通常,这会成为一种痛苦,因为你受到价值观的限制,最终在其他地方使用有趣的表达方式,只是为了让这项工作更容易。

我认为更容易使用一个标志,上面写着"值仍然是char"或"值是int"

使用并集节省的空间很少是值得的,它们对拥有初始状态和当前移动是有利的。

所以我认为你最终会得到这样的东西:

#include <stdio.h>
#define MAX_STATE (90)
int main (int argc, const char * argv[]) {
    struct GAME { int cell_state; int move; char start_value } game_state[MAX_STATE];
    enum CELL_STATE_ENUM { start_cell, move_cell };
    int state;
    int states;
    for (states=0; (state=getchar())!= EOF && states<MAX_STATE; ++states) {
        game_state[states].start_value = state;
        game_state[states].cell_state = start_cell;
    }
    // should be some error checking ...
    // ... make some moves ... this is nonsense but shows an idea
    for (int i=0; i<states; ++i ) {
        if (can_make_move(i)) {
            game_state[states].cell_state = move_cell;
            game_state[states].move = new_move(i);
        }
    }
    // print the board 
    for (int i=0; i<states; ++i) {
        if (game_state[i].cell_state == start_cell) {
        printf("'%c' ", game_state[i].start_value);
        } else if (game_state[i].cell_state == move_cell) {
            printf("%d ", game_state[i].move);
        } else {
            fprintf(stderr, "Error, the state of the cell is broken ...n");
        }
    }
    return 0;
}

移动可以是任何方便的值,没有什么可以使程序的其余部分复杂化的。

通过使用stdint.h标头中的int8_tuint8_t,您的意图可以更加明确。通过这种方式,您可以说"我正在使用一个八位整数,我希望它是一个数字。"

这是可能的,而且非常简单。这里有一个例子:

int main()
{
    // int array initialized with chars
    int arr[5] = {'A', 'B', 'C', 'D', 'E'};
    int i; // loop counter
    for (i = 0; i < 5; i++) {
        printf("Element %d id %d/%cn", i, arr[i], arr[i]);
    }
    return 0;
}

输出为:

Element 0 is 65/A
Element 1 is 66/B
Element 2 is 67/C
Element 3 is 68/D
Element 4 is 69/E

最新更新