 # Math with Structs

Hi,

I'm creating trying to create 3D objects via their pointers and contain the points in structures. I will then compute the volume of the objects.

``````/* Structures
*
*  Goals
*  1. create list of 3D geometrical objects (cube, sphere)
*  2. compute volume of objects, and print volume
*  3. scale the objects by permanently overwriting their sides / dimensions
*
*/

/***** GLOBAL VARIABLES *****/

/***** STRUCTURES *****/
struct cube
{
//dimensions
int x = 10;
int y = 10;
int z = 10;
} cube_vars;

int cube_volume(struct cube int x, int y, int z);

/*
struct sphere
{
int x;
int y
int z;
} sphere_vars;
*/

void setup()
{
Serial.begin(9600);
}

void loop()
{
int volume = cube_volume(side_1, side_2, side_3);

Serial.print("volume = ");
Serial.println(volume);

Serial.flush();
exit(0);

}

/***** FUNCTIONS *****/
int cube_volume(struct cube int x, int y, int z)
{
int volume;
volume = x * y * z;
return volume;
}
``````

I feel I'm close to solving this, but I'm getting this error message:

``````structure_example_functions_3:30:33: error: two or more data types in declaration of 'x'
int cube_volume(struct cube int x, int y, int z);
^
structure_example_functions_3:30:34: error: expected ')' before ',' token
int cube_volume(struct cube int x, int y, int z);
^
structure_example_functions_3:30:36: error: expected unqualified-id before 'int'
int cube_volume(struct cube int x, int y, int z);
^~~
\structure_example_functions_3.ino: In function 'void loop()':
structure_example_functions_3:49:28: error: 'side_1' was not declared in this scope
int volume = cube_volume(side_1, side_2, side_3);
^~~~~~
\structure_example_functions_3.ino:49:28: note: suggested alternative: 'size_t'
int volume = cube_volume(side_1, side_2, side_3);
^~~~~~
size_t
structure_example_functions_3:49:36: error: 'side_2' was not declared in this scope
int volume = cube_volume(side_1, side_2, side_3);
^~~~~~
\structure_example_functions_3.ino:49:36: note: suggested alternative: 'size_t'
int volume = cube_volume(side_1, side_2, side_3);
^~~~~~
size_t
structure_example_functions_3:49:44: error: 'side_3' was not declared in this scope
int volume = cube_volume(side_1, side_2, side_3);
^~~~~~
\structure_example_functions_3.ino:49:44: note: suggested alternative: 'size_t'
int volume = cube_volume(side_1, side_2, side_3);
^~~~~~
size_t
\structure_example_functions_3.ino: At global scope:
structure_example_functions_3:60:33: error: two or more data types in declaration of 'x'
int cube_volume(struct cube int x, int y, int z)
^
structure_example_functions_3:60:34: error: expected ')' before ',' token
int cube_volume(struct cube int x, int y, int z)
^
structure_example_functions_3:60:36: error: expected unqualified-id before 'int'
int cube_volume(struct cube int x, int y, int z)
^~~
exit status 1
two or more data types in declaration of 'x'
``````

Any tips as what I'm missing?

Just pass the struct, or better a reference to it. No need to pass x, y and z as parameters as well.

Something like this

``````/* Structures

Goals
1. create list of 3D geometrical objects (cube, sphere)
2. compute volume of objects, and print volume
3. scale the objects by permanently overwriting their sides / dimensions

*/

/***** GLOBAL VARIABLES *****/

/***** STRUCTURES *****/
struct cube
{
//dimensions
int x = 10;
int y = 10;
int z = 10;
} cube_vars;

/*
struct sphere
{
int x;
int y
int z;
} sphere_vars;
*/

void setup()
{
Serial.begin(9600);

int volume = cube_volume(cube_vars);
Serial.print("volume = ");
Serial.println(volume);

cube_vars.x = 1;
cube_vars.y = 2;
cube_vars.z = 3;
Serial.print("volume = ");
Serial.println(volume);

}

void loop()
{
}

/***** FUNCTIONS *****/
int cube_volume(struct cube var)
{
int volume;
volume = var.x * var.y * var.z;
return volume;
}
``````

Even better, make them classes* that contain a method to compute and return their own volume.

Even more better, make a “ThreeDimObject” base class and have the specific shape classes inherit from it.

Also, none of the dimension of you 3D objects are likely to be negative. So, don’t use signed integers to represent them. Use something unsigned like uint16_t, uint32_t, etc.

*In C++, classes and structs are essentially identical except that class members are private by default whereas they are public by default with structs.

Instead of making a separate 'volume' function for each type of struct, you can put the function inside the struct so ithe right 'volume' function gets called for each struct.

``````/***** STRUCTURES *****/
struct cube
{
// dimensions
int x = 10;
int y = 10;
int z = 10;
// functions
int volume() {return x*y*z;}
} myCube;

void setup()
{
Serial.begin(9600);

Serial.print("volume = ");
Serial.println(myCube.volume());

myCube.x = 1;
myCube.y = 2;
myCube.z = 3;
Serial.print("volume = ");
Serial.println(myCube.volume());
}

void loop() {}
``````

Then it's trivial to turn your 'struct' into a 'class':

``````/***** OBJECT CLASSES *****/
class cube
{
public:
//dimensions
int x = 10;
int y = 10;
int z = 10;

// functions
int volume() {return x*y*z;}
} myCube;
``````

(The difference between 'class' and 'struct' is that the contents of 'class' default to 'private:' and the contents of 'struct' default to 'public:'. When you change the keyword 'struct' to 'class' you only have to put "public:" a the top to make the 'class' act the same as the 'struct' did.)

function inside the struct so ithe right 'volume' function gets called for each struct.

Functions in structs? Never heard of such a thing. Functions in classes.. Heard of that.

-jim lee

jimLee:
Functions in structs? Never heard of such a thing. Functions in classes… Heard of that.

As stated in both Replies #3 and #4, classes and structs in C++ are essentially identical except that class members are private by default whereas they are public by default with structs.

Are there functions in structs in straight c?

-jim lee

jimLee:
Are there functions in structs in straight c?

-jim lee

Good question, but the answer is no. Difference between C structures and C++ structures - GeeksforGeeks

It would be good to use a constructor as well so the user could create multiple cube or other objects using the same struct / class.

6v6gt:
It would be good to use a constructor as well so the user could create multiple cube or other objects using the same struct / class.

Yes. Good idea. If you want to create a cube that is NOT 10x10x10 it would be good to be able to specify the dimensions. You can put the default dimensions on the constructor arguments rather than built into the struct.

``````struct cube
{
public:
//dimensions
int x;
int y;
int z;

// functions
cube(int x=10, int y=10, int z=10) : x(x), y(y), z(z) {}
int volume()
{
return x * y * z;
}
} myCube;

cube cube2(2, 4, 6);

void setup()
{
Serial.begin(9600);

Serial.print("volume = ");
Serial.println(myCube.volume());

myCube.x = 1;
myCube.y = 2;
myCube.z = 3;
Serial.print("volume = ");
Serial.println(myCube.volume());

Serial.print("volume2 = ");
Serial.println(cube2.volume());
}

void loop() {}
``````