Output parameters with arrays in one function with Arduino and C ++ - c++

I have a problem with the initialization with various parameters in my function.
It works if I have created an array int params [] = {...}. However, it doesn't work if I want to write the parameters directly into the function.
declaration (in the .h)
void phase_an(int led[]);
in the .cpp
void RS_Schaltung::phase_an(int led[])
{
for (size_t i = 0; i < LEN(led); i++) {
digitalWrite(led[i], HIGH);
}
}
if I try this way, it won't work. I would like it to be like that. But I couldn't find anything about it on the internet. ...:
in the Arduino sketch:
RS.phase_an(RS.ampelRot, RS.ampelGelb, ..... ); <--- is there a way to do it like that?
what amazes me is that it works this way:
int p_an [5] = {RS.ampelRot, RS.ampelGelb, RS.ampelGruen, RS.rot, RS.gelb};
...................
RS.phase_an (p_an);
does anyone have a suggestion?

There are several ways of making a function accepting a variable number of arguments here.
However, in your current code there is a problem: when you pass a native array of unknown size as argument of a function (e.g. void f(int a[])), the argument will be managed a pointer to an array, and there is no way inside this function to know the real length of that array. I don't know how LEN() is defined, but chances are high that it doesn't works well in your code.
A safer and more practical alternative is to use a vector<int> instead:
#include <iostream>
#include <vector>
using namespace std;
void f(const vector<int>& a){
for (int i=0; i<a.size(); i++) {
cout<<a[i]<<" ";
}
cout<<endl;
}
int main() {
vector<int> test={1,2,3,4};
f(test);
f({1,2,3,4});
return 0;
}
In this case, you can pass your multiple values between bracket in the function call (e.g. ({RS.ampelRot, RS.ampelGelb, RS.ampelGruen, RS.rot, RS.gelb})and C++ will automatically convert it to a vector.

Related

Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred

#include<iostream>
#include <list>
using namespace std;
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas[];
public:
void print() { cout << *pinakas[0]; return; }
Euler(int korifess, int akmess);
~Euler() { delete[] *pinakas; }
void addAkmes(int kor1, int kor2);
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess) {
*pinakas = new int(korifes);
*pinakas[0] = 89;
}
int main() {
Euler e(2, 1);
e.print();
}
Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred...i can not find where i am wrong in my code.
There are a number of errors in your code, all related to the nature of the pinakas member variable. As it stands, you are declaring this as an array of pointers (to int), and, furthermore, you are using a non-standard syntax for 'flexible' arrays (the empty []).
I don't normally just paste 'fixed' code as an answer but, in this case, that code (with the added \\\ comments where I've made changes) is likely to be the most succinct way to help you.
Although, as many here will no doubt point out, it is far better to avoid the use of 'raw' pointers and the new and delete operators, and use the std::vector container, instead.
#include <iostream>
#include <list>
//using namespace std;/// This is considered 'bad practice' by many programmers
using std::cout;/// Just use the aspect of the STL that you need!
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas;/// This will point an 'array' of integers
public:
void print() {
cout << pinakas[0]; return;/// No longer any need for the dereference (*)
}
Euler(int korifess, int akmess);
~Euler() {
delete[] pinakas;/// No need for the dereference (*)
}
// void addAkmes(int kor1, int kor2);/// You haven't provided an actual definition for this, but your never use it!
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess)/// NOTE: Members are initialized in DECLARATION order!
{
pinakas = new int[korifes];/// Use "[]" (not "()") to allocate an array!
pinakas[0] = 89;/// No need for the dereference (*)
}
Feel free to ask for any further clarification and/or explanation.

Passing array between structures C++

I am new to C++ and there is a basic problem I am dealing with. The code below gives complier error:
#include <iostream>
using namespace std;
struct contact_info {
long number;
string name;
};
contact_info take(){
contact_info takein[2];
for (int i=0; i<2; i++) {
cout<<"what is the name"<<"\n";
getline(cin,takein[i].name);
cout<<"what is the phone number"<<"\n";
cin>>takein[i].number;
};
return takein;
};
void give(contact_info takein){
cout<<"Name:"<<takein.name<<"\n"<<"Number:"<<takein.number;
};
int main(int argc, const char * argv[])
{
contact_info takein;
takein=take();
give(takein);
return 0;
}
The error comes from function "take" and is "No viable conversion from 'contact_info[2]' to 'contact_info'"
The code is supposed to take two contact informations in a loop and then prints them on the screen.
I think I need to use pointers for that to pass the "takein" from "take" function to "main" function. Can anyone says if I can fix the code using array and not pointer?
#include <iostream>
struct contact_info
{
long number;
string name;
};
void take(contact_info takein[2])
{
for (int i=0; i<2; i++)
{
cout<<"what is the name"<<"\n";
getline(cin,takein[i].name);
cout<<"what is the phone number"<<"\n";
cin>>takein[i].number;
};
};
void give(contact_info takein)
{
cout<<"Name:"<<takein.name<<"\n"<<"Number:"<<takein.number;
};
int main()
{
contact_info takein[2];
take(takein);
for(int i=0;i<2;++i)
give(takein[i]);
return 0;
}
return takein;
but
contact_info takein[2];
Compiler is upset because you're trying to return an array, use return takin[0]; or return takin[1]; to return a specific contact_info
Addendum
Don't be afraid to learn Python first, higher level languages are a lot more forgiving and python is by no means a toy language, Python and C++ are two things I use daily and I love them both. I tolerate Java, it can be good when you want static typing and something more forgiving than C++, or in my case Android :P
If you edit your question to describe what you want to do I am happy to provide some annotated code to demonstrate, leave a comment to this to get my attention.
contact_info[] take(){
...
}
if you are trying to return an array.
for returning an element, use
return takein[0];
or
return takein[1];
If your goal is "to take two contact informations in a loop and then prints them on the screen", you must pass an array to get information and pass an array to prints it:
contact_info * take(contact_info *takein){
for (int i=0; i<2; i++) {
cout<<"what is the name"<<"\n";
getline(cin, takein[i].name);
cout<<"what is the phone number"<<"\n";
cin>>takein[i].number;
};
return takein;
};
void give(contact_info * takein){
for (int i = 0; i < 2; i++)
cout<<"Name:"<<takein[i].name<<"\n"<<"Number:"<<takein[i].number;
};
int main(int argc, const char * argv[])
{
contact_info takein[2];
// pass takein as an array
take(takein);
give(takein);
return 0;
}
Secret's out! Arrays are pointers. Or at least, they implicitly convert to them. Even it you did have the right type, you'd be using undefined behavior, as the array is allocated on a place on the stack that no longer exists.
I'll assume you actually want to 'return two things', otherwise Alec's answer is perfectly valid.
Try a vector, or a 2 element struct. People often struggle mentally with the notion of creating a struct only to serve as a return value, but it's worth it from a maintainability standpoint. You get the power of naming the type and naming its contents, and that self-documents your intent.
In the main function takein is a variable of type contact_info
and here takein=take(); you are trying assign an array to a normal variable.

foreach in C++ int array

I am new to C++ and I am writing the following code.
I needed to iterate over all the addons in my calling function - testFunction. I know this works in C#, but this code is not working. Can anyone please point out the right way to do it in C++?
#include "stdafx.h"
#include <iostream>
#include "resource.h"
int testFunction(char* tester);
int _tmain()
{
int mainProd=2;
int Addons[]={7,8,9,10};
testFunction(mainProd,Addons);
}
void testFunction(int mainProd,int addons[])
{
for(int x = 0 ; addons.length;++x) ---- Not working
{
std::cout<< addons[x];
}
}
I tried to implement vector as below suggestions by you guys
#include "stdafx.h"
#include <iostream>
#include "resource.h"
#include <vector>
void testFunction(std::vector<int> addons);
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<int> Addons ;
for(int i = 0 ;i<10;++i)
{
Addons.push_back(i);
}
testFunction(Addons);
}
void testFunction(std::vector<int> addons)
{
for(int i =0 ; i<addons.size();++i)
{
std::cout<<addons.at(i);
}
}
An array (a raw array) decays into a pointer when passed as an argument to a function, so your array has no size information.
You need to pass the length of the array explicitly into the function to know it inside the function.
Alternatively, and better, use a std::vector and then you'll have the .size() always available when needed.
Apart from using vectors, as Tony suggests, you can use templates and pass the array by reference so that the compiler will deduce the array's size:
template<int N>
void testFunction(int mainProd,int (&addons)[N])
{
for(int x = 0; x < N; ++x) // ---- working
{
std::cout<< addons[x];
}
}
You're using concepts of C# in C++ but, even if we assume that both languages are similar, they're not equal.
The syntax for a ranged-for in C++ is the following:
for (type identifier : container) // note the ':', not ';'
{
// do stuff
}
You can use this for flavour if you have a C++11 compiler.
Btw, it seems that you're using properties on your code:
for(int x = 0 ; addons.length;++x) // what is lenght?
{
std::cout<< addons[x];
}
There's no such thing in C++, if you want to call an object method you need to call it as a function:
// assuming that the object 'addons' have a method
// named 'length' that takes no parameters
addons.length();
But the addons variable isn't an object, is an array (take a look to this tutorial), so it doesn't have a method or property named length; if you need to know its length in order to iterate it you can use in some contexts the sizeof operator (see the tutorial for more information).
Let's suppose that addons were a container:
typedef std::vector<addon> Addons;
Addons addons;
If you want to iterate it using the C++11 range-for, you can write it as follows:
for (addon a : addons)
{
// do stuff with a.
}
Hope it helps.
If you were to use a std::vector or std::array, you could use std::foreach,
std::vector<int> addons = {7,8,9,10};
std::array<int, 4> addons = {7,8,9,10}; // Only use one of these...
std::foreach(addons.begin(), addon.end(), [](int i) {
std::cout << i
});
Code is working with this
for (int i = 0; i < (end(array) - begin(array)); i++)
Return maximum size
Test whether array is empty
array::empty
Element of array
array::size
Array size
sizeof()
If you don't want to use any STL container, you just need to pass the array by reference to the function. Problem here is that you can't define such argument without exact size of the array. This restriction you can overcome making the function as a template, defining the size as the template parameter:
#include <iostream>
template<int N>
void testFunction(int mainProd,int (&addons)[N])
{
for(int x = 0 ; x < N; ++x)
{
std::cout<< addons[x];
}
}
int main()
{
int mainProd=2;
int Addons[]={7,8,9,10};
testFunction(mainProd,Addons);
return 0;
}

C++ swap() for deque indexes

I have two questions, the second being optional.
First, in the program below (a prototype of a simple card program), I am getting the following error:
(29): error C2660: 'shuffle' : function does not take 1 arguments
with the following code:
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <deque>
#include <algorithm>
using namespace std;
deque<int> cardDeck (51);
void flip(); //Prototype flip()
void shuffle(); //Prototype shuffle()
int _tmain(int argc, _TCHAR* argv[])
{
ostream& operator<<(ostream& os, deque<int> dq); //overload << operator to accept deque
//arguments
for (int a=52; a>0; a--) { //initialize the 52 cards in a deck
cardDeck.push_front(a);
}
flip(); //prompt my input to check data
return 0;
}
void flip() { //flip over card in specified location in the deck
int input;
cin >> input;
cout<<cardDeck[input]<<endl;
shuffle(cardDeck);
flip();
}
void shuffle(deque<int> dq) { //use Fisher-Yates algorithm to efficiently and accurately
//randomize card order
for(int i=dq.size()-1; i>-1; i--) {
int j = rand() % (i + 1);
if(i != j) {
swap(dq[j], dq[i]);
}
}
}
Why do I receive this error? (I have looked around and attempted to solve it myself)
Secondly, I'm not certain if I'm doing the fisher-yates algorithm properly because c++ documentation isn't easy to find on it (for the version that utilizes swap();) (Brownie points for answering this or pointing out any horribly awful coding practices, not including the lack of classes)
Thanks in advance!
The reason you get that error is because you declare shuffle as a function not taking any arguments.
void shuffle();
Another note is that you probably want to take a reference to the deque in that function, otherwise you'll shuffle a local copy and won't have the desired side effect.
You probably want it to lok like this:
void shuffle(deque<int>& dq);
Also, you might want to use iter_swap instead of swap to swap the elements. In a dequeue it probably won't make a difference, but for list or map it would.
I think you forgot to put the argument in your function declaration
void shuffle();
should be
void shuffle(deque<int> dq);
I think that the problem is that at the top of your program you've prototyped `shuffle as
void shuffle();
Notice that this takes no arguments. Because C++ uses a one-pass compiler, at the point that you call shuffle, this is the only declaration of shuffle available because the compiler hasn't seen the implementation later on. Consequently, it gives you the above error, because it thinks you are calling a zero-argument function with one argument.
To fix this, update the prototype so that it matches the function you've actually defined.
Hope this helps!

Problem passing a list of objects to another class, C++

Below I have written a sample program that I have written to learn about passing a list of objects to another class. I talk about the problems I am having below.
#include <iostream>
#include <vector>
using namespace std;
class Integer_Class
{
int var;
public:
Integer_Class(const int& varin) : var(varin) {}
int get_var() { return var; }
};
class Contains_List
{
typedef Integer_Class* Integer_Class_Star;
Integer_Class_Star list;
public:
Contains_List(const Integer_Class_Star& listin) : list(listin) {}
Integer_Class* get_list() { return list; }
};
int main (int argc, char * const argv[])
{
// Create a vector to contain a list of integers.
vector<Integer_Class> list;
for(int i = 0; i < 10; i++)
{
Integer_Class temp_int(i);
list.push_back(temp_int);
}
This is where the errors start occuring. Could someone please look at the second class definition and the code below and shed some light on what I'm doing wrong. Thank you so much, as always!
// Import this list as an object into another object.
Contains_List final(list);
// Output the elements of the list by accessing it through the secondary object.
for(int i = 0; i < 10; i++)
{
cout << final.get_list()[i].get_var();
}
return 0;
}
You don't mention what sort of errors you are getting, but one very obvious problem with your code is that the constructor for Contains_List expects a pointer to Integer_Class while the parameter you are sending it (list) is of type vector<Integer_Class>.
A vector is not the same as an array, so you cannot pass it as pointer to the type it contains. Either change your constructor to accept a vector or pointer/reference to vector, or change the code that is causing you problems so that it sends it a pointer to an array.
The 'Contains_List' constructor takes in an 'Integer_Class*'
You declare 'list' to be of type 'vector', yet you pass it to the the 'Contians_List' constructor. You should change the 'Contains_List' class so that it holds a vector instead of an Integer_List array. The two are not interchangeable.
You could also change the vector to be an array of Integer_List's instead, if you so wished.