How can i pass a structure to a function - c

I have called a function with seven parameters from main
find_sync(es_data + (loop_count * size) + chunk_bytes_counter,
size - chunk_bytes_counter, &sync_index, &flag,
&sync_length, &chunk_bytes_counter, &total_bytes_counter);
in function.c:
void find_sync(char data[], size_t size, unsigned int *sync_index, int *flag, unsigned int *sync_length, unsigned int *chunk_bytes_counter, unsigned int *total_bytes_counter)
prototype in header file:
extern void find_sync(char data[], size_t size, unsigned int *sync_index, int *flag, unsigned int *sync_length, unsigned int *bytes_counter, unsigned int *total_bytes_counter);
Now, my question is, how can i declare all these 7 parameters in a structure, so that i can only pass one structure variable.

Begin by declaring the struct:
struct find_sync_parameters {
char* data;
size_t size;
unsigned int *sync_index;
int *flag;
unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
}
Then change your function signature either to:
void find_sync(struct find_sync_parameters param)
Or to
void find_sync(struct find_sync_parameters *param)
In the first case the whole struct will be pushed onto the stack before transferring control to find_sync. On the second case only a pointer to the struct (stored elsewhere) will be pushed.
There are advantages and drawbacks in each one. When passing a pointer note that the function can change the contents (this can be positive: for returning values directly inside the struct; also can be negative: the caller cannot be sure if its data were changed or not). If the struct is too big (not your case), then pushing everything onto the stack can take a significant amount of time and become a performance hit.
Inside the function you use it either with '.' (dot, the first case) or '->' (arrow, the second case) operator.
To call it:
struct find_sync_parameters p = { ... };
find_sync(p); // first case
find_sync(&p); // second case
If you find it annoying to type struct find_sync_parameters everytime you can define a new type with typedef:
typedef struct find_sync_parameters find_sync_parameters;
Or in one line (struct and typedef definitions):
typedef struct find_sync_parameters {
...
} find_sync_parameters;
Or even without struct name (anonymous struct)
typedef struct {
...
} find_sync_parameters;
In this last case you cannot reference the struct itself inside the struct (the case, for example, with linked list nodes).

Just put in structure .
struct pars_t
{
char data[];
size_t size; unsigned int *sync_index;
int *flag; unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
} pars;
and then call foo (pars_t par)

You can create a struct (and typedef it at the same time, to make it usable without saying "struct" every time) like so:
typedef struct _find_sync_str{
char* data;
size_t size;
unsigned int *sync_index;
int *flag;
unsigned int *sync_length;
unsigned int *bytes_counter;
unsigned int *total_bytes_counter;
} find_sync_str
Then you can list the function as:
void find_sync(find_sync_str f);

I am going to suggest:
struct find_sync_struct {
char* data;
size_t size;
unsigned int sync_index;
int flag;
unsigned int sync_length;
unsigned int bytes_counter;
unsigned int total_bytes_counter;
};
Change the input argument of find_sync to:
void find_sync(struct find_sync_struct* strPtr);
Call the function using:
struct find_sync_struct str;
// Set str.data to something suitable.
// ....
find_sync(&str);

Here is a simple example demonstrating how to pass a structure to a function:
#include<stdio.h>
#include<conio.h>
//-------------------------------------
struct Example
{
int num1;
int num2;
}s[3];
//-------------------------------------
void accept(struct Example *sptr)
{
printf("\nEnter num1 : ");
scanf("%d",&sptr->num1);
printf("\nEnter num2 : ");
scanf("%d",&sptr->num2);
}
//-------------------------------------
void print(struct Example *sptr)
{
printf("\nNum1 : %d",sptr->num1);
printf("\nNum2 : %d",sptr->num2);
}
//-------------------------------------
void main()
{
int i;
clrscr();
for(i=0;i<3;i++)
accept(&s[i]);
for(i=0;i<3;i++)
print(&s[i]);
getch();
}

Related

How to pass a pointer to the array of structure in another fuction

I am trying to pass pointer to an array of structures to another function
#include<stdio.h>
#include<string.h>
typedef struct CovidData{
char region[7];
char towns[12];
char race[12];
int yearlyIncome;
int members;
int testedMembers;
int testedPositive;
} CovidData;
void RandomDataGenerator(CovidData *data[] ,int count)
{
for(int i=0;i<count;i++){
memcpy(data[i]->region,"david",sizeof("david"));
memcpy(data[i]->towns,"david",sizeof("david"));
memcpy(data[i]->race,"david",sizeof("david"));
data[i]->yearlyIncome=1000;
data[i]->members=99;
data[i]->testedMembers=88;
data[i]->testedPositive=656;
}
}
int main() {
struct CovidData data[100];
RandomDataGenerator(&data,2);
for(int i=0;i<5;i++){
printf("%s",data[i].region);
}
}
But it throws an error while compiling in terminal with gcc
incompatible pointer types passing 'CovidData (*)[100]' to
parameter of type 'CovidData
CovidData *data[] is grouped as CovidData *(data[]), so it declares an array of pointers to CovidData. For a pointer to an array, you would use CovidData (*data)[].
However, we rarely pass a pointer to an array. Usually, it is sufficient and convenient merely to pass a pointer to the first element. Thus, you would declare the parameter as CovidData *data and pass it as RandomDataGenerator(data, 2).
If you did declare the parameter as a pointer to an array, you would not use it with data[i]->region. You would need *data to get the array before applying the subscript, and again you would need parentheses for correct grouping: (*data)[i]->region.
Change your function to void RandomDataGenerator(CovidData *data ,int count); and pass only the pointer to the first array element, like this RandomDataGenerator(data,2);
#include<stdio.h>
#include<string.h>
typedef struct CovidData{
char region[7];
char towns[12];
char race[12];
int yearlyIncome;
int members;
int testedMembers;
int testedPositive;
} CovidData;
void RandomDataGenerator(CovidData *data ,int count)
{
for(int i=0;i<count;i++){
memcpy(data[i].region,"david",sizeof("david"));
memcpy(data[i].towns,"david",sizeof("david"));
memcpy(data[i].race,"david",sizeof("david"));
(data+i)->yearlyIncome=1000;
data[i].members=99;
data[i].testedMembers=88;
data[i].testedPositive=656;
}
}
int main() {
struct CovidData data[100];
RandomDataGenerator(data,2);
for(int i=0;i<5;i++){
printf("%s\n",data[i].region);
}
}

Freeing a pointer to a string in a structure [in C]

i'm trying to find the most efficient way to use the 'free' command in a program I made. Basically there are several structers, the first is called Operation. Here's how it's defined -
struct Operation {
unsigned int ic;
unsigned int dc;
struct symbolStruct *externHead;
struct symbolStruct *symbolHead;
struct DataCode *dataHead;
struct MachineCode *machineHead;
int linenumber;
};
It has several pointers to other structers, let's take machineHead for example.
struct MachineCode {
unsigned int row : WORD_SIZE;
unsigned int line;
OperandType *structure;
struct MachineCode *next;
};
And OperandType looks like this -
typedef struct {
unsigned int numOfOperands : 2;
unsigned int addrMethSou : 2;
unsigned int addrMethDest : 2;
unsigned int operation : 4;
unsigned int extraWords : 2;
char *firstOperand;
char *secondOperand;
} OperandType;
What I want to do is to free the strings "firstOperand" and "secondOperand" in structure (which is in machineHead ) and then to free machineHead itself, I tried to write it down using the following code -
void clear(struct Operation *op) {
struct MachineCode *mh = op->machineHead, *fmh;
while(mh != NULL) {
fmh = mh;
mh = mh->next;
free(fmh->structure->firstOperand);
free(fmh->structure->secondOperand);
free(fmh->structure);
free(fmh);
}
But the program crashes in runtime. Is there an elegant way to do it or do I have to make a pointer varibale of every type in order to clear the memory?

Diab Compiler, Does it automatically optimize array and structure initialization ?

Hi,
I'm using Diab 5.8.0 as a compiler for my C source code.
I've recognized that if I have a program like this:
typedef struct
{
int field_1;
int field_2;
int field_3;
} Struct_Type;
int main()
{
Struct_Type temp_st = {1,1,1};
return temp_st.field_1;
}
It seems to be converted to this (the return value is 0 instead of 1)
typedef struct
{
int field_1;
int field_2;
int field_3;
} Struct_Type;
int main()
{
Struct_Type temp_st;
return temp_st.field_1;
}
There is same problem with array initialization,
This:
int main()
{
int array[3]={1,1,1};
return array[0];
}
is converted to this:
int main()
{
int array[3];
return array[0];
}
I think the issue is from the optimization of Diab Compiler so I do not use any optimize-flag when compile code but the issue is still there.
Could you help me if you know the root cause of this and the solution if I want to init value for struct and array right at the declaration?

Why updated structure variable not printing

This is my code in which if student marks is greater than 85,scholarship status will be changed to sanctioned, but after updating it is not printing
#include<stdio.h>
#include<string.h>
struct scholor
{
char name[25];
int sem;
int marks;
char status;
};
void sanction(int m, char *s)
{
if(m>85)
{
char p[15]="sanctioned";
char *r;
r=p;
while(*r!='\0')
{
*s=*r;
s++;
r++;
}
*s='\0';
}
}
int main()
{
struct scholor s1;
scanf("%s%d%d%s",&s1.name,&s1.sem,&s1.marks,&s1.status);
sanction(s1.marks,&s1.status);
printf("%s",s1.status);
}
status is a single char but you are storing a string into it, effectively doing out of bounds access (undefined behaviour). Change it to an array and then you'll be able to copy.
struct scholor
{
char name[25];
int sem;
int marks;
char status[128];
};
and adjust the calls and passing (since status is an array now -- its name gets converted into a pointer t its first element when passed to functions):
scanf("%s%d%d%s",s1.name,&s1.sem,&s1.marks,s1.status);
sanction(s1.marks,s1.status);
printf("%s",s1.status);
Other suggestions:
1. Use a standard prototype for main such as: int main(void)
2. You could usr strcpy to copy the string as opposed to doing it yourself.
Your struct should have status as a character array not a character .Moreover when you scanf an array dont write & before because the name itself points to the assdress of the first element.Your corrected program is :
struct scholor
{
char name[25];
int sem;
int marks;
char status[16];
};
void sanction(int m, char *s)
{
if(m>85)
{
char p[15]="sanctioned";
char *r;
r=p;
while(*r!='\0')
{
*s=*r;
s++;
r++;
}
*s='\0';
}
}
int main()
{
struct scholor s1;
scanf("%s%d%d%s",s1.name,&s1.sem,&s1.marks,s1.status);
sanction(s1.marks,s1.status);
printf("%s",s1.status);
}

Instantiations for structs in C?

So I'm trying to learn C right now, and I have some basic struct questions I'd like to clear up:
Basically, everything centers around this snippet of code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN 127
const char* getName(const Student* s);
void setName(Student* s, const char* name);
unsigned long getStudentID(const Student* s);
void setStudentID(Student* s, unsigned long sid);
int main(void) {
Student sarah;
const char* my_name = "Sarah Spond";
setName(&sarah, my_name);
printf("Name is set to %s\n", sarah.name);
}
typedef struct {
char name[MAX_NAME_LEN + 1];
unsigned long sid;
} Student;
/* return the name of student s */
const char* getName (const Student* s) { // the parameter 's' is a pointer to a Student struct
return s->name; // returns the 'name' member of a Student struct
}
/* set the name of student s
If name is too long, cut off characters after the maximum number of characters allowed.
*/
void setName(Student* s, const char* name) { // 's' is a pointer to a Student struct | 'name' is a pointer to the first element of a char array (repres. a string)
int iStringLength = strlen(name);
for (i = 0; i < iStringLength && i < MAX_NAME_LEN; i++) {
s->name[i] = name[i];
}
}
/* return the SID of student s */
unsigned long getStudentID(const Student* s) { // 's' is a pointer to a Student struct
return s->sid;
}
/* set the SID of student s */
void setStudentID(Student* s, unsigned long sid) { // 's' is a pointer to a Student struct | 'sid' is a 'long' representing the desired SID
s->sid = sid;
}
However, when I try and compile the program, I get a bunch of errors saying that there's an "unknown type name Student". What am I doing wrong?
Thanks!
Move the type definition for Student - the typedef .. right after #define MAX_NAME_LEN 127, i.e. before it's being referenced.
You need to move the declaration of the Student struct above the first time it is referenced by other code - otherwise those functions will not know what it is.
Struct declarations need to be defined before you use them , so you need to move your Student
As cnicutar said, move the typedef - the reason for this is that the type must be known before it's used. Alternatively, you can forward declare the type.
> Move the typedef .. right after #define MAX_NAME_LEN 127, i.e. before
> it's being used.
OR, if you want to keep your definition after, and if you are ready to use a pointer to Student, you can:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN 127
// forward declare Student ici
struct Student;
//...
// in main, use a pointer to student
int main(void) {
Student *sarah; // Changed to pointer
const char* my_name = "Sarah Spond";
setName(sarah, my_name); // Pass the pointer instead of reference
printf("Name is set to %s\n", sarah->name); // Use the pointer
//....
delete sarah; // delete object when done
}
// Change struct decl to the following // can't explain the diff yet
struct Student {
char name[MAX_NAME_LEN + 1];
unsigned long sid;
};
A basic structure of a C program is:
//======DOCUMENT SECTION=========
//File:test.c
//Author:
//Description:
//...
//================================
//====INCLUDE SECTION=============
#include "lib1"
#include <lib2>
//================================
//========DEFINITIONS SECTION=====
#define TRUE 1
#define FALSE 0
//================================
//========STRUCTURES SECTION======
struct P{
};
//================================
//========TYPEDEFS SECTION========
typedef *P P;
//================================
//========FUNCTION HEADERS========
void foo1(...);
int foo2(...,...,...);
//================================
//=========GLOBAL VARIABLES=======
int GLOBAL_INT;
float GLOBAL_FLOAT;
//================================
//=====MAIN FUNCTION DEFINITION===
void main(void)
{
...
...
...
}
//=================================
//======FUNCTIONS DEFINITION======
void foo1(...)
{
}
int foo2(...,...,...)
{
}
//================================
A main function is where a C program starts. A main function also typically has access to the command arguments given to the program when it was executed.
Usually you have got:
int main(void);
int main();
int main(int argc, char **argv);
int main(int argc, char *argv[]);

Resources