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
Related
basically I have 2d array in a struct that I access through a pointer and i can't figure out how to access matrix[i][j] in my if statement
struct Matrix{
unsigned int matrix_size;
int matrix [MAX_MATRIX][MAX_MATRIX];
};
short is_matrix_ok(const struct Matrix*n){
for(int i=0;i<n-matrix_size;i++){
for(int j=0;j<n->matrix_size;j++){
if(n->(matrix+i)[j] ?????)
}
}
Thanks for your answer
Use n->matrix[i][j].
matrix is a member of the structure. matrix+i is not, so you cannot use n->(matrix+i). You must first get the member of the structure, n->matrix, and then you can apply operations to that, like n->matrix[i], which is equivalent to (n->matrix)[i], and then you can apply the next subscript, n->matrix[i][j].
If you want to access it using pointers rather than subscripts, then it would be n->matrix + i to calculate a pointer to subarray i. Then *(n->matrix + i) is that subarray. As an array, it is automatically converted to a pointer to its first element, so *(n->matrix + i) + j calculates a pointer to element j of subarray i. Finally, *(*(n->matrix + i) + j) is element j of subarray i.
Never use that pointer expression in normal code without good reason. Use the easier-to-read n->matrix[i][j].
Try the code below:
#include <stdio.h>
#define ROWS 3
#define COLS 2
struct Matrix{
int matrix[ROWS][COLS];
};
short read_matrix(struct Matrix *M){
int tmp = -100;
for(int i=0;i<ROWS;i++){
for(int j=0;j<COLS;j++){
scanf("%d\n", &tmp);
M->matrix[i][j] = tmp;
//printf("tmp is %d\n", tmp);
}
}
return(0);
}
short is_matrix_ok(const struct Matrix *M){
for(int i=0;i<ROWS;i++){
for(int j=0;j<COLS;j++){
printf("n[%d][%d] = %d\n",i,j,M->matrix[i][j]);
}
}
return(0);
}
int main(){
struct Matrix Mat;
read_matrix(&Mat);
is_matrix_ok(&Mat);
return(0);
}
If you input 1 to 6, output is as follows:
n[0][0] = 1
n[0][1] = 2
n[1][0] = 3
n[1][1] = 4
n[2][0] = 5
n[2][1] = 6
I have two identical arrays of struct , one in reverse order.
The problem is that i don't want duplicate the same data into the two arrays , i would a reversed array with elements pointing elements of the first array in a way that i can edit the members of struct of first array or from the reversed array taking effect in both.
you can view the source and run it online here https://onlinegdb.com/SJbepdWxS
#include <stdio.h>
typedef struct point{
int id;
float x,y,z;
} point;
void printPoints(point *pts,int len){
int i = 0;
while (pts !=NULL && i < len){
printf("id %d x %f y%f z %f\n",pts->id,pts->x,pts->y,pts->z);
pts++;
i++;
}
}
void translatePoints(point *pts,int len,float t){
int i = 0;
while (pts !=NULL && i < len){
pts->x = pts->x + t;
pts->y = pts->y + t;
pts->z = pts->z + t;
pts++;
i++;
}
}
void reversePoints(point *pts, int len, point *rev){
int i = 0;
int j = len;
while (i < len){
j=len-i-1;
rev[j]=pts[i];
i++;
}
}
int main()
{
int i;
int t1=200;
int t2=300;
int len=3;
point points[len];
point rev_points[len];
for(i=0; i<len ; i++){
points[i].id=i;
points[i].x=10+i;
points[i].y=20+i;
points[i].z=30+i;
}
//point * pts = points;
printf("\nprint points \n\n");
printPoints(points,len);
printf("\ntranslate points %d...\n\n",t1);
translatePoints(points,len,t1);
printf("\nprint points\n\n");
printf("\nreverse points to rev_points\n");
reversePoints(points,len,rev_points);
printf("\nprint rev_points \n\n");
printPoints(rev_points,len);
printf("\ntranslate rev_points %d...\n\n",t2);
translatePoints(rev_points,len,t2);
printf("\nprint rev_points\n\n");
printPoints(rev_points,len);
printf("\nprint points\n\n");
printPoints(points,len);
return 0;
}
I expect that struct values of both arrays change when i change value in one of the two array.
But changing values of struct in the first array , the second array not changes and the other way around.
One way to look at this is a set of points and two permutations on the set. This sets up a points array, which is used as a set, and forward_points and reverse_points as arrays of pointers to the point array that we are going to use as permutations.
#include <stdio.h>
struct Point {
int id;
float x,y,z;
};
/* Print a point. */
static void printPoint(struct Point *point) {
printf("id %d x %f y%f z %f\n",point->id,point->x,point->y,point->z);
}
/* These print out an array of pointers to point. */
static void printPointsRef(struct Point **ref, int len) {
struct Point **end = ref + len;
while(ref < end) printPoint(*(ref++));
}
/* This translates all the `pts` up to `len` by `(1,1,1)*t`. */
static void translatePoints(struct Point *pts, int len, float t) {
struct Point *end = pts + len;
while(pts < end) {
pts->x = pts->x + t;
pts->y = pts->y + t;
pts->z = pts->z + t;
pts++;
}
}
/* Helper function to `main`. */
static void printPoints(struct Point **forward_points,
struct Point **reverse_points, int len) {
printf("print points\nprint points forward:\n");
printPointsRef(forward_points,len);
printf("print points reverse:\n");
printPointsRef(reverse_points,len);
printf("\n");
}
int main(void)
{
const int len = 3;
/* This is the actual points structure. */
struct Point points[len];
/* These are arrays of pointers to points; they are
permutations of `points`. */
struct Point *forward_points[len], *reverse_points[len];
int i;
const int t1=200;
for(i=0; i<len; i++) {
/* Initialise element `i` of `points`. */
points[i].id=i;
points[i].x=10+i;
points[i].y=20+i;
points[i].z=30+i;
/* Initialise element `i` of `forward_points`
to point to `points[i]`, and `backward_points`
to point the other way (it doesn't matter that
the backwards points are uninitialised, they
will be.) */
forward_points[i] = &points[i];
reverse_points[i] = &points[len - 1 - i];
}
printPoints(forward_points, reverse_points, len);
/* Translation is a vector space operation and doesn't
care about order; we just do it on the original points. */
printf("translate points %d...\n\n",t1);
translatePoints(points,len,t1);
printPoints(forward_points, reverse_points, len);
return 0;
}
Of course, there is no integrity constraints on the pointers; nothing stopping one from pointing at anything, null, the same elements, or anything else.
I added an other struct with one element that is a pointer
typedef struct ptr_point{
point * p;
} ptr_point;
I edited the function reversePoints
void reversePoints(point *pts, int len, ptr_point *rev){
// This function is used only to test pointers
int i = 0;
int j = len;
while (i < len){
j=len-i-1;
rev[j].p = &pts[i];
i++;
}
}
and added another function to print ptr_points
void printPtrPoints(ptr_point *pts,int len){
int i = 0;
while (i < len){
printf("id %d x %f y%f z %f\n",pts->p->id,pts->p->x,pts->p->y,pts->p->z);
pts++;
i++;
}
}
and declaring the second array as ptr_point array
ptr_point rev_points[len];
In conclusion : now data in the second array are not replicated but pointing to element structure of the first array.
The need to not replicate data arise in presence of millions of coordinate points that if replicate more than one time , sorting it for example by x, y, z and so on , occupe much memory with the difficulty of managing .
This fix however forces me to use structures->type in order to change the access mode to read or set values.
I don't know if this is the best solution but it has solved the problem for not duplicate the data.
you can run the source with fixes here: https://onlinegdb.com/SknP_i-eS
Thank you all for the advice.
So I have an exercice that asks me to define a structure that has 2 fields: one field to store an array of an already defined size, one field to store the length of the array. Then I have to define a function that should initialize the 2 fields in the structure, and another funciton that prints the 2 fields
I'm just a beginner in programming, here's my attempt to write the code, but it doesn't seem to work. Thanks in advance for the help.
#include<stdio.h>
#include<string.h>
#define SIZE 10
typedef struct stdata data{
int array[SIZE];
int length;
}
void initialize (int array[],int length){
data p;
p.array[SIZE]=array;
p.length=length;
}
void print(data p){
printf("%d %d ",p.array,p.length);
}
You can do it in two different ways both are correct:
Method 1:
memcpy(p.array, array, sizeof(int) * length);
Method 2: (using a loop)
for (int i = 0; i < length; i++) p.array[i] = array[i];
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.
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.