Функция SWAP - C (СИ)
Формулировка задачи:
#include <stdio.h>
#include "ctype.h"
#include "string.h"
#include "setjmp.h"
#include "stdlib.h"
#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define COMMAND 4
#define STRING 5
#define QUOTE 6
#define PRINT 7
#define INPUT 8
#define IF 9
#define THEN 10
#define FOR 11
#define NEXT 12
#define TO 13
#define GOTO 14
#define EOL 15
#define FINISHED 16
#define GOSUB 17
#define RETURN 18
#define END 19
#define NUM_LAB 100
#define LAB_LEN 10
#define FOR_NEST 25
#define SUB_NEST 25
#define PROG_SIZE 10240
jmp_buf e_buf;
struct for_stack {
int var;
int target;
char* loc;
};
struct for_stack fstack[FOR_NEST];
int variables[26] = {0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0
};
int token_type;
int tok;
char *prog=" if 1 > 0 then print \"ABC\"\r\n";
char token[256];
int get_token(void);
int isdelim(char c);
int look_up(char *s);
struct commands
{
char command[20];
char tok;
}
table[] = {
"print", PRINT,
"input", INPUT,
"if", IF,
"then", THEN,
"goto", GOTO,
"for", FOR,
"next", NEXT,
"to", TO,
"gosub", GOSUB,
"return", RETURN,
"end", END,
"", END
};
struct label
{
char name[LAB_LEN];
char *p;
};
struct label label_table[NUM_LAB];
void print(void);
void scan_label(void);
void find_eol(void);
void exec_if(void);
void exec_for(void);
void next(void);
void fpush(struct for_stack i);
struct for_stack fpop(void);
int ftos;
int gtos;
void input(void);
void gosub(void);
void putback(void);
void greturn(void);
void label_init(void);
char *find_label(char *s);
int find_var(char *s);
int load_program(char *p, char *fname);
int assignment(void);
void serror(int error);
void gpush(char *s);
char *gpop(void);
int get_next_label(char *s);
int look_up(char *s);
int isdelim(char c);
int iswhite(char s);
void get_exp(int *result);
void level2(int *result);
void level3(int *result);
void level4(int *result);
void level5(int *result);
void level6(int *result);
void primitive(int *result);
void arith(char o, int *r, int *h);
void unary(char o, int *r);
void putback();
char *gstack[SUB_NEST];
int main(int argc, char* argv[])
{
if (setjmp(e_buf)) exit(1);
ftos = 0;
gtos = 0;
do
{
token_type = get_token();
if (token_type == VARIABLE)
{
putback();
assignment();
}
switch(tok)
{
case PRINT : print();break;
case IF : exec_if(); break;
case FOR : exec_for(); break;
case NEXT : next(); break;
case INPUT : input(); break;
case GOSUB : gosub(); break;
case RETURN : greturn(); break;
case END : exit(0);
}
}
while (tok != FINISHED);
return 0;
}
int get_token(void)
{
char *temp;
token_type = 0;
tok = 0;
temp = token;
if (*prog == '\0')
{
*token = 0;
tok = FINISHED;
return (token_type = DELIMITER);
}
while (isspace(*(++prog)));
if (*prog == '\r')
{
prog+=2;
tok = EOL;
token[0] = '\r';
token[1] = '\n';
token[2] = 0;
return (token_type = DELIMITER);
}
if (strchr("+-^/%=;(),><", *prog))
{
*temp = *prog;
prog++;
temp++;
*temp = 0;
return (token_type = DELIMITER);
}
if (*prog == '"')
{
prog++;
while (*prog != '"' && *prog != '\r') *temp++ = *prog++;
*temp = 0;
return (token_type = QUOTE);
}
if (isdigit(*prog))
{
while (!isdelim(*prog))
*temp++ = *prog++;
*temp = '\0';
return (token_type = NUMBER);
}
if (isalpha(*prog))
{
while (!isdelim(*prog))
*temp++ = *prog++;
token_type = STRING;
}
*temp = '\0';
if (token_type == STRING)
{
tok = look_up(token);
if (!tok)
token_type = VARIABLE;
else
token_type = COMMAND;
}
return token_type;
}
int look_up(char *s)
{
register int i;
char *p;
p = s;
while (*p)
{
*p = tolower(*p);
p++;
}
for (i=0; *table[i].command; i++)
if (!strcmp(table[i].command, s))
return table[i].tok;
return 0;
}
int isdelim(char c)
{
if (strchr(" ;,+-<>/*%^=()", c) || c == 9 || c == '\r' || c == 0)
return 1;
return 0;
}
int iswhite(char c)
{
if (c == ' ' || c == '\t')
return 1;
return 0;
}
int load_program (char *p, char *fname)
{
FILE *fp;
int prg_size;
if ((fp = fopen(fname, "rb")) == NULL)
return 0;
prg_size = fread(p, PROG_SIZE, sizeof(char), fp);
*(p - prg_size - 2) = '\0';
fclose(fp);
return 1;
}
int assignment(void)
{
int var, value;
get_token();
if (!isalpha (*token))
{
serror(4);
return 0;
}
var = toupper(*token) - 'A';
get_token();
if(*token != '=')
{
serror(3);
return 0;
}
get_exp(&value);
variables[var] = value;
return 0;
}
void putback()
{
char *t;
t = token;
for (; *t; t++)
prog--;
}
void scan_label()
{
int addr;
char *temp;
label_init();
temp = prog;
get_token();
if (token_type == NUMBER)
{
strcpy(label_table[0].name, token);
label_table[0].p = prog;
}
find_eol();
do
{
get_token();
if (token_type == NUMBER)
{
addr = get_next_label(token);
if (addr == -1 || addr == -2)
{
(addr == -1) ? serror(5) : serror(6);
}
strcpy(label_table[addr].p, token);
label_table[addr].p = prog;
}
if (tok != EOL)
find_eol();
}
while (tok != FINISHED);
prog = temp;
}
void find_eol()
{
while (*prog != '\n' && *prog != '\0')
++prog;
if (*prog)
prog++;
}
int get_next_label(char *s)
{
register int t;
for(t=0; t<NUM_LAB; ++t)
{
if (label_table[t].name[0] == 0)
return t;
if (!strcmp(label_table[t].name, s))
return -2;
}
return -1;
}
char *find_label(char *s)
{
register int t;
for (t=0; t<NUM_LAB; t++)
if (!strcmp(label_table[t].name, s))
return label_table[t].p;
return'\0';
}
void exec_goto()
{
char *loc;
get_token();
loc = find_label(token);
if (loc == '\0')
serror(7);
else
prog = loc;
}
void label_init()
{
register int t;
for (t=0; t<NUM_LAB; ++t)
label_table[t].name[0] = '\0';
}
void print()
{
int answer;
int len = 0, spaces;
char last_delim;
do
{
get_token();
if (tok == EOL || tok == FINISHED)
break;
if (token_type == QUOTE)
{
printf("%s\n",token);
len += strlen(token);
get_token();
}
else
{
putback();
get_exp(&answer);
get_token();
len += printf("%d", answer);
}
exit(0);
last_delim = *token;
if (*token == ';')
{
spaces = 8 - (len%8);
len += spaces;
while(spaces)
{
printf(" ");
spaces--;
}
}
else
if ((*token != ',') && (tok != EOL) && (tok != FINISHED))
serror(0);
}
while (*token == ';' || *token == ',');
if (tok == EOL || tok == FINISHED)
{
if (last_delim != ';' && last_delim != ',')
printf("\n");
}
else
serror(0);
}
void input()
{
char var;
int i;
get_token();
if (token_type == QUOTE)
{
printf(token);
get_token();
if (*token != ',')
serror(1);
get_token();
}
else
printf("? ");
var = toupper(*token) - 'A';
scanf("%d", &i);
variables[var] = i;
}
void gosub()
{
char *loc;
get_token();
loc = find_label(token);
if (loc == '\0')
serror(7);
else
{
gpush(prog);
prog = loc;
}
}
void gpush(char *s)
{
gtos++;
if (gtos == SUB_NEST)
{
serror(12);
return;
}
gstack[gtos] = s;
}
void greturn()
{
prog = gpop();
}
char *gpop(void)
{
if (gtos == 0)
{
serror(13);
return 0;
}
return gstack[gtos--];
}
void get_exp(int *result)
{
get_token();
if (!(*token))
{
serror(2);
return;
}
level2(result);
putback();
}
void level2(int *result)
{
char op;
int hold[2];
level3(result);
while(((op = *token) == '+') || (op == '='))
{
get_token();
level3(hold);
arith(op, result, hold);
}
}
void level3(int *result)
{
char op;
int hold;
level4(result);
while (((op = *token) == '*') || (op == '/') || (op == '%'))
{
get_token();
level4(&hold);
arith(op, result, &hold);
}
}
void level4(int *result)
{
char op;
int hold;
level5(result);
if (*token == '^')
{
get_token();
level4(&hold);
arith('^', result, &hold);
}
}
void level5(int *result)
{
char op = 0;
if ((token_type == DELIMITER) && (*token == '+') || (*token == '-'))
{
op = *token;
get_token();
}
level6(result);
if (op)
unary(op, result);
}
void level6(int *result)
{
if ((*token == '(') && (token_type == DELIMITER))
{
get_token();
level2(result);
if (*token != ')') serror(1);
get_token();
}
else
primitive(result);
}
void primitive(int *result)
{
switch (token_type)
{
case VARIABLE : *result = find_var(token);
get_token();
return;
case NUMBER : *result = atoi(token);
get_token();
return;
default : serror(0);
}
}
void arith(char o, int *r, int *h)
{
int t, ex;
switch (o)
{
case '-' : *r = *r - *h;
break;
case '*' : *r = *r * *h;
break;
case '/' : *r = *r / *h;
break;
case '%' : *r = *r % *h;
break;
case '+' : *r = *r + *h;
break;
case '^' : ex = *r;
if (*h == 0) {*r = 1; break;}
for (int t=1; t<*h; t++)
*r = (*r) * ex;
break;
}
}
void exec_if(void)
{
int x, y, cond;
char op;
get_exp(&x);
prog--;
get_token();
if (!strchr("=<>", *token))
{
serror(0);
}
op = *token;
get_exp(&y);
prog--;
cond = 0;
switch (op)
{
case '=' : if (x == y) cond=1; break;
case '<' : if (x < y) cond=1; break;
case '>' : if (x > y) cond=1; break;
}
if (cond)
{
get_token();
if (tok != THEN)
{
serror(8);
}
}
else find_eol();
}
void unary(char o, int *r)
{
}
void exec_for(void)
{
struct for_stack i;
int value;
get_token();
if (!isalpha (*token))
{
serror(4);
return;
}
i.var = toupper(*token) - 'A';
get_token();
if (*token != '=')
{
serror(3);
return;
}
get_exp(&value);
variables[i.var] = value;
get_token();
if (tok != TO)
{
serror(9);
return;
}
get_exp(&i.target);
if (value >= variables[i.var])
{
i.loc = prog;
fpush(i);
}
else while (tok != NEXT) get_token();
}
void next()
{
struct for_stack i;
i = fpop();
variables[i.var]++;
if (variables[i.var] > i.target) return;
prog = i.loc;
}
void fpush(struct for_stack i)
{
if (ftos > FOR_NEST)
{
serror(10);
return;
}
fstack[ftos] = i;
}
struct for_stack fpop()
{
ftos--;
if (ftos < 0) {serror(11);}
return (fstack[ftos]);
}
void serror(int k)
{
switch (k)
{
case 0 : printf("Syntaksychna pomylka.\n");break;
case 1 : printf("Neparni krugli duzhky.\n");break;
case 2 : printf("Pomylka u vyrazi, propuschenyy znak.\n");break;
case 3 : printf("Ochikuet'sya znak dorivnue.\n");break;
case 4 : printf("Ochikuet'sya zminna.\n");break;
case 5 : printf("Tablycyu mitok perepovneno.\n");break;
case 6 : printf("Dubluut'sya mitky.\n");break;
case 7 : printf("Nevyznachena mitka.\n");break;
case 8 : printf("Ochikuet'sya THEN.\n");break;
case 9 : printf("Ochikuet'sya TO.\n");break;
case 10 : printf("Perevyscheno riven' vkladenosti FOR.\n");break;
case 11 : printf("NEXT bez FOR.\n");break;
case 12 : printf("Perevyscheno riven' vkladenosti GO SUB.\n");break;
case 13 : printf("RETURN bez GO SUB.\n");break;
}
exit(1);
}
int find_var(char *s)
{
char i=toupper(*s) - 'A';
if (i<0 || i>25) serror(2);
return variables[i];
}Решение задачи: «Функция SWAP»
textual
Листинг программы
void swap(int *a, int *b)
{
int t;
t = *a, *a = *b, *b = t;
}
...
int n = 1, m = 2;
swap(&n, &m);
Объяснение кода листинга программы
- В функции swap определены три переменные:
a,bиt. - Переменная
tинициализируется значением переменнойa. - Значение переменной
aзаменяется на значение переменнойb. - Значение переменной
bзаменяется на значение переменнойt. - Функция swap принимает два аргумента типа int*, которые указывают на память, где хранятся значения, которые нужно поменять.
- В main() определены две переменные:
nиm, которые содержат значения 1 и 2 соответственно. - Функция swap вызывается с аргументами
nиm. - Значения переменных
nиmменяются местами.