另一个人不了解main.cpp,program_name.cpp和program_name的联系。

Another person doesn't understand the linkage of main.cpp, program_name.cpp and program_name.h

本文关键字:name cpp program 联系 不了解 另一个人 main      更新时间:2023-10-16

我试图查看有关此事的旧堆栈溢出帖子,但我仍然感到困惑,非常感谢有人向我解释我在这里出错的地方。

我正在使用Apple XCode 3,我的项目的"Source"文件夹中有三个文件。它们是calcsteps.cpp,calcsteps.h和main.cpp。

在我的主要我有#include "calcsteps.h".根据我的理解,这实际上是粘贴calcsteps.h的内容,这些内容只是一堆函数声明。该 .h 文件中没有指令。但是,我的同名.cpp文件有一个指令,也有一个指令#include "calcsteps.h"

主.cpp:

#include "calcsteps.h"
#include <string>
#include <iostream>
int main (int argc, char* const argv[]) {
    // Evaluate expressions at the console
    std::string eqtn; 
    while (std::cin >> eqtn) {
        if (!valid_equation(eqtn)) { 
            std::cout << "Equation invalid; not evaluated" << std::endl;
        } else { 
            std::cout << evaluate_equation(eqtn) << std::endl;
        }
    }
    return 0;
}

Calcsteps.h:

std::string evaluate_equation(std::string);
bool valid_equation(const std::string&); 
int str2Int(const std::string&);
std::string int2Str(unsigned int);
bool isDigit(char);
bool isOp(char);
std::string addStrs(const std::string&, const std::string&);
std::string subtrctStrs(const std::string&, const std::string&);
std::string multStrs(const std::string&, const std::string&);
std::string divStrs(const std::string&, const std::string&);
std::string powStr(const std::string&, const std::string&);

计算步骤.cpp:

#include "calcsteps.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>

std::string evaluate_equation(std::string eq) {
    /* By the order of operations: 
     (1) Evaluate the expression in the innermost set of paranthesis;
     (2) Evaluation exponents;
     (3) Evaluate multiplication and division expressions left-to-right;
     (4) Evaluate addition and substraction expressions left-to-right;
     Use recursion. Print out steps.
     */
    // (1): 
    size_t LRFP = eq.find_last_of('('); // position of last right-facing paranthesis
    if (LRFP != std::string::npos) {
        // Set NLFP to be the position of the next left-facing paranthesis after the FRFPL
        size_t NLFP = LRFP; 
        while (eq[++NLFP] != ')'); 
        /* Replace the space between FRFP and NLFP inclusive with the evalulation of the expression 
         between FRFP and NLFP exclusive:
         */
        std::string paranstr = eq.substr(LRFP + 1, NLFP - LRFP - 1);
        std::cout << eq << " -> ";
        eq.replace(LRFP, NLFP - LRFP + 1, evaluate_equation(paranstr));
        std::cout << eq << std::endl;
        return evaluate_equation(eq);
    }
    // (2):
    size_t firstexp = eq.find_first_of('^');
    if (firstexp != std::string::npos) {
        // Set base and power equal to the respective numbers to the left and right of the '^' symbol
        std::string base, power; 
        size_t basebegin(firstexp), powerend(firstexp);
        while (basebegin > 0 && isDigit(eq[basebegin - 1]))  
            base.insert(0, 1, eq[--basebegin]);
        int eqsz = eq.size();
        while ((powerend + 1) < eqsz && isDigit(eq[powerend + 1]))
            power.push_back(eq[++powerend]);
        // Replace the space of the multiplication equation base^power with its evaluation:
        std::cout << eq << " -> ";
        eq.replace(basebegin, powerend - basebegin + 1, powStr(base, power));
        std::cout << eq << std::endl;
        return evaluate_equation(eq);
    }
    // (3):
    size_t firstast(eq.find_first_of('*')), firstslash(eq.find_first_of('/')); // position of first asterisk 
    size_t firstMD = std::min(firstast, firstslash);
    if (firstMD != std::string::npos) {
        // Set num1 and num2 equal to the respective numbers to the left and right of the asterisk:
        std::string num1, num2; 
        size_t num1begin(firstMD), num2end(firstMD);
        while (num1begin > 0 && isDigit(eq[num1begin - 1]))  
            num1.insert(0, 1, eq[--num1begin]);
        int eqsz = eq.size();
        while ((num2end + 1) < eqsz && isDigit(eq[num2end + 1]))
            num2.push_back(eq[++num2end]);
        std::cout << eq << " -> ";
        if (firstMD == firstast) { 
            // Replace the space of the multiplication equation num1*num2 with its evaluation:
            eq.replace(num1begin, num2end - num1begin + 1, multStrs(num1, num2));
        } else { 
            // Replace the space of the division equation num1/num2 with its evaluation:
            eq.replace(num1begin, num2end - num1begin + 1, divStrs(num1, num2));
        }
        std::cout << eq << std::endl;
        return evaluate_equation(eq);
    }
    // (4):
    size_t firstplus(eq.find_first_of('+')), firstminus(eq.find_first_of('-'));
    size_t firstAS = std::min(firstplus, firstminus);
    if (firstAS != std::string::npos) {
        // Set num1 and num2 equal to the respective numbers to the left and right of the asterisk:
        std::string num1, num2; 
        size_t num1begin(firstAS), num2end(firstAS);
        while (num1begin > 0 && isDigit(eq[num1begin - 1]))  
            num1.insert(0, 1, eq[--num1begin]);
        int eqsz = eq.size();
        while ((num2end + 1) < eqsz && isDigit(eq[num2end + 1]))
            num2.push_back(eq[++num2end]);
        std::cout << eq << " -> ";
        if (firstAS == firstplus) { 
            // Replace the space of the addition equation num1+num2 with its evaluation:
            eq.replace(num1begin, num2end - num1begin + 1, addStrs(num1, num2));
        } else { 
            // Replace the space of the subtraction equation num1-num2 with its evaluation:
            eq.replace(num1begin, num2end - num1begin + 1, subtrctStrs(num1, num2));
        }
        std::cout << eq << std::endl;
        return evaluate_equation(eq);
    }
    // If we made it to this point, all that's left of the equation is a single number. Return it; 
    return eq; 
}
bool valid_equation(const std::string& eq) { 
    // Equation cannot be empty: 
    if (eq.empty()) { 
        std::cout << "Equation cannot be an empty string" << std::endl;
        return false;
    }
    std::string::const_iterator it = eq.begin();
    // First character must be a right-facing parenthesis or a digit:
    if (*it != '(' && !isDigit(*it)) { 
        std::cout << "Equation cannot start with " << *it << std::endl;
        return false;
    }
    /* Iterate through the characters of the equation to check that it is valid based on 
     which characters are lined up next to which. For example, if two plus signs are found 
     next to each other, that makes the equation meaningless and the our function 
     valid_equation() immediately returns false.
     */
    // Count for the number of right-facing and left-facing parantheses:
    int RFPcnt(0), LFPcnt(0); 
    while ((it + 1) != eq.end()) { 
        if (isDigit(*it)) { 
            char nextchar = *(it + 1);
            if (!isDigit(nextchar) && !isOp(nextchar)) { 
                std::cout << "Digit cannot be followed by " << nextchar << std::endl;
                return false;
            } else { 
                ++it;
            }
        } else if (isOp(*it)) {
            char nextchar = *(it + 1);
            if (!isDigit(nextchar) && nextchar != '(') { 
                std::cout << "Operator cannot be followed by " << nextchar << std::endl;
                return false;
            } else { 
                ++it;
            }
        } else if (*it == '(') { 
        } else if (*it == ')') { 
        } else { 
            std::cout << "Inavlid character: " << *it << std::endl;
            return false;
        }
    }
    /* At this point, 'it' is the last character in the equation. It must be a digit
     or left-facing parenthesis.
     */
    if (*it != ')' && !isDigit(*it)) { 
        std::cout << "Equation cannot end with " << *it << std::endl;
        return false;
    }
    // Check for unbalanced parentheses
    if (LFPcnt != RFPcnt) { 
        std::cout << "Unbalanced parantheses." << std::endl;
        return false;
    }
    return true; // If we made it here, the equation is valid; return true
} 
// Given a decimal representation as a string s, str2Int(s) returns the corresponding decimal as an int
int str2Int(const std::string& str) {
    std::string::const_iterator it = str.begin();
    if (it == str.end()) { 
        std::cout << "Invalid parameter: str2Int() only accepts non-empty strings." << std::endl; 
        return -1;
    }
    int sum = 0;
    while (it != str.end()) {
        if (!isDigit(*it)) { 
            std::cout << "Invalid parameter: str2Int only accepts strings of chars '0' through '9'" << std::endl;
            return -1;
        } else { 
            sum *= 10;
            sum += *it++ - '0';
        }
    }
    return sum;
}
// Given an int n, int2Str(n) return the string representation 
std::string int2Str(unsigned int n) { 
    std::string retstring; 
    if (n == 0) { 
        retstring.push_back('0'); 
        return retstring;
    } else { 
        while (n != 0) { 
            retstring.insert(0, 1, char('0' + n % 10));
            n /= 10;
        }   
        return retstring;
    }
}
// Function that checks whether a given character is in one of '0', '1', ..., '9'
bool isDigit(char c) { 
    return (c >= '0' && c <= '9');
} 
bool isOp(char c) { 
    switch (c) { 
        case '^': return true;
        case '*': return true;
        case '/': return true;
        case '+': return true;
        case '-': return true;
        default: return false;  
    }
}
// Adds 2 string decimal representations and returns the sum as a string decimal representation
std::string addStrs(const std::string& s1, const std::string& s2) { 
    return (int2Str(str2Int(s1) + str2Int(s2)));
}
// Substracts 2 string decimal representations and returns the result as a string decimal representation
std::string subtrctStrs(const std::string& s1, const std::string& s2) { 
    return (int2Str(str2Int(s1) - str2Int(s2)));
}

// Multiplies 2 string decimal representations and returns the sum as a string decimal representation
std::string multStrs(const std::string& s1, const std::string& s2) { 
    return (int2Str(str2Int(s1) * str2Int(s2)));
}
// Divides 2 string decimal representations and returns the quotient as a string decimal representation
std::string divStrs(const std::string& s1, const std::string& s2) { 
    return (int2Str(str2Int(s1) / str2Int(s2)));
}
/* Raises the string decimal representation s to the string decimal representation p power and returns the 
 result as a string decimal representation.
 */
std::string powStr(const std::string& s, const std::string& p) {
    return (int2Str((int)pow((double)str2Int(s), (double)str2Int(p))));
}

当我尝试编译 calcsteps.cpp 时,我在函数实现调用其他函数的所有点都出现错误。任何建议都非常感谢。

您的calcSteps.h不包括包含您使用的标准类型(如 std::string )的声明的标准标头。

这将导致,在许多其他错误消息中,"powStr未在此范围内声明"的语句,因为powStr的声明根本无法理解那些对未知标准类型的引用。

即使您确实在 calcsteps.cpp 中包含这些标头,您在包含 calcSteps.h 之后这样做了。既然你绝对正确,#include就像复制粘贴一样,那么这些内含物来得太晚了。

我们通常在需要的地方包含标头,因此应从 calcSteps.h 中包含标准标头。

我还建议使您的文件名大小写约定保持一致,并且您的calcSteps.h包含保护目前在main.cpp中找到 - 大概是一个错字。