For my uni project I'm trying to create a basic tank game in C, but I've only just started learning C and have a very basic understanding of C. So I've started working on some simple code for a AI player, but when I compile it with GNU GCC compiler it comes up with these errors and I've got no clue how to proceed. So help would be great please! :D
Line 41 warning: passing argument 3 of 'AIMove' makes pointer from integer without a cast [enabled by default]
Line 19 note: expected 'int (*)()' but argument is of type 'int'
int PosCheck(int T1Pos, int T2Pos)
{
int a;
a = T2Pos - T1Pos;
if(a == 0) // Stop the tanks trying to overlay
{
return 0;
}
if(a >= 1 || a < 0) // Allows the tanks to move foward
{
return 1;
}
}
int AIMove(int T1Pos, int T2Pos, int PosCheck()) // AI movement
{
int b, c;
if(PosCheck(T1Pos, T2Pos) == 0) // Choose retreat options or stands still
{
b = 3 + round(3*(int)rand()/(int)RAND_MAX);
return b;
}
if(PosCheck(T1Pos, T2Pos) == 1) // Chooses foward options
{
c = 1 + round(3*(int)rand()/(int)RAND_MAX);;
return c;
}
}
main()
{
int T1Pos;
int T2Pos;
int T2MC;
T2MC = AIMove(T1Pos, T2Pos, PosCheck(T1Pos, T2Pos));
}
This function takes another function as a parameter because of these parens:
int AIMove(int T1Pos, int T2Pos, int PosCheck()) // AI movement
^^
But when you call it, you are passing the result of a same-named function:
T2MC = AIMove(T1Pos, T2Pos, PosCheck(T1Pos, T2Pos));
What is the PosCheck parameter supposed to do? Inside AIMove you call it, but it's not clear if you want the global PosCheck function or the argument.
By the way, the usual way to declare a function pointer is with an asterisk:
int AIMove(int T1Pos, int T2Pos, int (*PosCheck)()) // Obviously a pointer.
If there's nothing in particular you are trying to accomplish there, just delete the parameter and the argument.
T2MC = AIMove(T1Pos, T2Pos);
int AIMove(int T1Pos, int T2Pos)
Related
I am new to C programming which's why I am confused with its syntax.
Question: A Sudoku puzzle uses a 9 × 9 grid in which each column and row, as well as
each of the nine 3 × 3 subgrids, must contain all of the digits 1 ⋅ ⋅ ⋅ 9. Figure
4.26 presents an example of a valid Sudoku puzzle. This project consists of
designing a multithreaded application that determines whether the solution
to a Sudoku puzzle is valid.
There are several different ways of multithreading this application. The one
suggested strategy is to create threads that check the following criteria:
• A thread to check that each column contains the digits 1 through 9
• A thread to check that each row contains the digits 1 through 9
#include <stdlib.h>
int i,j,m,b,k;
void main()
{
int a[9][9]={1,2,3,4,5,6,7,8,9,
4,5,6,7,8,9,1,2,3,
7,8,9,1,2,3,4,5,6,
2,3,4,5,6,7,8,9,1,
5,6,7,8,9,1,2,3,4,
8,9,1,2,3,4,5,6,7,
3,4,5,6,7,8,9,1,2,
6,7,8,9,1,2,3,4,5,
9,1,2,3,4,5,6,7,8};
if(rowcheck(a)==1 && colcheck(a)==1 & cubecheck(a)==1)
{
printf("Success");
}
else{
printf("Failed");
}
}
int rowcheck(int a[9][9])
{
int c[10]={0};
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
c[a[i][j]]++;
}
for(k=1;k<=9;k++)
if(c[k]!=1)
{
printf("The value %d came %d times in %d row \n",k,c[k],i+1);
return 0;
}
for(k=1;k<=9;k++)
c[k]=0;
}
return 1;
}
int colcheck(int a[9][9])
{
int c[10]={0};
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
c[a[i][j]]++;
}
for(k=1;k<=9;k++)
if(c[k]!=1)
{
printf("The value %d came %d times in %d column \n",k,c[k],i+1);
return 0;
}
for(k=1;k<=9;k++)
c[k]=0;
}
return 1;
}
int cubecheck(int a[9][9])
{
int c[10]={0},count=0;
for(m=0;m<9;m+=3)
{
for(b=0;b<9;b+=3)
{
for(i=m;i<m+3;i++)
{
for(j=b;j<b+3;j++)
{
c[a[i][j]]++;
}
}
count++;
for(k=1;k<=9;k++)
if(c[k]!=1)
{
printf("The value %d came %d times in %d box\n",k,c[k],count);
return 0;
}
for(k=1;k<=9;k++)
c[k]=0;
}
}
return 1;
}```
I am getting this error plz help.
```proj1.c: In function ‘main’:
proj1.c:18:8: warning: implicit declaration of function ‘rowcheck’ [-Wimplicit-function-declaration]
if(rowcheck(a)==1 && colcheck(a)==1 & cubecheck(a)==1)
^~~~~~~~
proj1.c:18:26: warning: implicit declaration of function ‘colcheck’ [-Wimplicit-function-declaration]
if(rowcheck(a)==1 && colcheck(a)==1 & cubecheck(a)==1)
^~~~~~~~
proj1.c:18:43: warning: implicit declaration of function ‘cubecheck’ [-Wimplicit-function-declaration]
if(rowcheck(a)==1 && colcheck(a)==1 & cubecheck(a)==1)
^~~~~~~~~
proj1.c: At top level:
proj1.c:136:1: error: expected identifier or ‘(’ before ‘}’ token
}```
^
You need to give declarations for your functions before main() method since you define them afterwards:. A forward function declaration just tells the compiler that, somewhere in your code, a function with the same name will be defined, in this case after its usage in main().
Usually, in C/C++ you define function prototypes in header files, then include them in your main source code, so the functions can safely be defined after they are called.
#include <stdio.h>
#include <stdlib.h>
// add forward declarations for your functions here
int rowcheck(int [][9]);
int colcheck(int [][9]);
int cubecheck(int [][9]);
int main() {
// your code
return 0:
}
// method definitions afterwards
int rowcheck(int a[9][9]) {
// your definition here
}
int colcheck(int a[9][9]) {
// your definition here
}
int cubecheck(int a[9][9]) {
// your definition here
}
Also, define your main method as int main() rather than void main().
I'm having two compile errors when trying to compile my code, and I can't find what the issue really is. Could anybody help shed some light?
error: old-style parameter declarations in prototyped function definition
error: 'i' undeclared (first use in this function)
Code:
void printRecords (STUREC records[], int count)
STUREC records[ARRAY_MAX];
int count;
int i;
{
printf("+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
printf("| Student Name | ID | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |\n");
printf("+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
for (i = 0; i < count; i++)
{
size_t j;
printf ("|%s|%d|%d|%d|%d|%d|%d|%f|%c|", records[i].name, records[i].id, records[i].score1,
records[i].score2, records[i].score3, records[i].score4, records[i].score5,
records[i].ave, records[i].grade);
}
return;
}
Not for this specific question, but if you happen to come across this error, check that you did not miss a semicolon at the end of your declaration, because that's what happened to me.
If you want to use old style C parameter declarations, you need to do this:
void printRecords(records, count)
STUREC records[ARRAY_MAX];
int count;
{
int i;
// ... rest of the code ...
}
But this is not considered a good practice and can make your code harder to read. Some compilers have even stopped supporting this syntax.
The other comments/answers are saying that you re-declare (and therefore hide) your function parameters in the body of the function, but this is not what you want to do (otherwise you effectively lose the parameters being passed in).
If you define a function like this:
void fxn(int num) {
int num;
num = num;
}
What does num refer to: the parameter or the local variable?
Either do this:
void printRecords(records, count)
STUREC records[ARRAY_MAX];
int count;
{
int i;
// ... rest of the code ...
}
or do this:
void printRecords(STUREC records[], int count)
{
int i;
// ... rest of the code ...
}
But don't try to do both or a mixture of the two.
You have
void printRecords (STUREC records[], int count)
STUREC records[ARRAY_MAX];
int count;
int i;
{
But I guess you want:
void printRecords (STUREC records[], int count)
{
int i;
EDIT:
Thanks to callyalater for noting the redeclaration of the parameters in the function...
I'm making an application in C that will use text menus. So, I decided to create a global array containing all the menus. As a workaround of an issue I will mention later, the code looks like this:
char* main_menu[]=
{"Refresh rate", "Help", "Default config", NULL};
char* other_stuff[]=
{"Stuff", "More", NULL};
char** screens[]={main_menu, other_stuff};
And I can use those strings like: screens[0][1] meaning first (or rather second, since we count from zero) option in zeroth/first menu.
It works, but it strikes me as quite inelegant that I had to declare those auxilliary arrays (main_menu and other_stuff). I tried to make use of nested brace initialization of arrays, but always the compiler would complain. Also, before you suggest declaring the array as, say, char* screeens[10][5] - there should be no magic numbers, as this is equally inelegant for me.
I tried:
char** screens[]={
{"Refresh rate", "Help", "Default config", NULL},
{"Stuff", "More", NULL}
};
However, the compiler gives me a warning (and rightfully, as accessing elements yields gibberish):
../main.c:96:1: warning: braces around scalar initializer [enabled by default]
{"Refresh rate", "Help", "Default config", NULL},
^
../main.c:96:1: warning: (near initialization for ‘screens[0]’) [enabled by default]
../main.c:96:1: warning: initialization from incompatible pointer type [enabled by default]
../main.c:96:1: warning: (near initialization for ‘screens[0]’) [enabled by default]
../main.c:96:1: warning: excess elements in scalar initializer [enabled by default]
and so on.
If I change the first line to char* screens[][]={, the compiler won't compile the code at all, giving error: error: array type has incomplete element type.
I'm writing in embedded evironment (avr-gcc 4.8.1), where memory is quite scarce, so I don't want to declare arrays bigger than necessary, thus wasting memory. Is there anything I can do, or is this as simple as possible?
Assuming you have C99 or later, you can use 'compound literals' to initialize your array:
#include <stddef.h> // NULL
char **screens2[] =
{
(char *[]){ "Refresh rate", "Help", "Default config", NULL },
(char *[]){ "Stuff", "More", NULL },
};
Or, if you want to be const-correct (a good thing — thanks to M.M and his comment):
char const * const * screens3[] =
{
(char const * const []){ "Refresh rate", "Help", "Default config", NULL },
(char const * const []){ "Stuff", "More", NULL },
};
Compilation (clean — no warnings or errors):
gcc -std=c11 -O3 -g -Wall -Wextra -Werror -pedantic -c 2das.c
(GCC 5.1.0 on Mac OS X 10.10.5)
I'm making an application in C that will use text menus.
You could try something like this:
#include <stdio.h>
#include<unistd.h>
typedef int (*menu)(void);
void clearScreen(int x){
int i=0;
for(;i<x;i++){
printf("\n");
}
}
int exitMenu(void) {
clearScreen(100);
printf("Exiting... Goodbye\n");
sleep(1);
return 0;
}
int mainMenu(void){
clearScreen(100);
printf("\t\t\tMain Manu\n");
return 0;
}
int updateSystem(void) {
clearScreen(100);
printf("System update...\n");
sleep(1);
return 1;
}
int installVlcFromPpa(void) {
clearScreen(100);
printf("Install VLC from PPA \n");
sleep(1);
return 0;
}
int installVlcFromSource(void) {
clearScreen(100);
printf("Install VLC from Source \n");
sleep(1);
return 0;
}
int uninstallVLC(void) {
clearScreen(100);
printf("Uninstall VLC... \n");
sleep(1);
return 1;
}
int chooseOption(int min, int max){
int option,check;
char c;
do{
printf("Choose an Option:\t");
if(scanf("%d%c",&option,&c) == 0 || c != '\n'){
while((check = getchar()) != 0 && check != '\n');
printf("\tThe option has to be between %d and %d\n\n",min,max);
}else if(option < min || option > max){
printf("\tThe option has to be between %d and %d\n\n",min,max);
}else{
break;
}
}while(1);
return option;
}
void showMenu(char *question, char **options, menu *actions, int length) {
int choose = 0;
int repeat = 1;
int i;
menu act;
do {
printf("\n\t %s \n", question);
for(i = 0; i < length; i++) {
printf("%d. %s\n", (i+1), options[i]);
}
choose = chooseOption(1,length);
printf(" \n");
act = actions[choose - 1];
repeat = act();
if(choose == 3){
repeat = 0;
}
}while(repeat == 1);
}
int installVLC(void) {
clearScreen(100);
char *question = "Installing VLC from:";
char *options[10] = {"PPA", "Source", "Back to VLC menu"};
menu actions[3] = {installVlcFromPpa, installVlcFromSource, mainMenu};
showMenu(question, options, actions, 3);
return 1;
}
int meniuVLC(void) {
clearScreen(100);
char *question = "VLC Options";
char *options[10] = {"Install VLC.", "Uninstall VLC.", "Back to Menu."};
menu actions[3] = {installVLC, uninstallVLC, mainMenu};
showMenu(question, options, actions, 3);
return 1;
}
void startMenu(void){
clearScreen(100);
char *question = "Choose a Menu:";
char *options[10] = {"Update system.", "Install VLC", "Quit"};
menu actions[3] = {updateSystem, meniuVLC, exitMenu};
showMenu(question, options, actions, 3);
}
int main(void){
startMenu();
return 0;
}
Choose a Menu:
1. Update system.
2. Install VLC
3. Quit
Choose an Option:
The most elegant way is to declare them as separate variables.
You can also use the first method but utilizing enums/defines, so that you have screens[MAIN_MENU][...] rather that some magic screens[0xcafebabe][...], it is equally acceptable.
I am trying to make a compiler and if the compiler is given the token INTEGER, REAL or CHARACTER, i would like it to generate code to make int, float or char instead.
The language I am writing in is C and I am using flex and bison.
My lexer METHODS are:
SYMTABNODEPTR newSymTabNode()
{
return ((SYMTABNODEPTR)malloc(sizeof(SYMTABNODE)));
}
int installId(char *id)
{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
int index;
index = lookup(id);
if (index >= 0)
{
return (index);
}
else
{
symTab[currentSymTabSize] = newSymTabNode();
strcpy(symTab[currentSymTabSize]->identifier,id);
//symTab[currentSymTabSize]->type=0;
return(currentSymTabSize++);
}
}
int lookup(char *s)
{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
int i;
for(i=0; i<currentSymTabSize; i++)
{
if(strcmp(s,symTab[i]->identifier) == 0)
{
return (i);
}
}
return (-1);
}
and in my parser I have:
struct symTabNode {
char identifier [IDLENGTH];
};
typedef struct symTabNode SYMTABNODE;
typedef SYMTABNODE *SYMTABNODEPTR;
SYMTABNODEPTR symTab[SYMTABSIZE];
%token<iVal> IDENTIFIER NUMBER CHARACTER_CONSTANT EQUAL GTLT LT GT LTEQ GTEQ PLUS MINUS TIMES DIVIDE ASSIGN CHARACTER INTEGER REALCONST
type : CHARACTER
{
$$ = create_node($1, TYPE_NODE, NULL, NULL, NULL);
}
| INTEGER
{
$$ = create_node($1, TYPE_NODE, NULL, NULL, NULL);
}
| REALCONST
{
$$ = create_node($1, TYPE_NODE, NULL, NULL, NULL);
}
void GenerateCode(TERNARY_TREE t)
{
if (t == NULL) return;
switch(t->nodeIdentifier)
{
case(TYPE_NODE):
printf("%s ",symTab[t->item]);
break;
default:
GenerateCode(t->first);
GenerateCode(t->second);
GenerateCode(t->third);
}
My compiler is currently outputting:
INTEGER a, b, c;
REAL d, e;
CHARACTER f;
it would be great to have
int a, b, c;
float d, e;
char f;
instead
I hope thats enough information (there is alot more to the compiler of course)
Thank you in advance
I recommend creating a very simple test case (much like you put in your question), and then running your compiler in the debugger. As you step through line by line, the problem should become apparent to you. At least it usually does for me. You could also modify your program to print out extra information at key points in its execution so you can see what it is doing.
I have my code below that consits of a structure, a main, and a function. The function is supposed to display two parameters that have certain values, both of which point to the same structure.
The problem I dont know how to add the SECOND parameter onto the following code :
#include<stdio.h>
#define first 500
#define sec 500
struct trial{
int f;
int r;
float what[first][sec];
};
int trialtest(trial *test);
main(){
trial test;
trialtest(&test);
}
int trialtest(trial *test){
int z,x,i;
for(i=0;i<5;i++){
printf("%f,(*test).what[z][x]);
}
return 0;
}
I need to add a new parameter test_2 there (IN THE SAME FUNCTION) using this code :
for(i=0;i<5;i++){
printf("%f,(*test_2).what[z][x]);
How does int trialtest(trial *test) changes ?
and how does it change in main ?
I know that I should declare test_2 as well, like this :
trial test,test_2;
But what about passing the address in the function ? I do not need to edit it right ?
trialtest(&test); --- This will remain the same ?
So please, tell me how would I use test_2 as a parameter pointing to the same structure as test, both in the same function..
Thank you !!
Please tell me if you need more clarification
I think that this is your homework, so I'll just write a different function that may give you an idea of what (I think) you need to do. I read that you don't want to change the trail_test parameter list, so I stuck with a similar parameter list.
struct thing {
/* put some stuff here */
};
typedef struct thing thing; /* because this is C, not C++ */
int how_many_things(thing * thing_list);
int main(void) {
int i;
thing * a;
int count_init = random(); /* let's surprise ourselves and make a random number of these */
count_init %= 128; /* but not too many or it might not work at all */
a = malloc(count_init*sizeof(things)+1);
for (i = 0; i < count_init; i++) {
thing_init(&(a[i]));
}
make_illegal_thing(&(a[count_init]) ); /* like '\0' at the end of a string */
printf("There are %i things in the list\n", how_many_things(a) );
return 0;
}
/* This is very similar to strlen */
int how_many_things(thing * a) {
int count = 0;
while (is_legal_thing(a) ) {
a++;
count++;
}
return count;
}