I'm using a structure array to save data about specific person, and have 2 function which write out data. 3rd function (Wypisz) uses pointer to use specified one. The problem is when i try to compile it, error occurs in this function in both 'if clauses':
error: expected expression before 'struct'
struct Osoba
{ char imie[MAX], nazwisko[MAX];
int rokurodzenia[N];
};
void WypiszWLinii(struct Osoba osoba[])
{ int i;
for(i=0;i<N;i++)
{
printf("%c %c, %d\n", osoba[i].imie, osoba[i].nazwisko, osoba[i].rokurodzenia);
}
}
void WypiszJedenPoDrugim(struct Osoba osoba[])
{
int i;
for(i=0;i<N;i++)
{
printf("%c\n%c\n%d\n", osoba[i].imie, osoba[i].nazwisko, osoba[i].rokurodzenia);
}
}
void Wypisz(void (*wskfun)(struct Osoba), int i)
{
if(i=1)
{
wskfun=WypiszJedenPoDrugim(struct Osoba osoba[]);
}
else if(i=0)
{
wskfun=WypiszWLinii(struct Osoboa osoba[]);
}
else
{
printf("Wybrano zla opcje w menu\n");
return -1;
}
}
N and MAX is predefined variable with library inclusions
the problem you have in the Wypisz function implementation is the assignement of pointer to a function to a wrong value.
Instead to :
wskfun=WypiszJedenPoDrugim(struct Osoba osoba[]);
or
wskfun=WypiszWLinii(struct Osoba osoba[]);
you have to get the pointer to that function and assing it to the variable:
wskfun = &WypiszJedenPoDrugim;
or
wskfun = &WypiszWLinii;
After that you could use the pointer to the function like:
wskfun("pointer to struct array");
Said that, to solve your problem the function must be changed like:
void Wypisz(void(*wskfun)(struct Osoba[]), int i)
{
if (i = 1)
{
wskfun = &WypiszJedenPoDrugim;
}
else if (i = 0)
{
wskfun = &WypiszWLinii;
}
else
{
printf("Wybrano zla opcje w menu\n");
return -1;
}
}
Related
This is a plane game function I wrote. I use a two-dimensional array to represent the game variables but The running result is abnormal, and * will jump suddenly.
And there will be two * , at the same time, and the plane also will stop
There should be no two * in the process of traversing the two-dimensional array. I tried to modify the position of * but I still couldn't.It's OK to run part of the code alone, but when you use the key operation, the program makes an error, but I don't know what's wrong
#include<stdio.h>
#include <windows.h>
#include<stdlib.h>
#include<conio.h>
#define enemynum 3
int element [20][30];
int position_x,position_y;
int enemy_x[enemynum],enemy_y[enemynum];
int score;
void gotoxy(int x, int y)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = {1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void startup()
{ element[20][30]={0};
position_x=10;position_y=15;
element[position_x][position_y]=1;
for(int k=0;k<enemynum;k++)
{
enemy_x[k]=rand()%3;enemy_y[k]=rand()%20;
element[enemy_x[k]][enemy_y[k]]=3;
}
HideCursor();
}
This is an encapsulated pointer callback function. I don't think we need to consider the above functions
void show()
{ int i,j;
gotoxy(0,0);
for(i=0;i<20;i++)
{
for(j=0;j<30;j++)
{ if(element[i][j]==1)
{
printf("*");
}else if(element[i][j]==3)
{
printf("#");
}
else
printf(" ");
}
printf("\n");
}
}
void updatewhithout()
{
int i,j;
for(i=0;i<20;i++)
{
for(j=0;j<30;j++)
{
if(element[i][j]==2)
{
element[i][j]=0;
if(i>0)
element[i-1][j]=2;
}
}
} static int flag;
if(flag<20)
flag++;
if(flag==20)
{ for(int k=0;k<enemynum;k++)
{
if(enemy_x[k]==20)
{
enemy_x[k]=rand()%3;
enemy_y[k]=rand()%20;
}
element[enemy_x[k]][enemy_y[k]]=0;
enemy_x[k]++;
element[enemy_x[k]][enemy_y[k]]=3;
flag=0;
}
}
}
void updatewhith()
{ char ch;
if( kbhit())
ch=getch();
if(ch=='a')
{ element[position_x][position_y]=0;
position_y--;
element[position_x][position_y]=1;
}
if(ch=='d')
{ element[position_x][position_y]=0;
position_y++;
element[position_x][position_y]=1;
}
}
int main()
{startup();
while(1)
{show();
updatewhithout();
updatewhith();
}
}
So the code below can be used to pass a function as a parameter:
void printNumber(int nbr)
{
printf("%d\n", nbr);
}
void myFunction(void (*f)(int))
{
for(int i = 0; i < 5; i++)
{
(*f)(i);
}
}
int main(void)
{
myFunction(printNumber);
return (0);
}
But how can I change that code so that the integer for “printNumber” is defined outside of “myFunction”? In other words I only want to call the function “myFunction” for x number of times with the same integer .
I wrote some pseudocode to explain what I'm trying to accomplish:
void printNumber(int nbr)
{
printf("%d\n", nbr);
}
void myFunction(void (*f)(*int)) //pseudocode
{
for(int i = 0; i < 5; i++)
{
(*f)(*int); //pseudocode
}
}
int main(void)
{
myFunction(printNumber(5)); //pseudocode
return (0);
}
printnumber(5) means to call printnumber immediately and pass it 5. You want to pass printnumber and 5 separately as two arguments
void printNumber(int nbr)
{
printf("%d\n", nbr);
}
// void (*f)(int) is a pointer to a function that takes an int
// arg is the int to pass in
void myFunction(void (*f)(int), int arg)
{
for(int i = 0; i < 5; i++)
{
// call f and pass in arg
(*f)(arg);
}
}
int main(void)
{
// pass the function and the arg to use
myFunction(printNumber, 5);
return (0);
}
You need another argument.
void printNumber(int nbr)
{
printf("%d\n", nbr);
}
void myFunction(void (*f)(int), int Arg)
{
for(int i = 0; i < 5; i++)
{
(*f)(Arg);
}
}
int main(void)
{
myFunction(printNumber, 42);
return (0);
}
The parameter declaration void (*f)(int) only says that the function pointed to by f expects an int. It doesn't mean that an int is also packed into the function pointer somehow.
I'm using function to assign the patterns of my 2D arrays. All the other arrays are displaying as it should except for my 'ans' array (the last row's dash is missing). Im guessing the problem is because of the 'pat2match' function (merges all the patterns). Because if i don's assign 'ans' to that 'function' and print an empty pattern array, all the dashes shows.
The function that merges the patterns:
char pat2match(char mypattern[13][13], char pat1[13][13], char pat2[13][13],
char pat3[13][13], char pat4[13][13], char pat5[13][13])
{
int r,c;
overlap(mypattern,pat5);
overlap(mypattern,pat2);
overlap(mypattern,pat4);
overlap(mypattern,pat3);
return overlap(mypattern,pat1);
}
Assigning the 'ans':
mytile(ans);
for(r=0;r<13;r++)
{
for(c=0;c<13;c++)
{
ans[r][c] = pat2match(ans,pattern1,pattern2,pattern3,pattern4,pattern5);
}
}
The overlap function:
char overlap(char pat1[13][13], char pat2[13][13])
{
int r,c;
for(r=0;r<13;r++)
{
//printf("|");
for(c=0;c<13;c++)
{
if(pat1[r][c] == ' ' || pat2[r][c] != ' ')
{
pat1[r][c] = pat2[r][c];
}
//printf(" %c ", pat1[r][c]);
}
//printf("|\n");
}
return pat1[r][c];
}
the empty pattern (the dash is like its border) :
void mytile(char pat[13][13])
{
int r,c;
for(r=0;r<13;r++)
{
for(c=0;c<13;c++)
{
if(r==0 || r==12)
{
pat[r][c] = '-';
}
else
{
pat[r][c] = ' ';
}
}
}
}
The return value from overlap is undefined behavior:
return pat1[r][c];
When this return statement is executed, both r and c are 13. Neither can be greater than 12. It is indexing past the bounds of the array, which is undefined behavior.
So I implemented the following method. The problem is that when I begin
searching the variableVector pointer I noticed that variableVector->variables
might not be pointing to the beginning variable element.
Variable* findVariable(VariableVector *variableVector,
char *variableNameOfVariableToReturn) {
if (variableVector->size < 1) {
return NULL ; // since variableVector is empty
}
Variable *currentVariable = variableVector->variables;//<== HOW TO RESET TO BEGINNING???
int numberOfVariablesInVariableVector = variableVector->size;
for (int i = 0; i < numberOfVariablesInVariableVector; i++) {
if (strcmp(currentVariable->variableName,
variableNameOfVariableToReturn) == 0) {
return currentVariable;
} else {
currentVariable++;
}
}
return NULL ; // variable not found in variableVector
}
These are what my structs look like:
struct _Variable {
char *variableName;
char *arrayOfElements;
int32_t address;
};
typedef struct _Variable Variable;
struct _VariableVector {
int size; // elements full in array
int capacity; // total available elements
Variable *variables;
};
typedef struct _VariableVector VariableVector;
Also this is how I add a new variable:
bool appendVariable(VariableVector *variableVector, Variable *variable) {
if (variableVector->size == variableVector->capacity) {
return false;
} else { // append since vector is not full
int indexOfFirstEmptyElement = variableVector->size;
memcpy(&variableVector->variables[indexOfFirstEmptyElement], variable, sizeof(Variable));
//variableVector->variables[indexOfFirstEmptyElement] = *variable;
variableVector->size++;
return true;
}
}
I'm currently programming a PIC in C with MPLAB X (+ compiler XC8)
In my code, I have some interruptions (inter1, inter2, ..) which are each composed of urgent and non-urgent operations (urg1, urg2, .., n_urg1, n_urg2, ..).
So I'd like a code with the following structure :
stack s; // FIFO or other
main() {
while (true) {
if (!isEmpty(s)) {
doNextFunction(s);
}
}
}
void interrupt inter1() {
urg1(); // urgent code
addStack(n_urg1);
}
void n_urg1() {
// non-urgent code
}
How can I implement that kind of stack ? Is there something in the standard library ?
If I remember correct, then that compiler is rather primitive, I don't think you can use the std library.
If you need to implement it all by yourself, you can use an array of function pointers:
#include <string.h> // for memmove()
#define STACK_MAX 10
typedef enum
{
Int,
Boolean
} VariantType;
typedef struct
{
VariantType type;
union {
int intValue;
bool booleanValue;
} value;
} Variant;
typedef bool (*FunctionPtr)(Variant data);
typedef struct
{
FunctionPtr ptr;
Variant var;
} FunctionCall;
FunctionCall functionStack[STACK_MAX];
int functionStackUse = 0;
bool addStack(FunctionPtr ptr, Variant var)
{
if (functionStackUse >= STACK_MAX)
return false; // stack full
functionStack[functionStackUse].ptr = ptr;
functionStack[functionStackUse].var = var;
functionStackUse++;
return true;
}
bool callNextFunction(void)
{
// TODO: disable inter1
if (functionStackUse > 0)
{
// get first function on stack
FunctionCall functionCall = functionStack[0];
functionStackUse--;
// remove first function from stack
memmove((void*)functionStack, (void*)(functionStack + 1), functionStackUse * sizeof(functionStack[0]));
// TODO: re-enable inter1
// call function with arguments
return (*functionCall.ptr)(functionCall.var);
}
else
{
// TODO: re-enable inter1
return false; // no more functions
}
}
void main()
{
while (1)
{
callNextFunction();
// TODO add some delay otherwise you're constantly disabling inter1 (in doNextFunction)
}
}
bool n_urg1(Variant var)
{
if (var.type == Int)
{
int i = var.value.intValue;
// do something
return true;
}
return false;
}
void inter1(void)
{
Variant var;
var.type = Int;
var.value.intValue = 45;
addStack(n_urg1, var);
}