Разделно компилиране
Създаване
на заглавни файлове
* Стек - пример
s.push("Able")
s.push("Backer")
s.push("Charlie")
s.pop() -> "Charlie"
s.push("Delta")
s.pop() -> "Delta"
s.pop() -> "Backer"
s.pop() -> "Able"
* Създаване на клас
class Stack {
public:
Stack();
void push(string s);
string pop();
bool is_empty() const;
private:
vector<string> data;
int top;
};
Stack::Stack() { top = 0; }
void Stack::push(string s)
{
if (top < data.size()) data[top]
= s;
else data.push_back(s);
top++;
}
string Stack::pop()
{
assert(top > 0);
top--;
return data[top];
}
bool Stack::is_empty() const {
return top == 0; }
* Разделяне на информацията между stack.h
и stack.cpp
// stack.h
#include <vector>
#include <string>
using namespace std;
class Stack {
public:
Stack();
void push(string s);
string pop();
bool is_empty() const;
private:
vector<string> data;
int top;
};
// stack.cpp
#include <cassert>
using namespace std;
#include "stack.h"
Stack::Stack() { top = 0; }
void Stack::push(string s)
{
if (top < data.size()) data[top]
= s;
else data.push_back(s);
top++;
}
string Stack::pop()
{
assert(top > 0);
top--;
return data[top];
}
bool Stack::is_empty() const { return top == 0; }
*Проблемът за двукратно включване на един и същи заглавен файл в програмата
#ifndef STACK_H
#define STACK_H
...
#endif
Разделяне на програмата на няколко първични файла
// error.h
#ifndef ERROR_H
#define ERROR_H
#include <string>
using namespace std;
void error(string message);
#endif
// input.h
#ifndef INPUT_H
#define INPUT_H
#include <string>
using namespace std;
bool is_operator(string s);
string next_token();
#endif
// eval.h
#ifndef EVAL_H
#define EVAL_H
#include <string>
using namespace std;
#include "stack.h"
int precedence(string s);
void evaluate(Stack& num, string op);
#endif
// error.cpp
#include <iostream>
#include <string>
using namespace std;
#include "error.h"
void error(string message)
{
cout << "ERROR: " <<
message << ".\n";
exit(1);
}
// eval.cpp
#include <string>
#include <sstream>
#include <cmath>
using namespace std;
#include "stack.h"
#include "error.h"
#include "eval.h"
int precedence(string s)
{
if (s == "+" or s == "-")
return 1;
else if (s == "*" or s == "/")
return 2;
else if (s == "^")
return 3;
else
return 0;
}
double string_to_double(string s)
{
istringstream instr(s);
double x;
instr >> x;
return x;
}
string double_to_string(double x)
{
ostringstream outstr;
outstr << x;
return outstr.str();
}
void evaluate(Stack& num, string op)
{
if (num.is_empty()) error("Syntax
error");
double y = string_to_double(num.pop());
if (num.is_empty())
error("Syntax error");
double x = string_to_double(num.pop());
double z;
if (op == "^") z = pow(x,
y);
else if (op == "*") z = x
* y;
else if (op == "/")
{ if (y == 0) error("Divide
by 0");
else z
= x / y;
}
else if (op == "+") z = x
+ y;
else if (op == "-") z = x
- y;
else error("Syntax error");
num.push(double_to_string(z));
}
// input.cpp
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
#include "error.h"
#include "input.h"
bool is_operator(string s)
{
return s == "+" or s == "-" or
s == "*" or s == "/" or s == "^";
}
void skip_whitespace()
{
char ch;
do
{ cin.get(ch);
if (cin.fail())
return;
} while (isspace(ch));
#ifndef CCC_USE_OLD_STREAMS
cin.unget();
#else
cin.putback(ch);
/* used if your compiler doesn't support
the ANSI unget function */
#endif
}
string next_number()
{
string r;
bool more = true;
while (more)
{ char ch;
cin.get(ch);
if (cin.fail())
more = false;
else if
(isdigit(ch)) r = r + ch;
else
{
#ifndef CCC_USE_OLD_STREAMS
cin.unget();
#else
cin.putback(ch);
/* used if your compiler doesn't support
the ANSI unget function */
#endif
more = false;
}
}
return r;
}
string next_token()
{
skip_whitespace();
char ch;
cin.get(ch);
if (cin.fail()) return "";
if (isdigit(ch))
{
#ifndef CCC_USE_OLD_STREAMS
cin.unget();
#else
cin.putback(ch);
/* used if your compiler doesn't support the ANSI unget function */
#endif
return
next_number();
}
else
{ string token;
token =
token + ch;
if (is_operator(token)
or token == "(" or token == ")"
or token == "=") return token;
else
{
string message = "Unexpected input ";
error(message + ch);
return "";
}
}
}
// calc.cpp
#include <iostream>
#include <string>
using namespace std;
#include "stack.h"
#include "input.h"
#include "eval.h"
#include "error.h"
int main()
{
Stack numstack;
Stack opstack;
while (true)
{ string s = next_token();
if (is_operator(s))
{ if (opstack.is_empty())
opstack.push(s);
else
{ string old_op = opstack.pop();
if (precedence(s) >
precedence(old_op)) stack.push(old_op);
else
evaluate(numstack,
old_op);
opstack.push(s);
}
}
else if (s == "(") opstack.push(s);
else if (s == ")")
{ bool more = true;
while (more)
{ if (opstack.is_empty())
error("No matching (");
string old_op = opstack.pop();
if (old_op == "(")
more = false;
else evaluate(numstack,
old_op);
}
}
else if (s == "=")
{ while (not opstack.is_empty())
{ string old_op = opstack.pop();
if (old_op == "(")
error("No matching )");
else evaluate(numstack,
old_op);
}
if (numstack.is_empty())
error("Syntax error");
cout << numstack.pop()
<< "\n";
if (not numstack.is_empty())
error("Syntax error");
}
else if (s == "") /* end of input
*/
return 0;
else /* must be a number */
numstack.push(s);
}
}
Поделяне на
променливи между модули
Проекти