Accessing a struct without the struct being global - c

I've got a struct called members which contains a bunch of char arrays and integers. The struct has been declared in Header.h and defined it by "struct members pt" in source.c, inside main. From here a for-loop is being runned 5 times and adding variables to the character arrays and ints in pt[x].
Now I need to be able to access this from a function called void search(int a); (Should probably not be a void since I want it to return a value. But I'll fix that later)
What void search is supposed to do is basicly
int willReturn[10];
int b = 0;
for(int x = 0; x<a; x++)
{
if(pt[x].hasPayed == 0)
{
willReturn[b] = x;
b++;
}
}
There might be something wrong about that code, but the thing that I need to know is how I can access pt[x].hasPayed.
Any ideas?
I do not want to use any global variables.
Thank you in advance.

Below sample code might help you.
header.h
struct members {
int hasPayed;
};
main.c
#include <stdio.h>
#include <string.h>
#include "main.h"
typedef struct members MEMBERS;
void print_member(MEMBERS *pt) {
int i;
for(i =0 ; i< 10; i++)
{
printf(" %d\n",pt[i].hasPayed);
}
}
void main () {
MEMBERS pt[10];
int i;
for(i =0 ; i< 10; i++)
{
pt[i].hasPayed= i;
}
print_member(pt);
}
Instead of print_member code your search logic.

Pass a pointer to pt as a paraamter to search. e.g void search(int a, struct members *pt).

Another way if you don't want to pass pointers. Place pt in a function as a static variable.
struct members** ____get_pt(){
static struct members pt[ /* size */ ];
/*
or for dynamical size,
static struct members* pt;
*/
return &pt;
}
// Define a macro for convenience, above where you want to use 'pt'.
#define PT (*____get_pt())
Then you can use PT[x].hasPayed everywhere, without global variables.
However, this could do not improve your code ...

Related

How to run a function using a function pointer that located in a struct? (C)

I want to create an array of structs based on one struct definition, and initialize each one with a different int value.
Then, I want to print this value, using a function pointer that points to a print function.
Define a struct (includes an int and a function pointer).
create an array of 10 structs of the same definition.
set different values for each one of them.
send this value for a function that is pointed to by a function
pointer that is also located in the struct
This is my code:
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
void Print(int num);
typedef struct print_me
{
int x;
void (*Print)(int x);
};
struct print_me my_prints[ARRAY_SIZE];
int main()
{
size_t i = 0;
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].x = i;
my_prints[i].Print(my_prints[i].x);
}
return 0;
}
void Print(int num)
{
printf("%d\n",num);
}
I'm still learning the ideas of function pointer and structs , so I'll be glad to get some tips and suggestions that will help me to understand my mistakes here.
Thanks.
For starters there is no any sense to use the typedef specifier in this declaration
typedef struct print_me
{
int x;
void (*Print)(int x);
};
without specifying a typedef name. You could write for example
typedef struct print_me
{
int x;
void (*Print)(int x);
} print_me;
In the for loop you need to initialize the data member Print with the address of the function Print. For example
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].x = i;
my_prints[i].Print = Print;
}
then in a second for loop you could call the function like
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].Print( my_prints[i].x );
}
As with usual pointers, you have to set a pointer value before you can use it. So that it points somewhere.
Add:
my_prints[i].Print = &Print;
// or, it means the same, & is optional
// my_prints[i].Print = Print;
my_prints[i].Print(my_prints[i].x); // now ok
before calling my_prints[i].Print() so that the pointer will point to function Print before calling it.
Side note with a fun fact: because of the strange C rules, dereferencing the function pointer is not needed, and you can even like "dereference" the function pointer multiple times, like (****my_prints[i].Print)(). See ex this question.

Adding a parameter block to a function

Yesterday I had a problem with a function, turned out I forgot to declare a variable of the structure type, it is clear now what was the problem. I've modified my code, and I got another error messages, however it looks like the code actually s working.
I googled the problem but I can't really fit the solutions to my code. Can somebody shows and explain me what would be the clean way of the below code?
#include <stdio.h>
/*************************************************
include
**************************************************/
//A signal structure
typedef struct SIGNAL_STRUCTURE
{
int id;
int time;
}signal_structure;
//Structure what collects all the signals
typedef struct SIGNAL_COLLECTOR
{
signal_structure EngSpeed;
signal_structure TransReqGear;
signal_structure CurrentGear;
}signal_collector;
//Function to do with the above structure
void ManipulateSignal(signal_structure * signal)
{
signal->id = 10;
signal->time = 11;
}
/*************************************************
main
**************************************************/
void fcn(signal_collector * param_signal, int len)
{
int *pointer = param_signal;
while(len--)
{
ManipulateSignal(pointer);
pointer += (sizeof(signal_structure) / sizeof(int));
}
}
int main(void)
{
signal_collector foo;
fcn(&foo, 1);
return 0;
}
You can't use a typedef name as a function argument. You need to declare a variable with that type, and pass the address of the variable.
int main(void) {
param_collector my_pc;
fcn(&my_pc);
return 0;
}
You can only pass the reference to the object, but you forgot to define this object.
int main(void)
{
param_collector param_collector;
fcn(&param_collector);
return 0;
}
but I would give rather call the variable a distinct name (not the same as type)

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 use structs, pointers and a function in C?

I have learned how to use functions and structs and pointers. I want to combined them all into one. But the code that I write doesn't seem to work. The compiler tells me the test is an undeclared identifier. Here is the code:
#include <stdio.h>
#include <stdlib.h>
struct character
{
int *power;
};
void test (use_power)
int main ()
{
test (use_power)
printf("%d\n",*power);
return 0;
}
void test ()
{
int use_power = 25;
struct character a;
a.power = &use_power;
}
Your code has many mistakes it can't even compile
Multiple missing semicolons.
Implicit declaration of test() here
test (use_power)
with a missing semicolon too.
power is not declared in main().
This line
void test use_power()
does not make sense and is invalid, and also has no semicolon.
The a instance in test() defined at the end is local to test() and as such will be deallocated when test() returns. The use_power int, has exactly the same problem and trying to extract it's address from the function is useless because you can't access it after the function has returned.
I have no idea what you were trying to do, but this might be?
#include <stdio.h>
#include <stdlib.h>
struct character {
int *power;
};
/* Decalre the function here, before calling it
* or perhaps move the definition here
*/
void test(struct character *pointer);
/* ^ please */
int
main(void) /* int main() is not really a valid signature */
{
struct character instance;
test(&instance);
if (instance.power == NULL)
return -1;
printf("%d\n", *instance.power);
free(instance.power);
return 0;
}
void
test(struct character *pointer)
{
pointer->power = malloc(sizeof(*pointer->power));
if (pointer->power != NULL)
*pointer->power = 25;
}
Your code seems to be wrong. Your definition for test contains no arguments as
void test ()
{
int use_power = 25;
struct character a;
a.power = &use_power;
}
but your prototype contains one argument
void test (use_power)
which is wrongly put. First there are no semicolons; at the end of your prototype declaration, secondly by looking at your code, use_power is a variable and not a datatype so it cannot be present solely in a function declaration.
You will get an argument mismatch error.
You have used the line in main()
printf("%d\n",*power);
which is absolutely wrong. you cannot access any member of a structure without a structure variable.
And again, you have not mentioned the; after your call to the incorrect test()before this line
As you have not put your question so properly, I must figure out what you wish to achieve. I bet you want to hold the address of a integer in the pointer member of a structure and then print its value.
Below is a code snippet which will work as you desire.
#include <stdio.h>
#include <stdlib.h>
struct character
{
int *power;
};
struct character a; //define a structure variable
void test ();
int main ()
{
test ();
printf("%d\n",*(a.power)); // print the member of structure variable a
return 0;
}
void test ()
{
int use_power = 25;
a.power = &use_power;
}
example
#include <stdio.h>
struct character {
int *power;
};
void test(struct character *var);
int main (void){
struct character use_power;
int power = 5;
use_power.power = &power;
test(&use_power);
printf("%d\n", power);
return 0;
}
void test(struct character *var){
int use_power = *var->power;
*var->power = use_power * use_power;
}

How to parse a structure array as a parameter?

How should I parse an array of structures as parameter to a function?
For example, I have the following structure definition:
struct Town
{
char *TownName;
char **GiftList;
int *GiftCount;
int GiftTypes;
};
and a declaration of an array of such structures, in my main:
struct Town TownList[100];
struct Town AuxiliaryStructure;
I have written a custom sorting function for this array, in which I want to make use of each structure's fields, but I do not know how to provide the array TownList[100] to the sort function.
To pass an array of anything to a function, you can just pass a pointer to the first element plus an array length:
struct mystruct {
char* something;
/* ... */
}
struct mystruct myarray[100];
void do_something(struct mystruct* array, int length)
{
int i;
for (i=0; i<length; ++i)
{
array[i].something = ...
}
}
int main(void)
{
do_something(myarray, 100);
return 0;
}
Based on what you wrote, you would reference it in the caller and pass the result. For example:
void sort(char* str){
...
}
int main(){
for(int i=0; i<100; ++i){
sort(array[i].something);
}
}
Alternately you may want to pass the full array and handle it in another function, which would be like this:
void sort(struct mystruct * array){
...
}
int main(){
for(int i=0; i<100; ++i){
sort(array);
}
}
If, on the other hand, you meant that you want to sort the outer array of structures by the contents of something, then you would either have to pass the array as above and implement your own sort, or use a sorting function that takes a function pointer so you can write a comparator. The latter is available in the standard C library, and could be used something like this.
#include <stdlib.h>
int compare_mystruct_by_something(const void *a, const void *b){
return strcmp(((struct mystruct*)a)->something, ((struct mystruct *)b)->something);
}
int main(){
qsort(array, 100, sizeof(struct mystruct), compare_mystruct_by_something);
}

Resources