Local variables in c prgramming AT89C51 - c

I am trying to use recursion in a function and for that I have to use local variables. The compiler gives error c141 in the line where I am defining my local variable.
int minimax(int board[9], int player) {
int winner;
winner = win(board);
if (winner != 0) return winner*player;
int moveminimax;
moveminimax = -1;
int scoreminimax;
scoreminimax = -2;
int i3;
for (i3= 0; i3 < 9; ++i3) {//For all moves,
if (board[i3] == 0) {//If legal,
board[i3] = player;//Try the move
int thisScore;
thisScore = -minimax(board, player*-1);
if (thisScore > scoreminimax) {
scoreminimax = thisScore;
moveminimax = i3;
}board[i3] = 0;//Reset board after try
}
}
if (moveminimax == -1) return 0;
return scoreminimax;
}
6-3-17 4 01pm.c(116): error C141: syntax error near 'int'
//c(116) is the where int winner is defined
When i define my variables globally in the beginning of program the error goes away.

My guess is that the Keil C compiler is not following the C99 standard, where variables could be defined anywhere, but instead follow the older C89 standard where local variables only could be defined at the beginning of block.
That means code like
int winner;
winner = win(board);
if (winner != 0) return winner*player;
int moveminimax;
moveminimax = -1;
int scoreminimax;
scoreminimax = -2;
int i3;
is invalid since it contains mixed declarations and statements.
Two of the statements can be removed completely by initializing the variables when you declare them, which leaves the function call and if statement that needs to be moved.
Try this instead:
int winner;
int moveminimax = -1;
int scoreminimax = -2;
int i3;
winner = win(board);
if (winner != 0) return winner*player;

Related

How to generate a new function in C?

I want a function that could take input a single integer from the user with validation, lets call it input_single_int. Such a function would greatly simplify my code. If a user gives incorrect input, then the function should show error and again prompt the user to fill out the correct input. The problem is the validation part, different inputs require different validation. Even if I send a validation function, how do I send the different parameters required by the validation function through input_single_int?
I want this function to be generic, so that I could use it multiple places. In the code given, if I add a parameter in input_single_int to accomodate input of variable b, I would have to change check_a function also, which I don't want to do. I also don't want to use global variables.
The only way which I could think of achieving this is through a function that could generate another function. Something like this:
func generate_check_b(int a) {
return int check_b(int b) { return (b > 0 && b < a); };
}
Is such a thing possible in C?
#define MM_SHOW 8
#define MM_QUIT 9
int input_single_int(int *var, char msg[], int exit_on_eq, int secondary_check(int val)) {
int inp_status, error, temp;
char skip;
do {
error = 0;
printf("%s", msg);
inp_status = scanf("%d", &temp);
if (inp_status != 1) {
error = 1;
do {
scanf("%c", &skip);
if (exit_on_eq) {
if (skip == 'e') {
system("clear");
return MM_SHOW;
} else if (skip == 'q') {
system("clear");
return MM_QUIT;
}
}
} while (skip != '\n');
}
if (!secondary_check(temp)) {
error = 1;
}
} while (error && printf("Please give a correct input.\n"));
*var = temp;
return 0;
}
int check_a(int a) { return a > 0;}
int check_b(int b, int a) { return (b > 0 && b < a);}
int main() {
int a, b;
char amsg[] = "a should be more than 0: ";
char bmsg[] = "b should be more than 0 and less than a: ";
input_single_int(&a, amsg, 1, check_a);
input_single_int(&b, bmsg, 1, check_b);
return 0;
}
A common idiom is a pair of parameters; a function and an opaque context pointer; so a simple case could be something like:
int check_range(int a, void *p) {
int *range = p;
return a >= range[0] && a < range[1];
}
struct Set { int n; int *vals; };
int check_set(int b, void *p) {
struct Set *s = p;
int i;
for (i = 0; i < s->n && s->vals[i] != b; i++) {}
return i < s->n;
}
If you look at the blocks extension to C supported by clang & gcc, it isn't far different from this, except that it is more sugary and has some really scary side effects.

C - Passing a local variable in a function without initializing

so I'm really new at this, and I was wondering how I would go about passing a local variable in a function (in terms of the initialization). For example, I have one function (move) that declares and initializes two variables (t_row and t_column) to be used in a for loop, and within that loop, I have another functions (swap), that is called if certain conditions are met. How do I go about using those variables in the swap function. I know I need to declare them, but their initialization in the swap function depends on what iteration of the for loop swap was called. Thanks in advance for any help!
bool move(int tile)
{
for (int t_row = 0; t_row < d; t_row++)
{
for (int t_column = 0; t_column < d; t_column++)
{
if (tile == board[t_row][t_column])
{
if (0 < t_row && board[t_row - 1][t_column] == 0)
{
swap(t_row - 1, t_column);
return true;
}
}
}
}
return false;
}
void swap(int row_new, int column_new)
{
int t_row;
int t_column;
int hold = board[t_row][t_column];
board[t_row][t_column] = 0;
board[row_new][column_new] = hold;
}
The easiest way I can see to do this would be to pass in the values of the old row and column.
void swap(int row_new, int col_new, int row_old, int col_old) {
int hold = board[row_old][col_old];
board[row_old][column_old] = 0;
board[row_new][column_new] = hold;
}

Variable scope behavior c language

Code snippet:
void function(void)
{
while(1)
{
int i = 0;
i += 1;
if(i == 500) break;
}
}
The variable i is stored in stack every time when restart the loop ?
What is the memory structure when running this code ?
What is the behavior of this variable ?
It is a bad or good practice do this ?
Thanks.
You will never reach i == 500. It's being reset every time through the loop since it's within the scope of while(1){}.
The following will work.
void function(void)
{
int i = 0;
while(1)
{
i += 1;
if(i == 500) break;
}
}
When a function runs in C, it allocates space for all the local variables its going to need. If the variables are allocated all next to each other at the top of the function its easy to see how it works:
void foo(){
int x;
int y;
y = 1;
x = y + 2;
return x + y;
}
If the variables are declared inside inner blocks of the function, what the compiler does is "lift" those variable declarations to the top of the function. If there are variables with clashing names, the compiler renames things for you so they reference the correct variable.
// This is what you write
void original(){
int x = 0;
while(1){
int x = 1;
}
}
// This is what the compiler "sees"
void lifted(){
int x1;
int x2;
x1 = 0;
while(1){
x2 = 0;
}
}
In your case, your code is behaving like this one:
void function(void)
{
int i;
while(1)
{
i = 0;
i += 1;
if(i == 500) break;
}
}
In this version, its clear that the i is being reset to 0 all the time, which is why the loop will run forever.
As for if declaring variables in inner scopes is a good practice or not, it doesn't have to do with memory usage but with the scope of your variable names. In general its a good thing to keep your variables confined to inner scopes if possible (for the same reason why local variables are preferred to global ones). That said, you always have to initialize your variables before the loop and not inside it. In this case, its about removing bugs and not about being a best practice.
Logically speaking, each iteration of the loop creates a new instance of the i variable which only exists within the body of the loop. As written, this code will never terminate, because each iteration of the while loop creates a new instance of i and initializes it to 0.
Attempting to reference i outside the body of the loop results in undefined behavior; IOW, code like
int *p;
while ( 1 )
{
int i = 0;
p = &i;
if ( some_condition )
break;
...
}
printf( "last value of i was %d\n", *p );
isn't guaranteed to do what you expect.
In practice, the generated machine code will set aside the space for i once at function entry; however, you should not rely on that behavior.
The variable i will always be at 0 or 1 in this code; the break will never execute.
The variable i is declared in and is local to the while loop.
In the C language, a pair of braces can create a new scope
that hides variables with the same name declared outside the
scope.
This code:
void function(void)
{
while(1)
{
int i = 0;
i += 1;
if(i == 500) break;
}
}
should be changed to this:
void function(void)
{
int i = 0;
while(1)
{
i += 1;
if(i == 500) break;
}
}

Confusion about error of program in C

When I compile this code I get an error "in front of int val, there isn't" ;
how can I get rid of this error?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char card_name[3];
puts("카드 이름을 입력하세요: ");
int val = 0;
if(card_name[0]=='K') {
val = 10;
}
else if (card_name[0] == 'Q') {
val = 10;
}
else if (card_name[0] == 'J') {
val = 10;
}
else if (card_name[0] == 'A') {
val = 11;
}
else
{
val = atoi(card_name);
}
printf("카드값은 다음과 같습니다 : %i/n", val);
return 0;
}
Declare all variables in the top of main just after { ,i.e, declare val before the first puts. It is because your compiler uses C89 which forbids mixed declarations and code. From C99 onwards , they can be declared (almost) anywhere.
As mentioned in other answers, C89 does not support declaring variables other than at the start of the block. If you are using clang or gcc, you might want to add '-std=gnu99' to your CFLAGS. If using another compiler or an IDE, look for the language and change it to C99 or higher.
It seems that the compiler requires that all definitions of varaibles would be in the beginninh of block.
Try to write
char card_name[3];
int val = 0;
puts("카드 이름을 입력하세요: ");
Also take into account that array card_name is not initialized.

How to get Data & Control Dependency Slice using Frama-c

I was trying to do two things
Get a dynamic backward slice based on a criteria.
Map the slices statements back to the actual source code.
Problem 1: The slice returned by Frama-C doesn't return the exact statements that were relevant for the criteria - mainly the if and else statements.
Problem 2: How do I map the slicing statements back to the source code? The program gets changed when slicing (for example : int a=9 becomes 2 statements in sliced code int a; and a = 9;.) I am ok with the slice but what is the information I can use to map these back to the statements in the source code.
This is the source code.
void main(){
int ip1 = 9;
int ip2 = 3;
int option = 1;
int result = math(option,ip1,ip2);
//# slice pragma expr ((option == 1) || !(result == (ip1+ip2)));
}
int math(int option, int a, int b){
int answer = 0;
if (option == 1){
answer = a+b;
}else{
if (option == 2) {
answer = a-b;
}else { // a ^ b
for(int i=0 ;i<b; i++){
answer=answer*a;
}
}
}
return answer;
}
I use the following command to get the slice.
frama-c t.c -slicing-level 3 -slice-pragma main -slice-print
The slice I get from frama-c is :
void main(void)
{
int ip1;
int ip2;
int option;
int result;
ip1 = 9;
ip2 = 3;
option = 1;
result = math_slice_1(ip1,ip2);
/*# slice pragma expr option≡1∨!(result≡ip1+ip2); */ ;
return;
}
int math_slice_1(int a, int b)
{
int answer;
answer = a + b;
return answer;
}
Problem 1:
I dont get the if and else conditions in the slice. What should I do to get them?
I expected the following slice:
int math_slice_1(int a, int b)
{
int answer;
if (option == 1){
answer = a + b;
}
return answer;
}
Problem 2:
Source code has : int ip1 = 9;
But the sliced code has :
int ip1;
ip1 = 9;
How to map these 2 sliced statements back to the source code statement.
For Problem 1, the test is sliced out because it is always true since option is set to 1 in the main function. If you want to keep the test, you have to make option an entry (either external global variable or a parameter of main for instance), but then, there will be nothing to slice in the math function... The slicing tries to keep only what is strictly necessary, and the test is not in your case.

Resources