|
If you have an two-dimensional array where each row has a differing number of elements, why not use a std::vector?
std::vector<FOO> foo2DArray[];
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
I think you meant this answer for Vaclav.
|
|
|
|
|
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
Thanks, just what the doctor ordered.
Then I can add another member to the struct if I want.
Nice and clean solution.
|
|
|
|
|
Yes, if you are using a struct you can have many different items inside it. Also, as Daniel mentions below (to me) you may want to use a std::vector rather than a simple array.
|
|
|
|
|
Here is my test code.
It is not very "dynamic" but will do for now.
I may add the "Command" as a first element in Data array to make sure they match.
Actually it would simplify things (a little ) - using just multidimensional array with first element being "Command".
But I like the struct for future....
Now I need to modify usage of Command /Data....
#define COMMAND_ARRAY 16
struct ILI9341 {
int Command; int* Data; } ILI9341Array[COMMAND_ARRAY];
int index = 0;
int dataIndex = 0;
int DefineCommand[COMMAND_ARRAY] = { 0x0, 0x1, 0x4 };
int DefineData[][10] = { { 1, 2, 3, 4 }, { 5, 6, 7 }, { 9, 10, 11, 12, 13,
14 } };
for (index = 0; index != 3; index++) {
ILI9341Array[index].Command = DefineCommand[index];
#ifdef DEBUG
cout << "ILI9341Array[" << dec << +index << "] Command 0x" << hex
<< ILI9341Array[index].Command << endl;
#endif
ILI9341Array[index].Data = DefineData[index];
#ifdef DEBUG
do {
cout << "ILI9341Array[" << dec << +index << "] Data[" << dec
<< +dataIndex << "] 0x" << hex
<< ILI9341Array[index].Data[dataIndex] << endl;
} while (ILI9341Array[index].Data[++dataIndex]);
dataIndex = 0;
#endif
}
|
|
|
|
|
That's way too much typing. Consider:
#include <iostream>
#include <iomanip>
#include <map>
#include <vector>
using namespace std;
#define DEBUG
int main()
{
map<int,vector<int>> IL9341Command = {{ {0x0, {{ 1, 2, 3, 4 }} },
{0x1, {{ 4, 6, 7, }} },
{0x4, {{ 9, 10, 11, 12, 13, 14 }} },
{0xff, {{ 44, 55, 66, 77 }} } }};
#ifdef DEBUG
for(auto iter : IL9341Command) {
cout << "IL9341Comand [ 0x" << hex << iter.first << " ] =";
for(auto cmd : iter.second)
cout << " 0x" << hex << cmd;
cout << endl;
}
int *data = IL9341Command[0xff].data();
cout << "\nCommand[0xff] data :";
for(size_t i = 0; i < IL9341Command[0xff].size(); i++)
cout << " 0x" << data[i];
cout << endl;
#endif // DEBUG
return 0;
}
You can access the command data directly if you know the key via IL941Command[key], without having to iterate through the array, and as shown above, access to the "raw data" can be gained by calling data() on the vector. If you have C++17 then you can simplify the for(auto iter ...) loop as follows
for(auto [key, data] : IL9341Command) {
cout << "IL9341Comand [ 0x" << hex << key << " ] =";
for(auto cmd : data)
cout << " 0x" << hex << cmd;
cout << endl;
}
modified 20-Jan-19 15:07pm.
|
|
|
|
|
Hmm. Not sure why the code didn't format properly within the <pre code="C++"> tags. I looked closely and there wasn't any tags in the code as posted. Also, how does one post code with preprocessor directives in column one without them turning into (h1) header lines?
Edit: the format issue with the code was because I needed to convert "<" into <.
modified 20-Jan-19 15:09pm.
|
|
|
|
|
Richard,
I finally decided to use your suggestion and having a hard time initializing the pointer in the struct.
Here is how it looks as of today
struct ILI9341 {
uint8_t index; uint8_t Command; uint8_t c_d; uint8_t *Data; char *Name; char *Function; uint32_t delay = 0; char *RefPage; char *Notes; uint8_t temp[COMMAND_ARRAY] = {}; } ILI9341_CommandList[COMMAND_ARRAY];
I did try this (C sample I found) , but that obviously does not work initializing multiple struct and I feel it defeats the pointer by making the temp array fixed length.
uint8_t temp[3] = { 0x1, 0x0, 0xFF };
ILI9341_CommandList[4].Data = temp;
|
|
|
|
|
You cannot add initialisers to the struct definition, but only to actual instances of it. So it should rather be something like:
struct ILI9341 { uint8_t index; uint8_t Command; uint8_t c_d; uint8_t *Data; char *Name; char *Function; uint32_t delay; char *RefPage; char *Notes; uint8_t* temp; } ILI9341_CommandList[COMMAND_ARRAY] =
{ { 0, 0, 0, buffer, "command name" "Function", 100, RefPage, Notes, { 0x1, 0x0, 0xFF } }, {
}
};
And you can also fill in any of the fields later in the executable code by addressing struct entries as ILI9341_CommandList[n] where n is in the range [0..COMMAND_ARRAY-1].
|
|
|
|
|
If your single element is unique, then maybe a map of vectors might be a better choice
e.g.
map<obj_a, vector<obj_b>>
There is a requirement that obj_a implement operator<() . Basically if its not a basic type (e.g. int, double, string, etc), you need to add a
bool operator<(const foo& other) const {} method to the object, which is usually straight forward.
|
|
|
|
|
Well , I realize my way is too crude for today's standards.
Yes, the "command(s)' are unique and direct access to data would be much cleaner than scanning.
But I forgot that the command is actually "top level" - the same data can be actual "command" or "data" ( to be read).
The clocking of the command (command or data) is different so I need some identifier for that.
I need to rethink the method how to accomplish that - so far plain two dimensional array with
"command" , " command or data flag " , "data" scheme looks simpler.
Minor issue is - the "data" can be 0x0 - such as "0x4, 0x0, 0x7" etc.so plain scanning won't do.
I need a break.
Later.
|
|
|
|
|
Vaclav_ wrote: PS I did try std:array , but it conflicts with "boost" - can't do for now.
I'm using both boost functinality and std::array without any problems, ever. What is the problem you are experiencing? Maybe you were too gracious with using statements and contaminating your global namespace?
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
I am writing an article on best practices and in this article I am trying to formulate an hypothesis for which public functions eventually lead to most of the code design issues. It's not public functions per se, but more about inter-objects communication (messaging).
Established that encapsulation works fine for data abstract types, how would you define the situation in which stateful objects with well defined behaviours, do not have control on their states? Let's say in the best case scenarios, I have a well defined object with well defined behaviours, like Walk() and Run() but doesn't have control on when it walks and when it runs. Other objects will control when this object walks or runs. Let's now say that this object is used in a spaghetti codebase, where the reference to this object is injected indiscriminately. The object could potentially find itself walking or running at the wrong times. What I am trying to say is that encapsulation ensures the validity of the states, but cannot determine if the states are set at the right time.
How would you define this problem? I know how to solve it, I am just trying to understand if encapsulation is involved at all in this problem. Without public functions this problem wouldn't exist in the first place, but is the possibility of settings states at the wrong time a form of broken encapsulation?
modified 19-Jan-19 14:34pm.
|
|
|
|
|
I would bet a finite state machine would allow controlling the different states and their transitions.
667: The neighbour of the Beast
|
|
|
|
|
Are you asking if you might hit a brick wall while driving your car? Yes you might. Nonetheless your car is not faulty (at least before you hit the wall).
|
|
|
|
|
The car is fine, except for one nut behind the wheel.
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
I really like this analogy and I will steal it for my article. However argument is that encapsulation eventually doesn't solve the problem its meant to solve and it's flawed. I know it's controversial, but after some research, I found out I am not the only one who got to this conclusion Object-Oriented Programming: A Disaster Story – Brian Will – Medium[^]. The controversial part is that people can argue that Encapsulation does its job (like in the case of the car), but OOP doesn't help, with its flexibility, to not break the car. If I can break the car easily, what's the point of the encapsulation to start with? Of course Encapsualtion as hiding of complexity is absolutely valid. Hence I think this problem I am trying to formalise, which is the possibility to set a valid state at the wrong time, may need another name. I will link the article here before to make it public, as I'd like your feedback.
modified 20-Jan-19 10:34am.
|
|
|
|
|
I think you intended this reply for Carlo. If I mention @CPallini here, he should be alerted.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
Peter and @CPallini, I know it's a long shot, but if you have 10 minutes to read a first draft of my article, I would like to know if it makes sense to you and in this case give me some feedback.
The Quest for Maintainable Code and The Path to ECS - Seba's Lab[^]
password: readme.
I don't want this article to be too abstract, I know that I assume that people know what ECS is (It's not an article about explaining it), but nevertheless I need to know if I face things so abstractly that is hard to see how they are applied in real life. I will gather more significant anecdotes before to publish it.
|
|
|
|
|
What you are dealing with is called reaction programming .. your object needs to react to things .. anything from collisions to just communicating when asked.
It's well described here along with the usual 3 ways to deal with it
Reactive programming - Wikipedia[^]
Now take care Object-oriented Reactive Programming is not Reactive Object-oriented Programming there is a big difference between those two you need to decide which you are doing and the difference between them.
From what you said I think what you are after is
Observer pattern - Wikipedia[^]
The Observer pattern addresses the following problems:
- A one-to-many dependency between objects should be defined without making the objects tightly coupled.
- It should be ensured that when one object changes state an open-ended number of dependent objects are updated automatically.
- It should be possible that one object can notify an open-ended number of other objects.
Now in programmer jargon speak we call observer pattern programming as "Omnipotent god programming" because there will exist an object or function that observes and controls everything. It is often used in games programming but it is not well suited to real world situations where you can't encapsulate all options and you need to "think" about what is going on.
As an example DNS attacks on websites work because they break the observer pattern of the internet standards .. to deal with the attack you need to know past history and apply some logic
In vino veritas
modified 20-Jan-19 1:05am.
|
|
|
|
|
What are the programmers' opinions about Plain English Programming?
Plain English Programming is useful?
If not, why Plain English Programming is not useful?
Reference: www.osmosian.com
Moderators, if this place is not the correct place for this topic, please move this topic.
modified 18-Jan-19 15:29pm.
|
|
|
|
|
Quantum Robin wrote:
Reference: www.osmosian.com Wasn't the owner of this shunned here many years ago?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
Computer languages encapsulate precise physical concepts, english language encapsulates wide range communication.
It is never the language describing a problem that is the issue it is describing the process in terms of a physical concept the CPU can execute as code blocks.
For perspective you could write a book claiming all you need is a screwdriver, spanner and hammer as tools and you can fix anything. Whilst you can probably tackle a vast range of repairs there are jobs that require highly specialized tools that you simply couldn't do. Plain English Programming falls into the same fallacy you conceive situations it might work but you have to close your eyes to the situations it clearly won't.
I suspect the only way to really go after a real concept of english language programming would be via AI and if you went that path specific jargon would be less verbose, clearer and not prone to stupid English language nuances. Take any scientific field the first thing we generally have to do is butcher English into a series of defined jargon and acronyms so we can all agree on what is being said. Read any science journal or book and it isn't english a layman would recognize you need to know what all the jargon and acronyms mean. So I put the chances of any serious programming in english language at close to zero because we can't even do it with science.
In vino veritas
|
|
|
|
|
On top of everything leon already said, natural languages are too ambiguous to be used as a computer language. The exact meaning of everything you say depends on the context as much as who you're talking to, and often can only be interpreted correctly when also analyzing your gestures and mimics. A simple wink in the context of some statement could mean a world of a difference.
This is the main reason why we misunderstand each other so often in written communication.
Given that high chance of misunderstanding, I'd rather not use a software system that is prone to doing something entirely different than what I intended. If I tell it to "Go to hell" I do not want it to query TomTom for directions. And if I tell it to "Let's eat grandpa!", I better not forget that all-important comma: "Let's eat, grandpa!"
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|