Reputation: 157
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
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
Reputation: 101251
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
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
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
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
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