need to produce a function that detects the zeros in a array - c++

I have this code but is not working , it keep giving me the following errors :
[Error] cannot convert 'float' to 'float*' for argument '1' to 'void zeroCrossing(float*, float*, int)'
[Error] cannot convert 'float*' to 'float' for argument '1' to 'bool getSign(float)'
[Error] cannot convert 'float*' to 'float' for argument '1' to 'bool getSign(float)'
[Error] invalid conversion from 'int' to 'float*' [-fpermissive]
#include <iostream>
#include <cstring>
using namespace std;
void zeroCrossing(float *data, float *zerCross, int nx);
bool getSign(float data);
float array[9] = {1,2,3,0,-1,-2,-3,0,1};
float *p = array;
float f1[9];
float *p2 = f1;
int bx= 2 ;
int main() {
zeroCrossing(*p,*p2,bx);
return 0 ;
}
/* zero crossing function */
/* data = input array */
/* zerCross = output zero crossing array */
void zeroCrossing(float *data[], float *zerCross[], int nx)
{
int i;
bool sign1, sign2;
memset(zerCross, 0, nx*sizeof(float));//copies the 0 to the first characters of the string
//pointed to, by argument
for(i=0; i<nx-1; i++) /* loop over data */
{
sign1 = getSign(data[i]);
sign2 = getSign(data[i+1]);
if(sign1!=sign2) /* set zero crossing location */
zerCross[i+1] = 1;
}
}
/* get sign of number */
bool getSign(float data)
{
if(data>0) /* positif data */
return (1);
else /* negatif data */
return (0);
}

When you do coding, you should compile the code after some lines of codes, unless you are pro.
There are two things I could say about your codes
Function declaration: void zeroCrossing(float *data, float *zerCross, int nx); and void zeroCrossing(float *data[], float *zerCross[], int nx) are not the same.
Variable name: Should avoid names like array because they are used in the standard lib.
This is my fix to make your code compilable
#include <iostream>
#include <cstring>
using namespace std;
void zeroCrossing(float *data, float *zerCross, int nx);
bool getSign(float data);
float array_[9] = {1,2,3,0,-1,-2,-3,0,1};
float* p = array_;
float f1[9];
float *p2 = f1;
int bx= 2 ;
/* get sign of number */
bool getSign(float data)
{
if(data>0) /* positif data */
return (1);
else /* negatif data */
return (0);
}
/* zero crossing function */
/* data = input array */
/* zerCross = output zero crossing array */
void zeroCrossing(float *data, float *zerCross, int nx)
{
int i;
bool sign1, sign2;
memset(zerCross, 0, nx*sizeof(float));//copies the 0 to the first characters of the string
//pointed to, by argument
for(i=0; i<nx-1; i++) /* loop over data */
{
sign1 = getSign(data[i]);
sign2 = getSign(data[i+1]);
if(sign1!=sign2) /* set zero crossing location */
zerCross[i+1] = 1;
}
}
int main() {
zeroCrossing(p,p2,bx);
return 0 ;
}

1 - you should minimize the number of global variables, in your case it is 0.
2 - *p points to a value stored in an address p, so in main function when you are calling zeroCrossing you need to pass an address, not value.
To be honest, I don't understand what you are trying to do but at least this code don't throw errors:
#include <iostream>
#include <cstring>
using namespace std;
void zeroCrossing(float *data, float *zerCross, int nx);
bool getSign(float data);
int main()
{
float array[9] = {1,2,3,0,-1,-2,-3,0,1};
float *p = array;
float f1[9];
float *p2 = f1;
int bx = 2 ;
zeroCrossing(p, p2, bx);
return 0 ;
}
/* zero crossing function */
/* data = input array */
/* zerCross = output zero crossing array */
void zeroCrossing(float *data, float *zerCross, int nx)
{
int i;
bool sign1, sign2;
memset(zerCross, 0, nx*sizeof(float));//copies the 0 to the first characters of the string
//pointed to, by argument
for(i=0; i<nx-1; i++) { /* loop over data */
sign1 = getSign(data[i]);
sign2 = getSign(data[i+1]);
if(sign1!=sign2) /* set zero crossing location */
zerCross[i+1] = 1;
}
}
/* get sign of number */
bool getSign(float data)
{
if(data>0) /* positif data */
return (1);
else /* negatif data */
return (0);
}

Related

Overloading [] operator c++

I am trying to overload the indexing operator for a c++ class but I am not able to do so. When I try to index my Matrix class, I get the following error:
error: cannot convert 'Matrix' to 'double*' in initialization
This error occurs on the 9th line of my main.cpp. Does it seem that the indexing does not seem to be recognized by the compiler?
Below is my code:
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
using namespace std;
class Matrix
{
public:
/** Default constructor */
Matrix(unsigned int num_cols, unsigned int num_rows);
/** Default destructor */
virtual ~Matrix();
/** Access num_cols
* \return The current value of num_cols
*/
unsigned int getCols() { return _num_cols; }
/** Access num_rows
* \return The current value of num_rows
*/
unsigned int getRows() { return _num_rows; }
double operator[](unsigned int index);
protected:
private:
unsigned int _num_cols; //!< Member variable "num_cols"
unsigned int _num_rows; //!< Member variable "num_rows"
double ** _base;
};
#endif // MATRIX_H
Matrix.cpp
#include "Matrix.h"
Matrix::Matrix(unsigned int num_cols, unsigned int num_rows){
_num_cols = num_cols;
_num_rows = num_rows;
if(_num_cols > 0) {
_base = new double*[_num_cols];
for(unsigned int i = 0; i < _num_cols; i++) {
_base[i] = arr;
cout << _base[i] << endl;
}
}
}
double* Matrix::operator[](int index) {
if (index >= _num_cols) {
cout << "Array index out of bound, exiting";
exit(0);
}
return _base[index];
}
Matrix::~Matrix()
{
//dtor
}
main.cpp
#include <iostream>
#include "Matrix.h"
using namespace std;
int main()
{
Matrix * m = new Matrix(1,2);
double * d = m[1];
delete m;
return 0;
}
The declaration of the overloaded operator member function doesn't match the definition.
You defined the operator as:
double* Matrix::operator[](int index) {
But declared it as:
double operator[](unsigned int index);
The declaration should be:
double *operator[](int index);
Also, the problem with this line:
double * d = m[1];
Is that m is a pointer to a Matrix and the [] operator works on the class instance, not a pointer to it, so you need to dereference m:
double * d = (*m)[1];
Or you can define m as an instance of a Matrix:
Matrix m(1,2);
double * d = m[1];

Initialize and declare dynamically multiple variables of random entities in a loop in C++

This is my code:
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#define ENTITY(A) entity##A
#define ALM(A) alm##A
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity ENTITY(i)(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable ALM(i)(&ENTITY(i));
list->Push(&ALM(i));
size++;
}
//do things like printing their value...
delete list;
return 0;
}
I need to create a new variable everytime it run the "TEntity ENTITY(i)" line,
the problem is that it creates the same variable always, I think it is because it creates the variable entityi and therefore it is overwriting on the same variable, besides it seems that the random it generates is always the same number since all entities have the same values ​​in all its parameters. The c variable create a const char * random variable between a-z, A-Z , I don't put the print code because it is unnecessary, so what can I do? Is there any way to dynamically create variables of entities whose values ​​are random?
EDIT
Here is the new code fixed (the macros have been eliminated since they were not necessary and the necessary code has been included to be able to execute it) but there is still the same problem that they are generated with the same parameters (since they are still the same variable):
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#include <conio.h>
#include <windows.h>
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
void movimiento();
void pinta();
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
void TEntity::movimiento() {
m_ix += sumx;
m_iy += sumy;
}
void TEntity::pinta() {
gotoxy(static_cast<short int>(m_ix), static_cast<short int>(m_iy));
printf("%s", rep);
}
void gotoxy(short int x, short int y)
{
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
void clear()
{
system("cls");
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
IAlmacenable* First();
IAlmacenable* Next();
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
IAlmacenable* TList::First() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
res = elementos.front();
position = 1;
}
return res;
}
IAlmacenable* TList::Next() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
int pos = position;
int size = elementos.size();
if (pos < size) {
res = elementos.at(position);
position++;
}
else {
res = this->First();
}
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity *entity = new TEntity(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable *alm = new IAlmacenable(entity);
list->Push(alm);
size++;
}
while(true){
clear();
for (int i = 0; i < size; i++) {
reinterpret_cast<TEntity *>(list->Next()->getValue())->pinta();
reinterpret_cast<TEntity *>(list->Next()->getValue())->movimiento();
}
Sleep(2000);
}
delete list;
return 0;
}
There is some confusion here.
Some points:
The macro is not fit-for-purpose, as you already know; you're just creating a variable name entityi each time;
That doesn't matter! The object only exists for the duration of the loop iteration anyway; C++ doesn't let you create multiple objects with the same name at the same time. In fact you can get rid of the entire macro stuff and just call the object entity;
Now that that's out of the way, you're getting repeated results because you're storing a pointer to each iteration of that local variable — on each occasion, that's a dangling pointer to an object that's been destroyed. Don't store dangling pointers!
You can either:
Dynamically allocate the objects that you're adding to the list, or
Store actual objects rather than pointers-to-objects.
Either way, the local-scope name is irrelevant and certainly need not change repeatedly for each loop iteration.

C++ push_back overwrites last vector element

Since I cannot answer my own question in 8 hours after asking, I'm posting my solution here.
Made some mistakes in the incoming channel number and number of the vector element. Setting the value of channel-1 instead of channel fixed to problem.
My new function is as follows:
void input(long inlet, t_symbol *s, long ac, t_atom *av){
// GET VARIABLES
long channel = atom_getlong(av);
double value = atom_getfloat(av + 1);
long v_size = v_chan.size();
if(channel && v_size < channel){
for(int i = v_size; i < channel; i++){
v_chan.push_back(n_chan);
}
v_chan[channel - 1].value = value;
}
else if(channel){
v_chan[channel - 1].value = value;
}
}
I've got a vector containing structs, which I like to push_back with a new, empty struct.
Example code:
struct channels{
double value;
// eventually more variables
};
vector<channels> v_chan;
channels n_chan;
void push(){
v_chan.push_back(n_chan);
}
The problem is, if my vector contains elements, push_back add an element, but also overwrites the last element.
For example, if my vector size is 1 and element 0 has a value of 0.2, after push_back my vector size is 2, but element 0 and 1 have a value of 0.
What am I doing wrong here?
Real Code: (MAX/MSP external, function input is called in Max)
#include <maxcpp6.h>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
struct bind{
string param;
double* value;
int track;
double base;
double multiplier;
};
struct channels{
double value;
vector<int> bind;
};
vector<channels> v_chan;
vector<bind> v_bind(19);
channels n_chan;
class rec : public MaxCpp6<rec> {
public:
rec(t_symbol * sym, long ac, t_atom * av) {
setupIO(1, 1); // inlets / outlets
}
~rec() {}
// methods:
//SET BIND FUNCTION
void setBind(long inlet, t_symbol *s, long ac, t_atom *av){
}
void output(long track, long type){
}
void input(long inlet, t_symbol *s, long ac, t_atom *av){
// GET VARIABLES
long channel = atom_getlong(av);
double value = atom_getfloat(av + 1);
long v_size = v_chan.size();
if(v_size <= channel){
v_chan.push_back(n_chan);
}
else{
v_chan[channel].value = value;
}
}
void dump(long inlet){
for(int i = 1; i <= v_chan.size(); i++){
post("%d %.2f", i, v_chan[i].value);
}
}
void clearTrackBinds(long inlet){
}
void reset(long inlet){
clearTrackBinds(0);
}
};
C74_EXPORT int main(void) {
// create a class with the given name:
rec::makeMaxClass("solar_receiver");
REGISTER_METHOD_GIMME(rec, input);
REGISTER_METHOD_GIMME(rec, setBind);
REGISTER_METHOD(rec, dump);
REGISTER_METHOD(rec, clearTrackBinds);
REGISTER_METHOD(rec, reset);
}

expected an identifier c++

I am trying to write a class and I finally got it to compile, but visual studio still shows there are errors (with a red line).
The problem is at (I wrote #problem here# around the places where visual studio draws a red line):
1. const priority_queue<int,vector<int>,greater<int> #># * CM::getHeavyHitters() {
2. return & #heavyHitters# ;
3. }
And it says:
"Error: expected an identifier" (at the first line)
"Error: identifier "heavyHitters" is undefined" (at the second line)
The first problem I don't understand at all. The second one I don't understand because heavyHitters is a a member of CM and I included CM.
BTW, I tried to build. It didn't fix the problem.
Thanks!!!
The whole code is here:
Count-Min Sketch.cpp
#include "Count-Min Sketch.h"
CM::CM(double eps, double del) {
}
void CM::update(int i, int long unsigned c) {
}
int long unsigned CM::point(int i) {
int min = count[0][calcHash(0,i)];
return min;
}
const priority_queue<int,vector<int>,greater<int>>* CM::getHeavyHitters() {
return &heavyHitters;
}
CM::CM(const CM &) {
}
CM::~CM() {
}
int CM::calcHash(int hashNum, int inpt) {
int a = hashFunc[hashNum][0];
int b = hashFunc[hashNum][1];
return ((a*inpt+b) %p) %w;
}
bool CM::isPrime(int a) {
bool boo = true;
return boo;
}
int CM::gePrime(int n) {
int ge = 2;
return ge;
}
Count-Min Sketch.h
#pragma once
#ifndef _CM_H
#define _CM_H
using namespace std;
#include <queue>
class CM {
private:
// d = ceiling(log(3,1/del)), w = ceiling(3/eps)
int d,w,p;
// [d][w]
int long unsigned *(*count);
// [d][2]
int *(hashFunc[2]);
// initialized to 0. norm = sum(ci)
int long unsigned norm;
// Min heap
priority_queue<int,vector<int>,greater<int>> heavyHitters;
// ((ax+b)mod p)mod w
int calcHash(int hashNum, int inpt);
// Is a a prime number
bool isPrime(int a);
// Find a prime >= n
int gePrime(int n);
public:
// Constructor
CM(double eps, double del);
// count[j,hj(i)]+=c for 0<=j<d, norm+=c, heap update & check
void update(int i, int long unsigned c);
// Point query ai = minjcount[j,hj(i)]
int long unsigned point(int i);
const priority_queue<int,vector<int>,greater<int>>* getHeavyHitters();
// Copy constructor
CM(const CM &);
// Destructor
~CM();
};
#endif // _CM_H
>> is a single token, the right-shift (or extraction) operator. Some compilers don't recognize it correctly in nested template specialization. You have to put a space between the two angle brackets like this:
Type<specType<nestedSpecType> > ident;
^^^

Passing Arrays In a Library Arduino

I am trying to write a library that reads 5 variables, then sends them through the serial port to a bluetooth reciever, I am getting a number of errors and I am not sure where to go from here, do I need to implement pointers?
Here is the Arduino code....
#include <serialComms.h>
serialComms testing;
void setup()
{
Serial.begin(9600);
}
char data[] = {1,2,3,4,5,6};
void loop()
{
for(int t = 0;t<6;t++)
{
data[t] = data[t]++;
}
testing.updateUser(data);
delay(250);
}
serialComms.cpp
#include <Arduino.h>
#include <serialComms.h>
void serialComms::init()
{
// This is where the constructor would be...right now we are too stupid to have one
}
void serialComms::readAllBytes() // Target Pin,Values
{
}
void serialComms::assignBytes()
{
for(int t = 0;t<5;t++)
{
digitalWrite(12,HIGH);
delay(250);
digitalWrite(12,LOW);
}
}
void serialComms::updateUser(char t[])
{
Serial.write(t,5);
}
serialComms.h
#ifndef serialComms_h
#define serialComms_h
/* serialComms Class */
class serialComms
{
public:
serialComms() {};
void init();
void readAllBytes(); // Will be used to create the array --> two variables for now...
void assignBytes();
void updateUser(char t[]);
};
#endif
Here are the errors that I am getting...
- serialComms.cpp:28: error: initializing argument 1 of 'virtual size_t Print::write(const uint8_t*, size_t)'
-
- serialComms.cpp:28: error: invalid conversion from 'char*' to 'const uint8_t*'
- serialComms.cpp: In member function 'void serialComms::updateUser(char*)':
- serialComms.cpp:27: error: expected primary-expression before ']' token
Example:
void setup()
{
Serial.begin(9600);
char string_array[] = "hello";
char data_array[] = {1,2,3,4,5,6};
unsigned char data_array_uchar[] = {21,22,23,24,25,26};
uint8_t uint8_array[] = {11,12,13,14,15,16};
char alpha_array[] = {0x41,0x42,0x43,0x44,0x45,0x46};
// take note that sizeof() is a precompile command... number of places/size of each place.
updateUserPrint(string_array);
updateUserWrite(data_array, sizeof(string_array));
updateUserWriteUchar(data_array_uchar, sizeof(data_array_uchar));
updateUserWriteUchar(uint8_array, sizeof(uint8_array));
updateUserWriteUint(uint8_array, sizeof(string_array));
updateUserAlpha(alpha_array, sizeof(string_array));
}
void updateUserPrint(char *s)
{ //note a string aka array of char's is ended with a null.
Serial.print(s); // this can detect.
Serial.println();
}
void updateUserWrite(char *t, size_t len)
{ //note an array of int's is not ended with a null. so you need to know how long it is.
for (int n = 0; n < len ; n++) {
Serial.print(t[n],DEC);
Serial.print(",");
}
Serial.println();
}
void updateUserWriteUchar(unsigned char *t, size_t len)
{ //note an array of int's is not ended with a null. so you need to know how long it is.
for (int n = 0; n < len ; n++) {
Serial.print(t[n],DEC);
Serial.print(",");
}
Serial.println();
}
void updateUserWriteUint(uint8_t *t, size_t len)
{ //note an array of int's is not ended with a null. so you need to know how long it is.
for (int n = 0; n < len ; n++) {
Serial.print(t[n],DEC);
Serial.print(",");
}
Serial.println();
}
void updateUserAlpha(char *t, int len)
{ //note an array of int's is not ended with a null. so you need to know how long it is.
for (int n = 0; n < len ; n++) {
Serial.write(t[n]);
}
Serial.println();
}
produces the following:
hello
1,2,3,4,5,6,
21,22,23,24,25,26,
11,12,13,14,15,16,
11,12,13,14,15,16,
ABCDEF
Serial.write can only send constant strings like
Serial.write(“hello”);
That is why the error error: invalid conversion from 'char*' to 'const uint8_t*'
use as
char temp[max_length];
sprintf(temp,"%s",t);
Serial.write(temp);