Structs and passing values to them - c

If i had an array such as int numbers[5] i could assign values to it with numbers[0] = 1 or numbers[3] = 4. Then if i had a struct such as
struct structName
{
int number0;
int number1;
int number2;
};
is there any way to do something like the following (note this is not working code)
int main(void)
{
struct structName name; //how could i declare this to do the following
for(int i = 0; i < 2; i++)
{
name[i] = i; //maybe name.[i]
}
}
so is there a way to write name[ variable ] = someNumber to assign someNumber to say number0 (if variable was 0) or number2 (if variable was 2). ive been looking for days and cant find anything that does this. (maybe i just don't know what to look for)

is there any way to do something like the following
No, there's no way to access the fields of the structure by index. You use the names of the fields instead:
struct structName name;
name.number0 = someNumber;
name.number1 = someOtherNumber;
If you want to access the values by index, use an array instead, even if it's embedded in the structure:
struct structName
{
int numbers[3];
// other fields here
};
Then you can say:
struct structName name;
for (int i = 0; i <= 2, i++) {
name.numbers[i] = i;
}

You could write a function which uses a switch statement that allows you to access fields by index. Something like:
#include<stdio.h>
struct structName{
int number0;
int number1;
int number2;
};
void assign(struct structName * name, int i, int j){
switch(i){
case 0:
name->number0 = j;
break;
case 1:
name->number1 = j;
break;
case 2:
name->number2 = j;
break;
}
}
int main(void){
int i;
struct structName name;
for(i = 0; i <= 2; i++){
assign(&name,i,i);
}
//test:
printf("%d\n",name.number0);
printf("%d\n",name.number1);
printf("%d\n",name.number2);
return 0;
}
(which prints 0,1,2 as expected).
Needless to say, there isn't much point in doing this (as opposed to just having a field which is an array) unless the struct in question is already defined as part of an API or already part of a code base which isn't easily refactored.

Yes, with some weird and inadvisable memory manipulation. You're much better off using an array.
struct structName
{
int numbers[3];
};
int main(void)
{
struct structName name;
for(int i = 0; i <= 2; i++)
{
name.numbers[i] = i;
}
}
Also note that you had some syntax errors in your for loop and an off-by-one error.

Macros with arguments should work
#define name(x) x
So name(1) would become 1. name(2) would become 2 and so on.

In C, there is no spoon.
struct structName name;
int *idx = &name; // First we need a memory address to the struct
for (int i = 0; i < sizeof(name) / sizeof(*idx); ++i) {
// idx[i] == name.numberX
idx[i] = i;
}
Now, if you check the values of name.number0, name.number1, name.number2 you will see they contain the correct values.
This is not a very good way of doing things with structs, but I felt compelled to answer after the top response claims it is impossible.

Related

Understanding part of an algorithm

Below is a part of an algorithm i was given to use for a project, but as it's my first time to use an algorithm i don't understand the following lines. Please will need your help.
For i=1 to n do
t[i] .mark <-- 0
t[i] .num <-- -1
End
This pseudo code can be translated to C
Use struct
struct cm{
int mark;
int num;
};
#define N 10
int main(void)
{
struct cm t[N];
for (int i=0;i<N;i++){
t[i].mark = 0;
t[i].num = -1;
}
//print your struct elements field
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,t[i].mark, t[i].num);
}
}
We have an array of struct because of we need each element of it have two field of data (i.e. mark,num).
struct cm t[N]; define a N length array of structure cm.
In loop we assign to each field of array elements proper values.
For more readability you can use typedef instead of using struct to define your desire data structure in this case.
typedef vs struct
Use typedef
typedef struct typecm{
int mark;
int num;
}typecm;
#define N 10
int main(void)
{
typecm s[N];
for (int i=0;i<N;i++){
s[i].mark = 0;
s[i].num = -1;
}
//print values
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,s[i].mark, s[i].num);
}
}
The "t" seems to be an array of objects, and "mark" and "num" are properties of the object.
This may help you:
From an array of objects, extract value of a property as array

Generate random numbers for member of struct

I would like to have the user define the number of random numbers they would like to be stored in a member of my struct.
Here is what I have so far.
struct BigInt {
int A;
int rdm;
};
struct BigInt A[300];
struct BigInt rdm[10]={0,1,2,3,4,5,6,7,8,9};
printf("Number");
int len;
scanf("%i",&len);
srand(time(NULL));
int i=0;
while (i!=len){
int r=rand()%10;
A[i]=rdm[r];
printf("\nr:%i\n",r);
printf("A[i]:%i",A[i]);
i++;
}
But I am getting strange values and it's not working as I expect it to be. I have no idea why, what am I doing wrong?
The following snippet of code solves your problem basing on your comment below. You haven't completely understood how to use structure perhaps. Note that to use member of a structure you must use the . symbol
struct BigInt {
int *A;
};
struct BigInt bigIntVar = {
NULL
};
printf("Number");
int len;
scanf("%i", &len);
bigIntVar.A = (int*)malloc(len * sizeof(int));
srand(time(NULL));
int i = 0;
while (i != len) {
int r = rand() % 10;
bigIntVar.A[i] = r + 1;
printf("\nr:%i\n", r);
printf("A[i]:%d", bigIntVar.A[i]);
i++;
}

C- Iterating over an array of structs passed through a void*

I have a function
struct Analysis reduce (int n, void* results)
Where n is the number of files to be analyzed, and I'm passing an array of Analysis structs to results.
The Analysis struct is defined as follows:
struct Analysis {
int ascii[128]; //frequency of ascii characters in the file
int lineLength; //longest line in the file
int lineNum; //line number of longest line
char* filename;
}
I've cast the void * as such,
struct Analysis resArray[n];
struct Analysis* ptr = results;
resArray[0] = ptr[0];
but I can't figure out how to iterate through the resArray properly. I've tried
for (i = 0; i < n; i++){
printf("lineLength: %d\n", resArray[i].lineLength);
}
with n = 3, and I'm getting garbage values. resArray[0] is correct, but resArray[1] is an insanely high number and resArray[2] is just 0. Why wouldn't resArray[1] or resArray[2] give the correct values? If I was incrementing the address incorrectly then it would make sense but I'm just accessing the array at a certain index. Pretty lost here!
resArray[0] is correct because there is "something":
resArray[0] = ptr[0];
Other elements are garbage because you didn't set there any values. If you want to copy entire array you need to change copying method to:
for (i = 0; i < n; i++)
{
resArray[i] = ptr[i];
}
You can't assign a pointer to an array directly because they are different typessince array[n] is type struct analysis(*)[n] and ptr is type struct analysis(*). Check here for more info.
Hopefully this code will help you.
#include <stdio.h>
#define d 3
struct Analysis {
int ascii[128];
int lineLength;
int lineNum;
char *filename;
};
struct Analysis Analyses[d];
struct Analysis reduce(int n, void *results) {
struct Analysis resArray[n];
struct Analysis *ptr = results;
for (int i = 0; i < n; i++) {
resArray[i] = ptr[i];
}
for (int i = 0; i < n; i++) {
printf("lineLength: %d\n", ptr[i].lineLength);
}
return *ptr;
}
int main(void) {
struct Analysis a = {{5}, 2, 2, "George"};
struct Analysis b = {{6}, 3, 3, "Peter"};
struct Analysis c = {{7}, 4, 4, "Jane"};
Analyses[0] = a;
Analyses[1] = b;
Analyses[2] = c;
reduce(d, &Analyses);
return 0;
}
You can try it online.

array initialization for one of the elements in the structure

I have initialized the array for one of the element in the structure, there were some errors in printing the output, please point the errors and guide in solving it . Thanks!
#include<stdio.h>
typedef struct person
{
int row[3];
int age;
}PERSON;
int main()
{
int i;
PERSON p;
PERSON *pptr=&p;
pptr->row[3] = {4,5,6};
for (i = 0; i < 3; i++) {
printf (" %d\n", pptr->row[i]);
}
return 0;
}
Array objects in C language are not assignable. You cannot set the values in the entire array by using assignment. So, to do what you are trying to do using assignment syntax is impossible.
You had a chance to initialize your array at the point of declaration, i.e. when you defined object p
PERSON p = { { 4, 5, 6 } };
but you did not use that chance. After that it is too late to do it using pure core language features.
To set the values in the entire array after the point of declaration you can use a library function, like memcpy, in combination with a compound literal
memcpy(pptr->row, (int []) {4, 5, 6}, sizeof pptr->row);
You can't assign values to array like this: pptr->row[3] = {4,5,6};. Such syntax is valid only at initialization. You need to set each value manually or initialize your array with the values you want, something like this: PERSON p = {{4,5,6}, 0};.
#include<stdio.h>
typedef struct person
{
int row[3];
int age;
}PERSON;
int main()
{
int i;
PERSON p;
PERSON *pptr=&p;
pptr->row[0] = 4;
pptr->row[1] = 5;
pptr->row[2] = 6;
for (i = 0; i < 3; i++) {
printf (" %d\n", pptr->row[i]);
}
return 0;
}
You can't initialize array like this pptr->row[3] = {4,5,6};, You can use the above method or use for loop to initialize array..
When you have done PERSON p;. object p is created containing indeterminate values.
It means all the data members are already initialized with garbage since it's on stack.
So, pptr->row[3] = {4,5,6}; is not the initialization of the array an not allowed in this case. The for loop method is the best in this case.
for (i = 0; i < 3; i++)
scanf("%d",&(pptr->row[i])); // prenthrsis is for human readability

How do you make an array of structs in C?

I'm trying to make an array of structs where each struct represents a celestial body.
I don't have that much experience with structs, which is why I decided to try to use them instead of a whole bunch of arrays. However, I keep on running into numerous different errors. I've tried to implement the techniques that I've seen on various threads and on StackOverflow (such as Array of structs in C and C - initialize array of structs), however not all of them were applicable.
Further information for those who have read this far: I don't need any of this to be dynamic, I know/define the size of everything beforehand. I also need this to be a global array as I'm accessing this in several different methods which have defined arguments (i.e. GLUT methods).
This is how I'm defining the struct in my header:
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
I have a list of other global variables that I'm defining before I define the interior of the struct, and one of those is the array of this struct (basically, if I'm being too unclear in my fogged speak, the line below is above the stuff above):
struct body bodies[n];
Just so you know, n is something that I've legitimately defined (i.e. #define n 1).
I use this array in several different methods, but the easiest and least space consuming one is a simplified form of my main. Here I initialize all of the variables in each of the structs, just to set the variables for certain before I modify them in some way:
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
The current error that I'm facing is nbody.c:32:13: error: array type has incomplete element type where line 32 is where I'm making the array of the structs.
One last clarification, by header I mean the space above int main(void) but in the same *.c file.
#include<stdio.h>
#define n 3
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
struct body bodies[n];
int main()
{
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
return 0;
}
this works fine. your question was not very clear by the way, so match the layout of your source code with the above.
Another way of initializing an array of structs is to initialize the array members explicitly. This approach is useful and simple if there aren't too many struct and array members.
Use the typedef specifier to avoid re-using the struct statement everytime you declare a struct variable:
typedef struct
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
}Body;
Then declare your array of structs. Initialization of each element goes along with the declaration:
Body bodies[n] = {{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0},
{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0},
{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}};
To repeat, this is a rather simple and straightforward solution if you don't have too many array elements and large struct members and if you, as you stated, are not interested in a more dynamic approach. This approach can also be useful if the struct members are initialized with named enum-variables (and not just numbers like the example above) whereby it gives the code-reader a better overview of the purpose and function of a structure and its members in certain applications.
So to put it all together by using malloc():
int main(int argc, char** argv) {
typedef struct{
char* firstName;
char* lastName;
int day;
int month;
int year;
}STUDENT;
int numStudents=3;
int x;
STUDENT* students = malloc(numStudents * sizeof *students);
for (x = 0; x < numStudents; x++){
students[x].firstName=(char*)malloc(sizeof(char*));
scanf("%s",students[x].firstName);
students[x].lastName=(char*)malloc(sizeof(char*));
scanf("%s",students[x].lastName);
scanf("%d",&students[x].day);
scanf("%d",&students[x].month);
scanf("%d",&students[x].year);
}
for (x = 0; x < numStudents; x++)
printf("first name: %s, surname: %s, day: %d, month: %d, year: %d\n",students[x].firstName,students[x].lastName,students[x].day,students[x].month,students[x].year);
return (EXIT_SUCCESS);
}
I think you could write it that way too. I am also a student so I understand your struggle. A bit late response but ok .
#include<stdio.h>
#define n 3
struct {
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
}bodies[n];
move
struct body bodies[n];
to after
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
Rest all looks fine.
Solution using pointers:
#include<stdio.h>
#include<stdlib.h>
#define n 3
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double *mass;
};
int main()
{
struct body *bodies = (struct body*)malloc(n*sizeof(struct body));
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
return 0;
}
That error means that the compiler is not able to find the definition of the type of your struct before the declaration of the array of structs, since you're saying you have the definition of the struct in a header file and the error is in nbody.c then you should check if you're including correctly the header file.
Check your #include's and make sure the definition of the struct is done before declaring any variable of that type.
You can do it in a same manner as you create the array of numbers but wrap the element's values in braces like this ->
struct Wrestler studs[count] = {
{"John", "Cena"},
{"The", "Undertaker"},
{"The", "Big Show"},
{"The", "Rock"},
{"Triple", "H"},
{"Scott", "Hall"},
{"Roman", "Reings"},
{"Dean", "Ambrose"}};
Here is full code
#include <stdio.h>
struct Wrestler
{
char firstName[20];
char secondName[20];
};
void pIntro(struct Wrestler *s)
{
printf("Hi, I am %s %s.\n", s->firstName, s->secondName);
};
int main(int argc, char const *argv[])
{
#define count 8
struct Wrestler studs[count] = {
{"John", "Cena"},
{"The", "Undertaker"},
{"The", "Big Show"},
{"The", "Rock"},
{"Triple", "H"},
{"Scott", "Hall"},
{"Roman", "Reings"},
{"Dean", "Ambrose"}};
for (int i = 0; i < count; i++)
{
pIntro(&(studs[i]));
}
return 0;
}

Resources