I'm fairly new to C/C++, but I'm trying to debug some code. It uses a vector that someone had called CART8 and is structured as such:
typedef struct crt8 {
double x;
double y;
double z; } CART8;
Now my question is this. How do I create and populate an instance of an vector of type CART8 called vector1? I've read through a lot of material, and even found a site that indicate how you would create the vector...as indicated above, but no information on HOW to actually use it.
typedef is used extensively in C to refer to struct variables without specifying the struct prefix, for example if I had:
struct vector {
double x;
double y;
double z;
};
than to initialize it I'd have to do:
struct vector vector1;
vector1.x = 1.11;
vector1.y = 1.22;
vector1.z = 1.33;
But if I used a typedef in the declaration:
typedef struct vector {
double x;
double y;
double z;
} vector_type;
than I could simplify this initialization like so (note the struct prefix is not needed now):
vector_type vector1;
vector1.x = 1.11;
vector1.y = 1.22;
vector1.z = 1.33;
Of course, I could still use the full struct vector initialization in this case as well
So in your case:
#include <stdio.h>
typedef struct crt8 {
double x;
double y;
double z;
} CART8;
int main(int argc, char** argv)
{
CART8 vector1;
vector1.x = 2.526;
vector1.y = 3.416;
vector1.z = 4.32;
printf("%f %f %f\n", vector1.x, vector1.y, vector1.z);
}
Alternatively, you can always resort to the original struct definition:
#include <stdio.h>
typedef struct crt8 {
double x;
double y;
double z;
} CART8;
int main(int argc, char** argv)
{
struct crt8 x;
x.x = 2.341;
x.y = 3.43;
x.z = 4.521;
printf("%f %f %f\n", x.x, x.y, x.z);
}
You wrote:
typedef struct crt8 {
double x;
double y;
double z;
} CART8;
This defined a new 'type'. The 'typename' is struct crt8 or the alias you defined CART8. This is how you instantiate an object from that type in C:
struct crt8 myVector;
or you can use the alias 'CART8' that you've defined:
CART8 myVector;
Either way, this is how you populate the 'members' of your object:
CART8 x; // Creation of object
x.x = 100;
x.y = 101;
x.z = 102;
Here is a demonstrative program that shows various ways how objects of the structure can be created, initialized, and used.
#include <stdio.h>
#include <math.h>
typedef struct crt8 {
double x;
double y;
double z; } CART8;
int main( void )
{
CART8 vector1 = { 1.1, 2.2, 3.3 };
CART8 vector2 = { .x = 1.1, .y = 2.2, .z = 3.3 };
CART8 vector3;
vector3.x = 1.1;
vector3.y = 2.2;
vector3.z = 3.3;
CART8 vector4 = vector1;
CART8 vector5 = { vector1.x + vector2.z, vector1.y + vector2.y, vector1.z + vector2.x };
printf( "vector5 = { %lf, %lf, %lf }\n", vector5.x, vector5.y, vector5.z );
printf( "Magnitude = %lf", sqrt( pow( vector1.x, 2 ) + pow( vector1.y, 2 ) + pow( vector1.z, 2 ) ) );
return 0;
}
The output is
vector5 = { 4.400000, 4.400000, 4.400000 }
Magnitude = 4.115823
Related
I need to sum two complex numbers (c1,c2) and then express the result in its polar form.
I don't really know how to access the result for c1+c2, I mean I store them in the variable "result" but when I try to access them I find myself in the ComplexPolar structure and so I can't access the result.real and result.img to calculate magnitude and angle:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
struct ComplexCartesian
{
float real;
float img;
};
struct ComplexPolar
{
float magnitude;
float angle;
};
struct ComplexPolar add_two_complex(struct ComplexCartesian c1, struct ComplexCartesian c2, struct ComplexPolar result)
{
result.real= c1.real+c2.real;
result.img=c1.img+c2.img;
result.magnitude= sqrt((result.real)^2 + (result.img)^2);
result.angle= atan2(result.img, result.real);
}
^2 is not how you square in C, you have to either multiply the number by itself or use libc pow function.
^2 is a XOR operation where you aim to toggle the second bit, but in your case you are using it on a float which violates the strict aliasing rule and cause undefined behavior (on top of not being what you seek).
See the code below with some comments:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct ComplexCartesian
{
float real;
float img;
};
struct ComplexPolar
{
float magnitude;
float angle;
};
struct ComplexPolar polar_from_cartesian_sum(struct ComplexCartesian c1, struct ComplexCartesian c2)
{
struct ComplexPolar complexPolar; // here you declare the variable of your ComplexPolar struct
c1.real += c2.real; // you don't need to have a result var, you can just reuse c1.
c1.img += c2.img;
complexPolar.magnitude = sqrt(c1.real * c1.real + c1.img * c1.img);
complexPolar.angle = atan2(c1.img, c1.real);
return complexPolar; // you return the value;
}
int main(void) {
struct ComplexCartesian c1 = {0.12f, 0.15f};
struct ComplexCartesian c2 = {0.42f, 1.15f};
struct ComplexPolar complexPolar = polar_from_cartesian_sum(c1, c2);
printf("%f %f\n", complexPolar.magnitude, complexPolar.angle);
return 0;
}
Compile with gcc complex.c -lm && ./a.out
Output:
1.407693 1.177098
NB: Perhaps you should explicitly tell that your angle is expressed in radians, and also rename your function as polar_from_cartesian_sum
Radius = 1.41
θ = 67.44o = 1.18 radians
I'm trying to use GCC's vector extensions, the exact code that I tried is:
typedef float Vector4 __attribute__ ((vector_size (16)));
void defVector(Vector4* v, float x,float y,float z,float w){
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}
int main(int argc, char* argv){
Vector4 a;
defVector(&a, 1, 2, 3, 4);
}
and keep getting errors:
incompatible types when assigning to type ‘Vector4 {aka __vector(4) float}’ from type ‘float’
v[0] = x;
Can't dereference it too or I get another error.
I would like to not copy the entire thing to the function stack every time I use it, and it's a necessity to make pointers to the return values like
int someFunc(Vector4 v, Vector4* r){
...
r[0] = return_value;
return 0;
}
I tried everything I know to access the values inside the funtion.
What I'm missing here?
Based on the OP's example in which a local function gets a "vector-extension" pointer:
#include <stdio.h>
#include <stdint.h>
typedef float Vector4 __attribute__ ((vector_size (16)));
void defVector(Vector4 *v,float a, float b);
void defVector(Vector4 *v,float a, float b){
v[0] = *(Vector4*)&a;
v[1] = *(Vector4*)&b;
a = *(float*)&v[0] + 1.2;
b = *(float*)&v[1] + 2.1;
printf("%f,%f,%u",a,b,\
(uint32_t)sizeof(Vector4)/(uint32_t)sizeof(float));
}
int main(void) {
static Vector4 vectorA;
static float x1 = 3.4;
static float x2 = 4.3;
defVector(&vectorA,x1,x2);
}
This code will print (demo): 4.6,6.4,4 , so the value of two float were assigned to two units (being the number of units sizeof(Vector4)/sizeof(float)) of a Vector4 type variable.
New to C, here is a simple Struct I have created.
typedef struct car {
float x, y;
unsigned char width, height;
} Cars;
My attempt to assign the x and y property of car:
Cars sedan;
sedan.x = 20;
sedan.y = 10;
Error
error: expected '=', ',', ';', 'asm' or 'attribute' before '.' token
Any ideas? Please help!
I'm guessing that you have the lines
Cars sedan;
sedan.x = 20;
sedan.y = 10;
outside a function. You cannot use
sedan.x = 20;
sedan.y = 10;
outside a function. Move those lines inside a function.
Another choice is to initialize the members of the struct using (Thanks #JonathanLeffler)
Car sedan = { .x = 20, .y = 10 };
Maybe you could try defining one member of struct in one line.
typedef struct car {
float x;
float y;
unsigned char width;
unsigned char height;
} Cars;
#include <stdio.h>
#include <string.h>
typedef struct car {
float x, y;
unsigned char width, height;
} Cars;
int main( ) {
Cars sedan;
sedan.x = 20;
sedan.y = 10;
printf( "value one : %f\n", sedan.x);
printf( "value two : %f\n", sedan.y);
}
Output :
value one : 20.000000
value two : 10.000000
You can also code structure as follow, :)
struct car {
float x, y;
unsigned char width, height;
};
int main( ) {
struct car sedan; /* Declare sedan of type car */
sedan.x = 20;
sedan.y = 10;
printf( "value one : %f\n", sedan.x);
printf( "value two : %f\n", sedan.y);
}
I am trying to create a 3d grid for my OpenCl/GL fluid. The problem Im having is that for some reason the my grid initialization function does not work properly. Here is my *.h, *.c setup and (at the end) call in main:
(grid.h):
#if RunGPU
#define make_float3(x,y,z) (float3)(x,y,z)
#define make_int3(i,j,k) (int3)(i,j,k)
#else
typedef struct i3{
int i,j,k;
} int3;
typedef struct f3{
float x,y,z;
} float3;
#define __global
#define make_float3(x,y,z) {x , y , z}
#define make_int3(x,y,z) {x , y ,z}
#endif
typedef struct grid3 * grid3_t; // u,v,w
typedef struct grid * grid_t; // p
struct grid3 {
__global float3* values_;
__global float * H_;
__global float * h_;
int dimx_;
int dimy_;
int dimz_;
} ;
struct grid {
__global float * values_;
int dimx_;
int dimy_;
int dimz_;
};
void grid3_init(grid3_t grid,__global float3* vel,__global float* H,__global float *h, int X, int Y, int Z);
(grid.c):
void grid3_init(grid3_t grid,__global float3* val,__global float* H,__global float *h, int X, int Y, int Z){
grid->values_ = val;
grid->H_ = H;
grid->h_ = h;
grid->dimx_ = X;
grid->dimy_ = Y;
grid->dimz_ = Z;
}
In main im initializing my grid like so:
int main(int argc, char** argv)
{
const int size3d = Bx*(By+2)*Bz;
const int size2d = Bx*Bz;
float3 * velocities = (float3*)malloc(size3d*sizeof(float3));
float * H = (float*)malloc(size2d*sizeof(float));
float * h = (float*)malloc(size2d*sizeof(float));
for(int i = 0; i < size3d; i++){
float3 tmp = make_float3(0.f,0.f,0.f);
velocities[i] = tmp;
if(i < size2d){
H[i] = 1;
h[i] = 2;
}
}
grid3_t theGrid;
grid3_init(theGrid, velocities, H, h, Bx, By, Bz); // <- ERROR OCCURS HERE
}
The error im getting is during runtime - "Run-Time Check Failure #3 - The variable 'theGrid' is being used without being initialized". But thats precisely the job of grid3_init?
As im trying to write code to work for both Host and GPU I have to sacrifice the use of classes and work strictly with structs - which I have less experience with.
At this point I dont really know what to google either, I appriciate any help i can get.
struct grid3 theGrid;
grid3_init(&theGrid, velocities, H, h, Bx, By, Bz);
You need to create grid3 instance and pass its pointer to grid3_init. Your existing code just uses uninitialized pointer.
Im having a small math library for 3d vector and Im trying to "unify" it.
Instead of having multiple typedef struct for vector3f, vector3i, color3, angles etc... Im trying to put everything inside the same struct like this:
typedef struct
{
union
{
float x;
float r;
float ax;
int x_int;
};
union
{
float y;
float g;
float ay;
int y_int;
};
union
{
float z;
float b;
float az;
int z_int;
};
} vec3;
Everything works peachy as long as the type is float, however when it falls to int Im having some strange values (which is understandable). My question is: Is there a way to cast directly/automatically inside the structure definition or I have to create extra functions to typecast between float and int?
Due to the answers below, maybe I should modify my original question to the following:
What is the best way to "unify" (and by unify I mean have like 1 struct) to be able to handle at the same time the following:
vector3f (float x,y,z)
vector3i (int x,y,z)
RGB (float r,g,b)
RGB (unsigned char r,g,b)
euler angle (ax, ay, az)
Thanks in advance!
If you mean that you want to put '360.0f' into float z of a union and have int z_int == 3, or vice versa, you can't. That is not the purpose of a union, and the binary representation of 3 (an integer) and 3.0 (a floating point value) are dissimiliar.
However, you could just remove the int and cast one of the floats to an int.
#include <stdio.h>
#include <stdlib.h>
typedef struct genericStruct
{
void *valueOne;
void *valueTwo;
}GS;
int main()
{
GS *gs = malloc(sizeof(*gs));
int valueInt = 10;
float valueFloat = 3.141592653589;
int *inputIntPtr = (int*)malloc(sizeof(int));
float *inputFloatPtr = (float*)malloc(sizeof(float));
void *voidPtr = NULL;
*inputIntPtr = valueInt;
*inputFloatPtr = valueFloat;
voidPtr = inputIntPtr;
gs->valueOne = voidPtr;
int *outputIntPtr = (int*)malloc(sizeof(int));
outputIntPtr = gs->valueOne;
printf("Input ptr = %d\n", *inputIntPtr);
printf("Output ptr = %d\n", *outputIntPtr);
voidPtr = inputFloatPtr;
gs->valueTwo = voidPtr;
float *outputFloatPtr = (float*)malloc(sizeof(float));
outputFloatPtr = gs->valueTwo;
printf("Input ptr = %f\n", *inputFloatPtr);
printf("output ptr = %f\n", *outputFloatPtr);
free(gs);
free(inputIntPtr);
free(inputFloatPtr);
free(outputIntPtr);
free(outputFloatPtr);
return 0;
}
And this what I meant by using void types.
This is a small piece of code that i wrote for you.It should do the job.I hope i was able to do what you asked for...
typedef struct{
void *ptr1;
void *ptr2;
void *ptr3;
}VEC;
main(){
VEC v ;
VEC *ptr;
int a = 5;
double b = 6;
float c = 7;
v.ptr1 = NULL;
v.ptr2 = NULL;
v.ptr3 = NULL;
ptr = &v;
v.ptr1 = (int *)&a;
ptr->ptr1 = (int *)&a;
v.ptr2 = (double *)&b;
ptr->ptr2 = (double *)&b;
v.ptr3 = (float *)&c;
ptr->ptr3 = (float *)&c;
printf("%d\n",*(int *)v.ptr1);
printf("%d\n",*(int *)(ptr->ptr1));
printf("%lf\n",*(double *)v.ptr2);
printf("%lf\n",*(double *)(ptr->ptr2));
printf("%f\n",*(float *)v.ptr3);
printf("%f\n",*(float *)(ptr->ptr3));
}
Or change all variables to void pointer type and then cast them to float or integer. Is it OK?