开发者

New to programming, don't get 2D/3D arrays

开发者 https://www.devze.com 2023-01-05 02:21 出处:网络
Hey everyone, I\'m basically new to programming. I\'ve decided to try and get started with C (not C++ or C#) and so far I\'ve been doing pretty well. I managed to get far as two-dimensional arrays bef

Hey everyone, I'm basically new to programming. I've decided to try and get started with C (not C++ or C#) and so far I've been doing pretty well. I managed to get far as two-dimensional arrays before I started to falter. While I think I broadly understand 2D integer arrays, I certainly don't understand 3D string arrays.

I'm learning by taking the techniques and applying them in an actual program I've created, an exchange rate "calculator" that basically takes asks the user to select a base currency then prints its value in USD. There's no maths involved, I simply googled stuff like EUR/USD and set the values manually in the array which I discuss below.

But here's where I'm getting stuck. I figure the best way to learn multi-dimensional arrays is to practically apply the theory, so here's what I've typed so far (I've omitted the other functions of my program (including the code which calls this function) for brevity):

 char currencies[5][3][4] = {
    {'1','2','3','4','5'},
    {'GBP','EUR','JPY','CAD','AUD'},
    {'1.5','1.23','0.11','0.96','0.87'}
};

int point, symbol, value;

displayarraycontents()
{
    for(point=1;point<5;point++){
        for(symbol=1;symbol<5;symbol++){
            for(value=1;symbol<5;symbol++)
                printf("%s ", currencies[point][symbol][value]);
    开发者_C百科        printf("\n");
        }}

}

Because C doesn't feature a string data type, building string arrays completely messes with my head.

Why currencies[5][3][4]? Because I'm storing a total of 5 currencies, each marked by a 3-letter symbol (eg EUR, CAD), which have a value of up to 4 digits, including the decimal point.

I'm trying to display this list:

1 GBP 1.5

2 EUR 1.23

3 JPY 0.11

4 CAD 0.96

5 AUD 0.87

When I click build, the line where I specify the values in the array is highlighted with several instances of this warning:

warning: overflow in implicit constant conversion

...and the line where I print the contents of the array is highlighted with this warning:

warning: format '%s' expects type 'char *', but argument 2 has type 'int'

Upon running the code, the rest of the program works fine except this function, which produces a "segmentation error" or somesuch.

Could somebody give me a hand here? Any help would be greatly appreciated, as well as any links to simple C 2D/3D string array initialisation tutorials! (my two books, the K&R and Teach Yourself C only provide vague examples that aren't relevant)

Thanks in advance!

-Ryan

EDIT: updated code using struct:

struct currency {
    char symbol[4];
    float value[5];
};


void displayarraycontents(){

        int index;

        struct currency currencies[] {
            {"GBP", 1.50},
            {"EUR", 1.23},
            {"JPY", 0.11},
            {"CAD", 0.96},
            {"AUD", 0.87},};

}

I get the following errors: main.c:99: error: nested functions are disabled, use -fnested-functions to re-enable

main.c:99: error: expected '=', ',', ';', 'asm' or 'attribute' before '{' token

main.c:100: error: expected ';' before '}' token

main.c:100: error: expected expression before ',' token

In the actual code window itself, every symbol is flagged as an "unexpected token".


In this case, you don't actually want a 3D array. In fact, since you have a table of values, all you need is a 1D array.

The tricky part is that each element of the array needs to store two things: the currency symbol, and the associated exchange rate. C has a way of building a type that stores two things - it's the struct mechanism. We can define a struct to hold a single currency:

struct currency {
    char symbol[4];
    char value[5];
};

(Note that this does not create a variable; it creates a type. struct currency is analagous to char, except that we defined the meaning of the former ourselves).

...and we can now create an array of 5 of these:

struct currency currencies[5] = { 
    {"GBP", "1.5" },
    {"EUR", "1.23" },
    {"JPY", "0.11" },
    {"CAD", "0.96" },
    {"AUD", "0.87" } };

To iterate over them and print them out, the code would look like:

void displayarraycontents(void)
{
    int point;

    for(point = 0; point < 5; point++)
    {
        printf("%d %s %s\n", point + 1, currencies[point].symbol, currencies[point].value);
    }
}


You need a to correct your array dimensions, and you also need to declare your strings as strings, not as multibyte character constants:

char currencies[3][5][5] = {
    {"1","2","3","4","5"},
    {"GBP","EUR","JPY","CAD","AUD"},
    {"1.5","1.23","0.11","0.96","0.87"}
};

Your logic for the array dimensions is wrong - what you want is 3 columns, each with 5 entries, each of which is a string 5 bytes long.

Your for loop should index from 0, not from 1.


There is also a oops in for statements:

for(point=1;point<5;point++)

First item in an array is in 0 position, so for statements should be like this:

for(point=0;point<5;point++)


It would make more sense to use structs here rather than a multi-dimensional array.

#include <stdio.h>

typedef struct Currency {
   const char* symbol;
   double value;
} Currency;

Currency CURRENCIES[] = {
   {"GBP", 1.5},
   {"EUR", 1.23},
   {"JPY", 0.11},
   {"CAD", 0.96},
   {"AUD", 0.87},
};
size_t NUM_CURRENCIES = sizeof(CURRENCIES) / sizeof(Currency);

int main()
{
   size_t index;

   for (index = 0; index < NUM_CURRENCIES; index++)
   {
      printf("%zu %s %.2f\n",
         index + 1, CURRENCIES[index].symbol, CURRENCIES[index].value);
   }

   return 0;
}


It should be

char currencies[3][5][5] = {

because it contains 3 lists containing 5 strings each.

Each string has a max of 4 characters, but you need the additional NUL character, so 5 at the end.

-- EDIT

You have the array access confused. Using your array definition (fixed as above) it would be currencies[data_type][index] to get a string.

  • data_type = 0 -> the index
  • data_type = 1 -> the symbol
  • data_type = 2 -> the value

the first line

{'1','2','3','4','5'},

is redundant.

Fixed code:

 char currencies[2][5][5] = {
     {"GBP","EUR","JPY","CAD","AUD"},
     {"1.5","1.23","0.11","0.96","0.87"}
 };

 void displayarraycontents()
 {
    int index;
    for(index = 0;index < 5;index++) {
        printf("%i %s %s\n", index, currencies[0][index], currencies[1][index]);
    }
}


In C/C++ you would normally read your array dimentions from right to left to get a good idea of how the compiler will see it. In this case, you need to store strings of 4 characters each which requires storage for 5 chars (to include the trailing \0) therefore [5] will be the array size. Next you are storing groups of 5 items, therefore the middle value will be [5] and finally, you are storing a total of 3 groups of these items, therefore [3]. The final result of all of this is char currencies[3][5][5] = . . .;

Of course, as replied elsewhere, you need to use the double quotes for string values.


If you want to solve this with multi-dimensional arrays, as @Forrest says, you need [3][5][5]. Look at it this way: in the initializer, find the outermost braces: inside that, on the top level, how many elements are there? 3. Now, each of these elements (one level in), how many elements? 5. Drilling further down, inside each of those, you have a string of 4 elements, plus one for the terminator, again 5.

Second error: you can only ever have one character in single quotes, like 'a'; that's char type, and equivalent to ASCII code (97 in this case). For strings, you have to use double quotes ("abc", which is equivalent to {97, 98, 99, 0}).

Third error: loops. You are not actually iterating over all three loops while printing a string at a time (since printf will actually do one of the loops for you) - so you should only have 2 loops (or, less efficiently, you can keep all three loops, but then print only a character at a time). Also, you need to be aware of the loop limits; you are going up to 5 in each case, but this will give you runtime garbage (in the best case) or runtime crash (in the worst case) when you go out of your [3] dimension. Thus, something like this:

Then again, your innermost loop is inconsistent in your variable usage (copy-paste error).

However, there will almost never be need to write code like this. You mainly use 2D arrays for matrix operations. Something like this should only have a one-dimensional array, storing record elements.

struct currency {
    int     id;
    char[4] symbol;
    float   value;
} currencies[5];


You don't need to store the indices (1-5) as you can access the array (0-4) and thus know the indices. You can encapsulate the other values in a struct or two seperate arrays which gets your array(s) down to one dimension as it should be... In that way the items have proper types and you don't misuse two-dimensional arrays.

A 2D or 3D area shouldn't be filled with items that should be of a different type, it is needed when you have items that are of the same type and have a logic 2D or 3D structure. The pixels on your screen are a good example of something that needs a 2D structure, coordinates in a 3D graph are a good example of something that needs a 3D structure.

0

精彩评论

暂无评论...
验证码 换一张
取 消