void postfix(char *, char *);
이것으로 시작된게 이해가 잘안되,,, 우리조원이 짠건데 먼지 몰겠다,,,
이거 해석 하면 복받을거임 근데 좀 어렵나,,
주석이라도 부탁해 ,,
답글 또는 메일도 좋아~
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>//삼각함수 선언 해더파일
#define MAX 100
#define M_PI 3.141592
#define RD(X) (X)*M_PI/180 //삼각 함수 구하는 공식
typedef enum { lparen, rparen, plus, minus, times, divide, mod, SIN, COS, TAN, eos, operand } precedence;
char stack[MAX]; // 후휘표기법으로 바꿀때 사용할 스택
double stack_eval[MAX]; // 연산시 사용할 스택 double형
int top, top_eval; // 스택의 top
char expr[MAX]; // 입력문자 전열 배열
precedence get_token(char *); // 연산자의 내용을 리턴하는 함수
double eval (char*); // 연산하는 함수
double change_value (char *,int *); // atof 함수
double push_eval(double); // 연산스택 push
double pop_eval(void); // 연산 스택 pop
void postfix(char *, char *); // 후위 표기법으로 바꾸는 함수
void init_stack(void); // 후위표기법의 스택의 초기화
char push(char);
char get_stack_top(void);
char is_stack_empty(void);
int is_operator(int);
int precedence_def(int);
void main_a();
int help(); //도움말 함수
int help_a();
int help_b();
int help_c();
int calc1();
void main()
{
여긴생략
<BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr>
int selectnum; //입력받은 메뉴의 숫자를 저장
while(1)
{
printf("입력값:");
scanf_s("%d", &selectnum);
if(selectnum==1)
{
help();break;
}
else if(selectnum==2)
{
calc1();break;
}
else if(selectnum==3)
{
while(1)
{
main_a();
}
}
else if(selectnum==4)
{
printf("종료합니다\\n");break;
}
else //정해진 1,2,3,4 이외를 입력시
printf("잘못된 숫자를 입력하셨습니다 다시 입력하세요\\n");
}
}
</BLOCKQUOTE>
int help()
{
<BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr>
여긴생략
</BLOCKQUOTE>
<BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr>
printf("\\n입력값:");
int helpnum;
scanf_s("%d",&helpnum);
switch(helpnum)
{
case 1:
printf("기본도움말\\n");
help_a();
case 2:
printf("함수도움말\\n");
help_b();
case 3:
printf("공식참고자료\\n");
help_c();
case 4:
break;
default :
printf("잘못된 값을 입력하셨습니다\\n");
}
return 0;
}
</BLOCKQUOTE>
int help_a()
{
printf("\\n여기에는 기본도움말에 관한 자료를 입력\\n");
return help();
}
int help_b()
{
여긴생략
return help();
}
int help_c()
{
printf("\\n여기에는 공식참고자료에 관한 자료를 입력\\n");
return help();
}
<BLOCKQUOTE style="MARGIN-RIGHT: 0px" dir=ltr>
void main_a()
{
double result; // 모든 연산의 결과값을 리턴받는다.
char c,str[MAX]; // 문자열로 입력받을 변수, 배열
int i; // 인덱스
for ( i=0 ; (c=getchar()) != \'\\n\' ; i++ ) // 문자열을 받아서 배열에 넣는 루프
{
str[i] = c;
}
str[i] = \'\\0\';
postfix(expr,str);
//printf("%s\\n",expr);
result = eval (expr); // 최종 계산된 값을 리턴받는다.
printf("%lf\\n", result);
}
</BLOCKQUOTE>
double eval (char *expr) // 연산하는 함수
{
precedence token; // 변수 선언
double value, value_frist, value_secound;// 연산을 위해 필요한 변수
int i;
int top_eval = -1; // 스택의 초기화
for ( i=0 ; expr[i] != \'\\0\' ; i++) // 배열을 끝까지 검색하면서 연산
{
if( expr[i] == \' \' ) // 빈공간이면 다음칸으로 이동한다.
i++;
token = get_token(&expr[i]); // token값을 리턴받는다.
if ( token == operand )
{
value = change_value(&expr[i],&i);// 함수 숫자값(char)을 받아서 숫자값을(double) 리턴해주는 함수
push_eval(value); // 스택에 삽입
}
else if ( (token == SIN) || (token == COS) || (token == TAN) )
{
value_frist = pop_eval();//맨위의 숫자를 연산한다.
switch (token) // 삼각함수 연산시
{
case SIN : push_eval( sin( RD(value_frist)) );
break;
case COS : push_eval( cos( RD(value_frist)) );
break;
case TAN : push_eval( tan( RD(value_frist)) );
break;
}
}
else // 연산자가 들어 있다면
{
if (i==0 && token ==\'-\')
{
value = change_value(&expr[i],&i);// 함수 숫자값(char)을 받아서 숫자값을(double) 리턴해주는 함수
push_eval(value); // 스택에 삽입
}
else
{
value_secound = pop_eval();// 맨위의 값이 나중 값이므로 두번째 변수에 삽입
value_frist = pop_eval();
switch (token) // 연산실시
{
case plus : push_eval(value_frist + value_secound);
break;
case minus : push_eval(value_frist - value_secound);
break;
case times : push_eval(value_frist * value_secound);
break;
case divide : push_eval(value_frist / value_secound);
break;
case mod : push_eval((int)value_frist % (int)value_secound);
break;
}
}
}
}
return pop_eval(); //스택에 마지막으로 남은 숫자를 리턴한다.
}
/*----------- 연산시 사용할 함수--------------------------------------- */
double push_eval(double t) // 연산 스택의 푸시
{
if (top_eval >= MAX - 1)
{
printf("\\n Stack overflow.");
exit(1);
}
stack_eval[++top_eval] = t;
return t;
}
double pop_eval(void) // 연산 스택의 팝
{
if (top_eval < 0)
{
printf("\\n Stack underflow.");
exit(1);
}
return stack_eval[top_eval--];
}
double change_value (char *num, int *index) // atof 함수
{
double value; // 임시저장 값
char temp[MAX]; // 임시 배열
int i,k;
for ( i=0 ; num[i] != \' \' ; i++ ) // 빈킨을 만날때 까지 배열을 검색
temp[i] = num[i]; // 임시 배열에 넣는다.
temp[i] =\'\\0\';
value = atof (temp); //float값
k = *index;
*index = k+i; // eval함수에서 i(index)값 자체를 변환
return value; // 변환된 값을 리턴
}
precedence get_token (char *p) // 연산자 정의
{
switch ( *p )
{
case \'(\': return lparen;
case \')\': return rparen;
case \'+\': return plus;
case \'-\': return minus;
case \'*\': return times;
case \'/\': return divide;
case \'%\': return mod;
case \'s\': return SIN;
case \'c\': return COS;
case \'t\': return TAN;
case \'\\0\': return eos;
default: return operand;
}
}
//----------------------------후위표기법으로의 변환시 사용할 함수--------------------------
void init_stack(void)
{
top = -1;
}
char push(char t)
{
if (top >= MAX - 1)
{
printf("\\n Stack overflow.");
exit(1);
}
stack[++top] = t;
return t;
}
char pop(void)
{
if (top < 0)
{
printf("\\n Stack underflow.");
exit(1);
}
return stack[top--];
}
char get_stack_top(void)
{
return (top < 0) ? -1 : stack[top];
}
char is_stack_empty(void)
{
return (top < 0);
}
int is_operator(int k)
{
return (k == \'+\' || k == \'-\' || k == \'*\' || k == \'/\');
}
int precedence_def(int op)
{
if (op == \'(\') return 0;
if (op == \'+\' || op == \'-\') return 1;
if (op == \'*\' || op == \'/\') return 2;
else return 3;
}
void postfix(char *dst, char *src) // 후위표기로의 변환
{
int opernext=0, opercmt=0;
int cmt=0;
init_stack();
while (*src!=\'\\0\') // NULL까지 순환
{
if (*src == \'(\') // ( 만나면 푸시
{
if (opercmt % 2 !=0)
{
*dst++ = \'-\';
*dst++ = \'1\';
*dst++ = \' \';
push(\'*\');
opercmt=0;
}
push(*src);
src++;
}
else if (*src == \')\')
{
while (get_stack_top() != \'(\') // 스택의 top이 \'(\' 아니냐?
{
*dst++ = pop(); // 아니면 연산자를 팝
*dst++ = \' \'; // 빈킨을 만듬
}
pop();// \'(\' 이것을 지움
src++;
if ((get_stack_top() == \'s\') || (get_stack_top() == \'c\') || (get_stack_top() == \'t\') )
{ // 괄호가 끝이난후 삼각함수의 연산자가 들어 있는지 검사
*dst++ = pop(); // true일경우 팝
*dst++ = \' \';
}
else;
}
else if (is_operator(*src)) // 연산자일 경우
{
if (cmt==0 && *src==\'-\' || (opernext != 0 && *src==\'-\'))
{//처음이 \'-\'이거나 연산자뒤에 \'-\'경우
opercmt++;
opernext++;
*src++;
}
else
{
if ((get_stack_top() == \'s\') || (get_stack_top() == \'c\') || (get_stack_top() == \'t\') )
{// 스택의 탑이 삼각함수인지 검사. 이유 괄호다음의 우선순위는 삼각함수이다.
*dst++ = pop();
*dst++ = \' \';
}
while (!is_stack_empty() && precedence_def(get_stack_top()) >= precedence_def(*src))
{// 사칙연산의 우선순위를 정하는 루프
*dst++ = pop();
*dst++ = \' \';
}
opernext++;
push(*src);
src++;
}
}
else if (*src >= \'0\' && *src <= \'9\') // 숫자가 들어올경우
{
if(opercmt % 2 != 0)
{
*dst++ = \'-\';
}
do {
*dst++ = *src++; // 숫자를 배열에 넣는다. 숫자가 아닌것이 나올때 까지
} while ((*src >= \'0\' && *src <= \'9\') || *src == \'.\');
*dst++ = \' \'; // 다한다음 빈공간을 넣는다.
opernext=0;
opercmt=0;
}
else if ( *src == \'.\' )
*dst++ = *src++;
else if ( *src == \'s\' ) // sin을 만날경우 첫문자가 \'s\'임으로 검사
{
push(*src);
src = src+3; // sin글씨 세게의 다음으로 이동
}
else if ( *src == \'c\' )
{
push(*src);
src = src+3;
}
else if ( *src == \'t\' )
{
push(*src);
src = src+3;
}
else
src++; // 아무것도 경우에 없을경우는 다음으로
cmt++;
}
while (!is_stack_empty()) // 배열의 NULL까지 검사를 다한후 스택의 내용을 출력한다.
{
*dst++ = pop();
*dst++ = \' \';
}
dst--;
*dst = \'\\0\'; // 후위표기법으로 바꾼 배열의 마지막에 NULL을 넣는다.
}
int calc1()
{
int calc_1, calc_2;
char op;
int recent;
//double calc_11, calc_22;
while(1){
scanf_s("%d", &calc_1);
scanf_s("%c", &op);
scanf_s("%d", &calc_2);
//calc_1 = calc_11;
//calc_2 = calc_22;
switch(op)
{
case \'+\' : recent = calc_1 + calc_2;
printf("%d\\n", recent);calc1();
case \'-\' : recent = calc_1 - calc_2;
printf("%d\\n", recent);calc1();
case \'*\' :
recent = calc_1 * calc_2;
printf("%d\\n", recent);calc1();
case \'/\' : recent = calc_1 / calc_2;
printf("%d\\n", recent);calc1();
}
return 0;
}
return 0;
}
댓글 영역
획득법
① NFT 발행
작성한 게시물을 NFT로 발행하면 일주일 동안 사용할 수 있습니다. (최초 1회)
② NFT 구매
다른 이용자의 NFT를 구매하면 한 달 동안 사용할 수 있습니다. (구매 시마다 갱신)
사용법
디시콘에서지갑연결시 바로 사용 가능합니다.