About struct and arrays (C language) - c

I'm trying to create code using a struct and a pointer, for example:
struct Vector()
{ double x,y,z;};
struct vector *p[][][]. I need a 3d parameter which have x,y and z coordinates for a molecular simulation.
The problem is: I want to run in Ubuntu's terminal and give the values of sample size using argc argv on terminal.
So I ask you guys: Can I create a struct array? I believe this will solve my problem.

You could take a different approach instead of using command line arguments, as suggested in the previous answer.
You can take user input using file input indirection to stdin, which can be a convenient way of processing data. Your command line call looks like:
./your_prog < data
Where data is a data file with a set of three space separated values on each line:
1 1 1
2.1 2.2 2.3
3.1 3.2 3.3
You could then process the data using something like this:
#include <stdio.h>
#include <stdlib.h>
typedef struct vector {
double x;
double y;
double z;
} Vector;
Vector *createVector(double x, double y, double z);
int main()
{
// Initialize an array of pointers to Vector
Vector **array = calloc(5, sizeof(*array));
double x = 0, y = 0, z = 0;
size_t lineCount = 0;
while(1) {
// Take input from stdin
ssize_t r = scanf("%lf%lf%lf", &x, &y, &z);
if (r == EOF) {
// No more data so finish
break;
}
// Note that you need to check the size of the array
// and resize using realloc() as necessary within this loop.
// The array needs to have space for at least lineCount + 1 elements.
// Check this and reallocate before trying to add a
// new element to the array.
array[lineCount] = createVector(x, y, z);
lineCount++;
}
for (size_t i = 0; i < lineCount; i++) {
// Do something with each element of the array
printf("Vector %zu: (%lf, %lf, %lf)\n", i, array[i]->x, array[i]->y, array[i]->z);
}
// You have dynamically allocated memory, so it should be freed.
for (size_t i = 0; i < lineCount; i++) {
free(array[i]);
}
free(array);
return 0;
}
// Create a pointer to a Vector, dynamically allocating memory and returning
// a pointer to the new array.
Vector *createVector(double x, double y, double z)
{
Vector *v = calloc(1, sizeof(*v));
v->x = x;
v->y = y;
v->z = z;
return v;
}
Hope this helps.

I've just solved the problem.
typedef struct
{
double x,y,z;
}vetor;
vetor ***p;
void alloc(int lx, int lz)
{ int i,j=0;
int ly=lx;
p=calloc(lx,sizeof(vetor**));
for(i=0;i<lx;i++)
{
p[i]=calloc(lx,sizeof(vetor*));
for (j=0;j<lx;j++)
{
p[i][j]=calloc(lz,sizeof(vetor));
}
}
}
I was using sizeof(double*) but the member p is a vetor struct type.
So with this i can make a member p[a][b][c] dynamically using pointers and let it a global member ( in my code i have to) and put the values a,b and c on terminal.
I would like to thank you for the answers which makes me think a lot about this problem. Thank you for attention too.

Note that the struct definition you provided ( struct Vector() ) as an example is not a struct definition.
But yes, you can use int argc, char *argv[] to read the command line for user input.
Then you can use something as simple as
If(argc != 2) {
printf("usage error, exiting");
return 0;
}
int array_size = atoi(argc[1]);
Then for example you can easily create an array of struct by declaring a typedef:
typedef struct {
double x;
double y;
double z
} MOLECULE;
MOLECULE molArray[array_size];//from user input - each of array_size instances contains x,y,z members.
There are several ways to instantiate a pointer reference to this example struct, i.e.
MOLECULE *pMolecule = malloc(array_size)*sizeof(*molecule));
Or
MOLECULE *pMolecule = {0};
MOLECULE molecule = {1.0,2.0,3.0};//simple sample of data
pMolecule = &modlecule;//pointer pointing to area in memory containing instance of MOLECULE
Note that with an array of struct, it becomes impracticable to use user input to populate the many members, reading that information from a file, or a database is probably best.
If you provide more details, this answer can do the same. Just flag me in a comment
EDIT To address question in comments "...but how it would if I needed a MOLECULE molArray[x][y][z] ? and x,y,z is a dynamic value which I enter in the beginning of the program?":
Using VLA allows a way to dynamically defined sizes of objects when the sizes needed are not known until run-time. example...
defined MOLECULE struct differently since you want 3D array of struct, no need to define members x, y, z. You need to decide what members will define your actual struct. Because I do not know, I can only guess at what characteristics you want to include in this struct illustration:
typedef struct {
char R;
char G;
char B;
}COLOR;
typedef struct {
double mass;
COLOR color;
double size;
char molec_formula[80];
}CHARAC;
typedef struct {
char name[80];
CHARAC charac;
}MOLECULE;
int main(int argc, char *argv[])
{
if(argc != 4) // prog.exe <x> <y> <z>
{
printf("usage error, exiting");
return 0;
}
int x = atoi(argv[1]);//could also use strtol() here as well
int y = atoi(argv[2]);
int z = atoi(argv[3]);
// from MOLECULE definition above:
MOLECULE molArray[x][y][z];//now you have an 3D array of a struct using VLA
...(more code)
So, if your program name was prog.exe, and you wanted a 3D array with dimensions: 10, 12, 13. then typing this on command line:
prog 10 12 13
Will result in creating molArray[10][12][13]

Related

Malloc array of struct in C

Here is what I do:
I count the number of file inside a folder, get data from this file inside a array of struct.
I want to malloc this array of struct, since I do not know the exact number of file before strating the program.
Here is my code:
struct get_data{
int sequence;
int mask_ID;
char *name;
float intensity;
float angle_correction;
double points[10000];
float X_interval;
};
struct get_data all_data[number_of_file];
Consider I get number_of_file before somewhere in the program.
I want to know how to malloc the struct all_data. I search but got lost at some point. Any help would be welcomed. Thank you.
Mel.
I suggest you give a fixed length to the name variable inside the structure or else you would have to malloc that for each structure. The declaration could look like this:
struct get_data
{
int sequence;
int mask_ID;
char name[256];
float intensity;
float angle_correction;
double points[10000];
float X_interval;
};
Then, you may malloc an array of structures using the following code:
struct get_data *all_data;
all_data = malloc(number_of_files * sizeof(struct get_data));
if (all_data == NULL)
{
printf("Malloc failed!\n);
return -1;
}
/* now you can access each file structure using a for instruction */
int i;
for (i = 0; i < number_of_files; i++)
{
all_data[i].sequence = ...;
/* etc. */
}

How do I return a struct (from a function) containing an array with the correct elements in that array?

I'm making a program that returns a struct containing an array, but the elements in the array are completely wrong. I keep searching for an answer on this site, Google, and even Bing and nothing. The best I can find are answers like this:
Functions can't return arrays in C.
However, they can return structs. And structs can contain arrays...
from How to make an array return type from C function?
Now, how do I fix this without the use of pointers?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
struct Codes{
int as;
int a[];
};
struct Codes create(int as){
int a[as];
for(int j = 0;j<as;j++)
a[j]=j+1;
struct Codes c;
c.as = as;
c.a[c.as];
for(int i=0; i<as; i++)
c.a[i] = a[i];
for(int i=0; i<as; i+=1)
printf("%d \n", c.a[i]);
return c;
}
int main(int argc, char **argv) {
struct Codes cd;
int as = 4;
cd = create(as);
for(int i=0; i<4; i+=1)
printf("%d \n", cd.a[i]);
}
Actual output:
1
2
3
4
0
0
2
-13120
Expected output:
1
2
3
4
1
2
3
4
structs with flexible value are not meant to be manipulated by value, only by pointer.
You cannot return a struct with a flexible member by value, because C does not know how many items it needs to allocate to the return value, and how many bytes it needs to copy.
Allocate your struct in dynamic memory using malloc of sufficient size, copy your data into it, and return a pointer to the caller:
struct Codes *c = malloc(sizeof(struct Codes)+as*sizeof(int));
c->as = as;
for (int i = 0 ; i != as ; i++) {
c->a[i] = i+1;
}
return c;
Change your function to return a pointer; make sure the caller frees the result.
In your function, struct Codes create(int as), the struct Codes c; is allocated on the stuck, so the memory is no longer valid once the function returns...
...It is true that the core struct is copied in the return value... but the variable array length c.a isn't part of the struct (it's a memory "trailer" or "footer") and isn't copied along with the return value.
Either:
allocate the struct and pass it to a struct Codes create(struct Codes *dest, int as) function; OR
make the struct array fixed in size struct Codes{ int as; int a[4]; };
Good luck.

How to store adjacency matrix of a graph using bitmap 2D array

I want to store a adjacency matrix of a very large graph (approx. 40k nodes). But using int and char array for that I am getting segmentation fault due to memory limits.Dynamic allocation using malloc also failed here. Can anyone suggest a method to implement this using a bitmap 2D array?
Here's my implementation so far in C :
#include <stdio.h>
#include <stdlib.h>
int MAX = 50000;
void clustering(char adj[][MAX]);
int count_neighbour_edges(int temp[], int len, char adj[][MAX]);
int main()
{
int nol = 0, i, j, k;
FILE *ptr_file1,*ptr_file2;
struct community
{
int node;
int clust;
};
struct community d;
ptr_file1 = fopen("community.txt","r");
if (!ptr_file1)
return 1;
while(fscanf(ptr_file1,"%d %d",&d.node, &d.clust)!=EOF) //Getting total no. of nodes from here
{
nol++;
}
char adj[nol+1][nol+1]; //Getting segmentation fault here
struct adjacency
{
int node1;
int node2;
};
struct adjacency a;
ptr_file2 = fopen("Email-Enron.txt","r");
if (!ptr_file2)
return 1;
while(fscanf(ptr_file2,"%d %d",&a.node1, &a.node2)!=EOF)
{
adj[a.node1][a.node2] = '1';
adj[a.node2][a.node1] = '1';
}
clustering(adj);
return (0);
}
You can try to put the array in the DATA segment. You do this by declaring it outside any function and later use that memory area as a dynamically sized 2-dimensional array:
char buffer[MY_MAX_SIZE];
int main()
{
...
if ((nol+1)*(nol+1) > MY_MAX_SIZE) {
exit(1); // Too large to fit in buffer!
}
char (*adj)[nol+1] = buffer; // Use the space in buffer as a dynamic 2-dimensional array.
The slightly unintuitive declaration is because the size of nol is unknown at compile time, so I cannot declare buffer as a two-dimensional array of the size you want.
You need to decide on a value for MY_MAX_SIZE that fits the problem size and that your platform can handle, for example
#define MY_MAX_SIZE (40000L * 40000L)

returning multiple values from a function [duplicate]

This question already has answers here:
How do I return multiple values from a function in C?
(8 answers)
Closed 3 years ago.
Can anyone tell me how to return multiple values from a function?
Please elaborate with some example?
Your choices here are to either return a struct with elements of your liking, or make the function to handle the arguments with pointers.
/* method 1 */
struct Bar{
int x;
int y;
};
struct Bar funct();
struct Bar funct(){
struct Bar result;
result.x = 1;
result.y = 2;
return result;
}
/* method 2 */
void funct2(int *x, int *y);
void funct2(int *x, int *y){
/* dereferencing and setting */
*x = 1;
*y = 2;
}
int main(int argc, char* argv[]) {
struct Bar dunno = funct();
int x,y;
funct2(&x, &y);
// dunno.x == x
// dunno.y == y
return 0;
}
You can't do that directly. Your options are to wrap multiple values into a struct, or to pass them in as pointer arguments to the function.
e.g.
typedef struct blah
{
int a;
float b;
} blah_t;
blah_t my_func()
{
blah_t blah;
blah.a = 1;
blah.b = 2.0f;
return blah;
}
or:
void my_func(int *p_a, float *p_b)
{
*p_a = 1;
*p_b = 2.0f;
}
First of all, take a step back and ask why you need to return multiple values. If those values aren't somehow related to each other (either functionally or operationally), then you need to stop and rethink what you're doing.
If the various data items are part of a larger, composite data type (such as a mailing address, or a line item in a sales order, or some other type described by multiple attributes), then define a struct type to represent a single value of that composite type:
struct addr { // struct type to represent mailing address
char *name;
int streetNumber;
char *streetName;
char *unitNumber;
char *city;
char state[3];
int ZIP;
};
struct addr getAddressFor(char *name) {...}
struct point2D {
int x;
int y;
};
struct polygon2D {
size_t numPoints;
struct point2D *points;
};
struct point2D getOrigin(struct polygon2D poly) {...}
Do not define a struct to collect random items that aren't somehow related to each other; that's just going to cause confusion for you and anyone who has to maintain your code down the road.
If the data items are not functionally related, but are somehow operationally related (e.g. data plus a status flag plus metadata about the operation or items as part of a single input operation), then use multiple writable parameters. The most obvious examples are the *scanf() functions in the standard library. There are also the strtod() and strtol() functions, which convert a string representation of a number; they return the converted value, but they also write the first character that was not converted to a separate parameter:
char *str = "3.14159";
double value;
char *chk;
value = strtod(str, &chk);
if (!isspace(*chk) && *chk != 0)
printf("Non-numeric character found in %s\n", str);
You can combine these approaches; here's an example inspired by some work I'm currently doing:
typedef enum {SUCCESS, REQ_GARBLED, NO_DATA_OF_TYPE, EMPTY, ERROR} Status;
typedef struct bounds {...} Bounds;
tyepdef struct metadata {
size_t bytesRead;
size_t elementsRead;
size_t rows;
size_t cols;
} Metadata;
typedef struct elevations {
size_t numValues;
short *elevations;
} Elevations;
Elevations elevs;
Metadata meta;
Bounds b = ...; // set up search boundary
Status stat = getElevationsFor(b, &elevs, &meta);
The service that I request elevation data from returns a 1-d sequence of values; the dimensions of the array are returned as part of the metadata.
You can do it using structures:
#include <stdio.h>
struct dont { int x; double y; };
struct dont fred(void)
{
struct dont b;
b.x = 1;
b.y = 91.99919;
return b;
}
int main(int argc, char **argv)
{
struct dont look = fred();
printf("look.x = %d, look.y = %lf\n", look.x, look.y);
return 0;
}
You cannot return multiple values from a C function.
You can either
Return a data structure with multiple values, like a struct or an array.
Pass pointers to the function and modify the values of the pointers inside the function. You need to pass x number of pointers where x is the number of return values you need
To return multiple values from a function we should use a pointer. Here is an example through which you can understand it better
int* twoSum(int* nums, int numsSize, int target) {
int i,j,*a;
a=(int*)malloc(2*sizeof(int));
for(i=0;i<numsSize;i++)
for(j=i+1;j<numsSize;j++)
if(nums[i]+nums[j]==target)
{
a[0]=i;
a[1]=j;
return a;
}
}
I´m a beginner in C, so I don´t have experience with array, pointer, structure. To get more than one value from my function I just used a global variable.
Here is my code:
#include <stdio.h>
double calculateCharges( double hourCharges );
// Global variable for totalCharges-function and main-function interaction
double totalCharges = 0;
int main ( void ) {
double car1 = 0;
double car2 = 0;
double car3 = 0;
double totalHours = 0;
printf( "%s", "Hours parked for Car #1: ");
scanf( "%lf", &car1 );
printf( "%s", "Hours parked for Car #2: ");
scanf( "%lf", &car2 );
printf( "%s", "Hours parked for Car #3: ");
scanf( "%lf", &car3 );
totalHours = car1 + car2 + car3;
printf( "%s", "Car\tHours\tCharge\n");
printf( "#1\t%.1f\t%.2f\n", car1, calculateCharges( car1 ));
printf( "#2\t%.1f\t%.2f\n", car2, calculateCharges( car2 ));
printf( "#3\t%.1f\t%.2f\n", car3, calculateCharges( car3 ));
printf( "TOTAL\t%.1f\t%.2f\n", totalHours, totalCharges);
}
double calculateCharges( double hourCharges ) {
double charges = 0;
if( hourCharges <= 3.0 ) {
charges = 2;
} else if ( hourCharges >= 24.0) {
charges = 10.00;
} else {
charges = ((hourCharges - 3.0)*0.5) + 2.0;
}
totalCharges += charges;
return charges;
}
Method 1 is using array
Method 2 is using pointer
Method 3 is using structure

How to access members of a `struct' according to a variable integer in C?

Suppose I have this struct (which incidentally contain bit-fields, but you shouldn't care):
struct Element {
unsigned int a1 : 1;
unsigned int a2 : 1;
...
unsigned int an : 1;
};
and I want to access the i'th member in a convenient way. Let's examine a retrieval solution.
I came up with this function:
int getval(struct Element *ep, int n)
{
int val;
switch(n) {
case 1: val = ep->a1; break;
case 2: val = ep->a2; break;
...
case n: val = ep->an; break;
}
return val;
}
But I suspect that there is a much simpler solution. Something like array accessing style, maybe.
I tried to do something like that:
#define getval(s,n) s.a##n
But expectedly it doesn't work.
Is there a nicer solution?
Unless you have specific knowledge of the underlying structure of the struct, there is no way to implement such a method in C. There are all sorts of problems that will get in the way including
Members of different sizes
Packing issues
Alignment issues
Tricks like bitfields will be problematic
You're best off implementing a method by hand for your struct which has a deep understanding of the internal members of the structure.
If every field in your struct is an int, then you should basically be able to say
int getval(struct Element *ep, int n)
{
return *(((int*)ep) + n);
}
This casts the pointer to your struct to a pointer to an array if integers, then accesses the nth element of that array. Since everything in your struct seems to be an integer, this is perfectly valid. Note that this will fail horribly if you ever have a non-int member.
A more general solution would be to maintain an array of field offsets:
int offsets[3];
void initOffsets()
{
struct Element e;
offsets[0] = (int)&e.x - (int)&e;
offsets[1] = (int)&e.y - (int)&e;
offsets[2] = (int)&e.z - (int)&e;
}
int getval(struct Element *ep, int n)
{
return *((int*)((int)ep+offsets[n]));
}
This will work in the sense that you'll be able to call getval for any of the int fields of your struct, even if you have other non-int fields in your struct, since the offsets will all be correct. However, if you tried to call getval on one of the non-int fields it would return a completely wrong value.
Of course, you could write a different function for each data type, e.g.
double getDoubleVal(struct Element *ep, int n)
{
return *((double*)((int)ep+offsets[n]));
}
and then just call the proper function for whichever datatype you'd want. Incidentally, if you were using C++ you could say something like
template<typename T>
T getval(struct Element *ep, int n)
{
return *((T*)((int)ep+offsets[n]));
}
and then it would work for whatever datatype you'd want.
If your struct was anything except bitfields, you could just use array access, if I'm right in remembering that C guarantees that a series of members of a struct all of the same type, has the same layout as an array. If you know which bits in what order your compiler stores bitfields into integer types, then you could use shift/mask ops, but that's then implementation-dependent.
If you want to access bits by variable index, then it's probably best to replace your bitfields with an integer containing flag bits. Access by variable really isn't what bitfields are for: a1 ... an are basically independent members, not an array of bits.
You could do something like this:
struct Element {
unsigned int a1 : 1;
unsigned int a2 : 1;
...
unsigned int an : 1;
};
typedef unsigned int (*get_fn)(const struct Element*);
#define DEFINE_GETTER(ARG) \
unsigned int getter_##ARG (const struct Element *ep) { \
return ep-> a##ARG ; \
}
DEFINE_GETTER(1);
DEFINE_GETTER(2);
...
DEFINE_GETTER(N);
get_fn jump_table[n] = { getter_1, getter_2, ... getter_n};
int getval(struct Element *ep, int n) {
return jump_table[n-1](ep);
}
And some of the repetition could be avoided by the trick where you include the same header multiple times, each time having defined a macro differently. The header expands that macro once for each 1 ... N.
But I'm not convinced it's worth it.
It does deal with JaredPar's point that you're in trouble if your struct mixes different types - here all the members accessed via a particular jump table must of course be of the same type, but they can have any old rubbish in between them. That still leaves the rest of JaredPar's points, though, and this is a lot of code bloat for really no benefit compared with the switch.
No, there is no simple way to do this easier. Especially for bitfields, that are hard to access indirectly through pointers (you cannot take the address of a bitfield).
You can of course simplify that function to something like this:
int getval(const struct Element *ep, int n)
{
switch(n)
{
case 1: return ep->a1;
case 2: return ep->a2;
/* And so on ... */
}
return -1; /* Indicates illegal field index. */
}
And it seems obvious how the implementation can be further simplified by using a preprocessor macro that expands to the case-line, but that's just sugar.
If the structure really is as simple as described, you might use a union with an array (or a cast to an array) and some bit-access magic (as in How do you set, clear and toggle a single bit in C?).
As Jared says, the general case is hard.
I think your real solution is to not use bitfields in your struct, but instead define either a set type or a bit array.
I suggest code generation. If your structures don't contain huge amount of fields you can auto generate routines for each field or for a range of fields
and use them like:
val = getfield_aN( myobject, n );
or
val = getfield_foo( myobject );
If you have
Only bitfields, or all the bitfields first in your struct
less than 32 (or 64) bitfields
then this solution is for you.
#include <stdio.h>
#include <stdint.h>
struct Element {
unsigned int a1 : 1;
unsigned int a2 : 1;
unsigned int a3 : 1;
unsigned int a4 : 1;
};
#define ELEMENT_COUNT 4 /* the number of bit fields in the struct */
/* returns the bit at position N, or -1 on error (n out of bounds) */
int getval(struct Element* ep, int n)
{
if(n > ELEMENT_COUNT || n < 1)
return -1;
/* this union makes it possible to access bit fields at the beginning of
the struct Element as if they were a number.
*/
union {
struct Element el;
uint32_t bits;
} comb;
comb.el = *ep;
/* check if nth bit is set */
if(comb.bits & (1<<(n-1))) {
return 1;
} else {
return 0;
}
}
int main(int argc, char** argv)
{
int i;
struct Element el;
el.a1 = 0;
el.a2 = 1;
el.a3 = 1;
el.a4 = 0;
for(i = 1; i <= ELEMENT_COUNT; ++i) {
printf("el.a%d = %d\n", i, getval(&el, i));
}
printf("el.a%d = %d\n", 8, getval(&el, 8));
return 0;
}
Based on eli-courtwright solution but without using array of field offsets
......
if you have a structure containing pointer field like this, maybe you could write:
struct int_pointers
{
int *ptr1;
int *ptr2;
long *ptr3;
double *ptr4;
std::string * strDescrPtr;
};
Then you know that every pointer has a 4 bytes offset from a pointer to the structure, so you can write:
struct int_pointers ptrs;
int i1 = 154;
int i2 = -97;
long i3 = 100000;
double i4 = (double)i1/i2;
std::string strDescr = "sample-string";
ptrs.ptr1 = &i1;
ptrs.ptr2 = &i2;
ptrs.ptr3 = &i3;
ptrs.ptr4 = &i4;
ptrs.strDescrPtr = &strDescr;
then, for example, for a int value you can write:
int GetIntVal (struct int_pointers *ep, int intByteOffset)
{
int * intValuePtr = (int *)(*(int*)((int)ep + intByteOffset));
return *intValuePtr;
}
Calling it by:
int intResult = GetIntVal(&ptrs,0) //to retrieve the first int value in ptrs structure variable
int intResult = GetIntVal(&ptrs,4) //to retrieve the second int value in ptrs structure variable
and so on for the others structure fields values (writing other specific functions and using correct bytes offset value (multiple of 4)).
Although the OP specifies that we shouldn't care about the contents of the struct, since they are just bitfields would it be possible to use a char or int (or whatever data type has the size required) to create an n-bit "array" in this case?
void writebit(char *array, int n)
{
char mask = (1 << n);
*array = *array & mask;
}
with the char types replaced with a larger type if a longer "array" was needed. Not sure this is a definitive solution in other structs but it should work here, with a similar readbit funcition.
If you want to access your structure using both element index:
int getval(struct Element *ep, int n)
and by name:
ep->a1
then you are stuck with some hard to maintain switch like method that everyone has suggested.
If, however, all you want to do is access by index and never by name, then you can be a bit more creative.
First off, define a field type:
typedef struct _FieldType
{
int size_in_bits;
} FieldType;
and then create a structure definition:
FieldType structure_def [] = { {1}, {1}, {1}, {4}, {1}, {0} };
The above defines a structure with five elements of size 1, 1, 1, 4 and 1 bits. The final {0} marks the end of the definition.
Now create an element type:
typedef struct _Element
{
FieldType *fields;
} Element;
To create an instance of an Element:
Element *CreateElement (FieldType *field_defs)
{
/* calculate number of bits defined by field_defs */
int size = ?;
/* allocate memory */
Element *element = malloc (sizeof (Element) + (size + 7) / 8); /* replace 7 and 8 with bits per char */
element->fields = field_defs;
return element;
}
And then to access an element:
int GetValue (Element *element, int field)
{
/* get number of bits in fields 0..(field - 1) */
int bit_offset = ?;
/* get char offset */
int byte_offset = sizeof (Element) + bit_offset / 8;
/* get pointer to byte containing start of data */
char *ptr = ((char *) element) + byte_offset;
/* extract bits of interest */
int value = ?;
return value;
}
Setting values is similar to getting values, only the final part needs changing.
You can enhance the above by extending the FieldType structure to include information about the type of value stored: char, int, float, etc, and then write accessors for each type which checks the required type against the defined type.
Why not build getval() in to the struct?
struct Whang {
int a1;
int a2;
int getIth(int i) {
int rval;
switch (i) {
case 1: rval = a1; break;
case 2: rval = a2; break;
default : rval = -1; break;
}
return rval;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Whang w;
w.a1 = 1;
w.a2 = 200;
int r = w.getIth(1);
r = w.getIth(2);
return 0;
}
getIth() would have knowledge of the internals of Whang, and could deal with whatever it contained.

Resources