squares showing upon implicit conversion from numeric to char - arrays

I am trying to test the behavior of adding number in an array containing a string using the following code :
warning: implicit conversion from numeric to char
I do understand the error and all, but the weird thing is that I get squares for the numbers, as in the image and I don't understand what these are

If you want to mix heterogeneous input data in an array with Octave, you must use a cell array as container, that is, use braces instead of brackets to "concatenate" data:
>> a6 = {"test", 3, 5}
a6 =
{
[1,1] = test
[1,2] = 3
[1,3] = 5
}
Otherwise, as commented by Raymond Chen, Octave tries to convert some data to make homogeneous (of the same type) all of them.

Related

Can't create a 'real' type array in Verilog

I've tried creating a 'real' type value array in the following way in Icarus Verilog:
parameter width = 10;
shortreal b [width-1:0] = {0.0181,0.0487,0.1227,0.1967,0.2273,0.1967,0.1227,0.0487,0.0181};
Gives the following error:
error: Cannot assign to array b. Did you forget a word index?
I went through the icarus verilog src code error messages and the explanation to this one is "Special case: The l-value is an entire memory, or array
slice". This is, in fact, an error in l-values. Detect the
situation by noting if the index count is less than the
array dimensions (unpacked)", which I assume means that the array index size differs from the declared one [width-1:0], which isn't true if I understand.
I've also tried:
parameter width = 10;
parameter [32:0] b [width-1:0] = {0.0181,0.0487,0.1227,0.1967,0.2273,0.1967,0.1227,0.0487,0.0181};
but without any success.
Using Icarus Verilog with -g2012 flag (for SV support)
It is only legal to use so-called array concatenation if you fill the entire array. You array have 10 elements, but there are only 9 on the right hand side:
parameter width = 10;
shortreal b [width-1:0] = {0.0181,0.0487,0.1227,0.1967,0.2273,0.1967,0.1227,0.0487,0.0181,0.0181};

What is the point of cell indexing in MATLAB

The point of indexing is mainly to get the value. In MATLAB,
for a cell array, there is content indexing ({}), and thus cell indexing (()) is only for selecting a subset from the cell array, right?
Is there anything other advanced usage for it? Like using it as
a pointer and pass it to a function?
There is a heavily simplified answer. {}-indexing returns you the content, ()-indexing creates a subcell with the indexed elements. Let's take a simple example:
>> a=x(2)
a =
[2]
>> class(a)
ans =
cell
>> b=x{2}
b =
2
>> class(b)
ans =
double
Now continue with non-scalar elements. For the ()-indexing everything behaves as expected, you receive a subcell with the elements:
>> a=x(2:3)
a =
[2] [3]
The thing really special to Matlab is using {}-indexing with non-scalar indices. It returns a Comma-Separated List with all the contents. Now what is happening here:
>> b=x{2:3}
b =
2
The Comma-Separated List behaves similar to a function with two return arguments. You want only one value, only one value is assigned. The second value is lost. You can also use this to assign multiple elements to individual lists at once:
>> [a,b]=x{2:3} %old MATLAB versions require deal here
a =
2
b =
3
Now finally to a very powerful use case of comma separated lists. Assume you have some stupid function foo which requires many input arguments. In your code you could write something like:
foo(a,b,c,d,e,f)
Or, assuming you have all parameters stored in a cell:
foo(a{1},a{2},a{3},a{4},a{5},a{6})
Alternatively you can call the function using a comma separated list. Assuming a has 6 elements, this line is fully equivalent to the previous:
foo(a{:}) %The : is a short cut for 1:end, index the first to the last element
The same technique demonstrated here for input arguments can also be used for output arguments.
Regarding your final question about pointers. Matlab does not use pointers and it has no supplement for it (except handle in oop Matlab), but Matlab is very strong in optimizing the memory usage. Especially using Copy-on-write makes it unnecessary to have pointers in most cases. You typically end up with functions like
M=myMatrixOperation(M,parameter,parameter2)
Where you input your data and return it.

Arrays containing text in MATLAB

In MATLAB, when code like this is implemented:
c = ['a','b','c','d'];
you can't really do anything with the elements. To illustrate my example:
>> c
c =
abcd
and when you do c(1,1) it returns A. But for c(2,1) it returns Index exceeds matrix dimensions.
To combat this problem, is there any way I could get around it? Or perhaps a different type of array?
You need to store each string in a different row, like so:
c = ['a';'b';'c';'d'];
What you have done above is use the [], which is the string concatenation operator. What it outputs is a single string, 'abcd', stored in c(1), which is why c(2) throws an index error.
Alternatively, you could use cell arrays :
c{1} = 'a';
c{2} = 'b';

When to use the tick(') for Verilog array initialization?

Array initialization can be done with or without the ':
int a[8] = '{0,1,2,3,4,5,6,7}; // Packed
int b[8] = {0,1,2,3,4,5,6,7}; // Unpacked
Is there a correct way, assuming the array uses an un-packable type like int, string, etc.? Both ways seem to work just fine.
Full code example on EDA Playground: http://www.edaplayground.com/x/3Tc
Based on IEEE 1800-2009:
Array assignment patterns (1) have the advantage that they can be used to create assignment pattern expressions of selfdetermined type by prefixing the pattern with a type name. Furthermore, items in an assignment pattern can be replicated using syntax such as '{ n{element} }, and can be defaulted using the default: syntax. However, every element item in an array assignment pattern must be of the same type as the element type of the target array. By contrast, unpacked array concatenations (2) forbid replication, defaulting and explicit typing, but they offer the additional flexibility of composing an array value from an arbitrary mix of elements and arrays.
So:
int A3[1:3];
int A9[1:9];
A3 = '{1, 2, 3}; #legal
A9 = '{3{A3}}; #illegal
A9 = {A3, 4, 5, A3, 6}; #legal
A9 = '{9{1}}; #legal
A9 = {9{1}}; #illegal
In simple cases as you have shown there is overlap in functionality between assignment patterns and unpacked array concatenation. In fact in very early versions of SystemVerilog, they used the exact same syntax (without the '), but assignment context typing rules proved too complex to use the exact same syntax, so the ' prefix was added to distinguish the two.

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

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]);
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.

Resources