user1291204
user1291204

Reputation: 157

If I have to represent integers and char's in a single array, what would be an acceptable way to do this in C?

Can I declare an int array, then initialize it with chars? I'm trying to print out the state of a game after each move, therefore initially the array will be full of chars, then each move an entry will be updated to an int.

I think the answer is yes, this is permitted and will work because an int is 32 bits and a char is 8 bits. I suppose that each of the chars will be offset by 24 bits in memory from each other, since the address of the n+1'th position in the array will be n+32 bits and a char will only make use of the first 8.

It's not a homework question, just something that came up while I was working on homework. Maybe I'm completely wrong and it won't even compile the way I've set everything up?

EDIT: I don't have to represent them in a single array, as per the title of this post. I just couldn't think of an easier way to do it.

Upvotes: 2

Views: 350

Answers (6)

Israel Unterman
Israel Unterman

Reputation: 13510

It's possible and very simple. Here is an example:

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/%c\n", i, arr[i], arr[i]);
    }

    return 0;
}

The output is:

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

Upvotes: 0

Your intent can be made a little more clear my using int8_t or uint8_t from the stdint.h header. This way you say "I'm using a eight bit integer, and I intend for it to be a number."

Upvotes: 0

gbulmer
gbulmer

Reputation: 4290

As explained, char is an int compatible type.

From your explanation, you might initially start with an array of int who's values are char, Then as the game progresses, the char values will no longer be relevant, and become int values. Yes?

IMHO the problem is not putting char into an int, that works and is built into the language.

IMHO using a union to allow the same piece of space to be used to store either type, helps but is not important. Unless you are using an amazingly small microcontroller, the saving in space is not likely relevant.

I can understand why you might want to make it easy to write out the board, but I think that is a tiny part of writing a game, and it is best to keep things simple for the rest of the game, rather than focus on the first few lines of code.

Let's think about the program; consider how to print the board.

At the start it could be:

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

Then as the game progresses, some of those values will be int.

The issue to consider is "which format is needed to print the value in the 'cell'?". The %c format prints a single char. I presume you would like to see the int values printed differently from ordinary printed characters? For example, you want to see the int values as integers, i.e. strings of decimal (or hex) digits? That needs a '%d' format.

On my Mac I did this:

#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;
}

The expression states+256+32 guarantees the output character codes are not ASCII, or even ISO-8859-1 and they are not control codes. They are just integers. The output is:

  ! " # $ % & ' ( ) * + , - . / 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 

I think you'd like the original character to be printed (no data conversion) when the value is the initial character (%c format), but you do want to see data conversion, from a binary number to a string of digit-characters (%d or a relative format). Yes?

So how would the program tell which is which?

You could ensure the int values are not characters (as my program did). Typically, this become a pain, because you are restricted on values, and end up using funny expressions everywhere else just to make that one job easier.

I think it is easier to use a flag which says "the value is still a char" or "the value is an int"

The small saving of space from using a union is rarely worth while, and their are advantages to having the initial state and the current move available.

So I think you end up with something like:

#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;
}

The move can be any convenient value, there is nothing to complicate the rest of the program.

Upvotes: 0

tpg2114
tpg2114

Reputation: 15110

You can also make an array of unions, where each element is a union of either char or int. That way you can avoid having to do some type-casting to treat one as the other and you don't need to worry about the sizes of things.

Upvotes: 4

Luchian Grigore
Luchian Grigore

Reputation: 258618

Yes it would work, because a char is implicitly convertible to an int.

"I think the answer is yes, this is permitted and will work because an int is 32 bits and a char is 8 bits." this is wrong, an int is not always 32 bits. Also, sizeof(char) is 1, but not necessarily 8 bits.

Upvotes: 2

Jon
Jon

Reputation: 437634

int and char are numeric types and char is guaranteed smaller than int (therefore supplying a char where an int is expected is safe), so in a nutshell yes you can do that.

Upvotes: 2

Related Questions