c++应输入标识符_4.关键字、常数、常量、变量、标识符、运算符、表达式、数据类型...

三、关键字、常数、常量、变量、标识符、运算符、表达式、数据类型

下面通过几个例子介绍程序中一些要素和基本概念,以及程序设计、逐步求精技术等内容。

例1.3.2 编写程序,输入一个整数,代表圆的半径,计算并输出圆的面积和内接正方形的面积。

491bdce63882656098bcd397d0214deb.png

输入、保存、编译并运行上面程序。若程序运行时输入2,按回车键,则输出结果如下:

Circle=12.5664 //printf("Circle=%lfn", s_y); s_y的值输出在"Circle=%lfn"的占位符%lf所占的位置上。

Square=8

我们已经了解程序的结构,下面我们结合例1.3.2介绍程序的一些基本概念及要素。敬请强烈关注。

关键字:C、C++语言专用的用以表示特定语法结构的单词,又称为保留字,如int、double、return。

常数与常量:第3行的3.14159为常数,常数有4种类型,整型(整数常数,例如35)、浮点型(3.14)、字符型(如'A',见下面字符型介绍)、字符串常数("Square="、" Welcome to c++!" )。第三行#define定义了符号常量pi,它的值为3.14159,编译做预先处理时,程序中出现pi的地方,均以 3.14159替代。

变量:6、7行是程序中函数体的说明部分,定义了r、s_z两个整型变量及s_y浮点型(实型)变量,变量也称为内存变量,它是分配给运行程序用来存放数据带有名字且指定了存放特定类型数据内存区域。为方便理解,可以把变量想象成存放数据的盒子。

标识符(ID):指我们给程序中的对象(函数、常量、变量等)起的名字,标识符是以字母或下划线开头,后面跟随字母、数字、下划线的字符串。例如r、s_y、PrintStr、pi、_A、qw123、first_name是正确的标识符;2abc、int(保留字)、d#是错误的标识符。给对象起名字,最好能做到“见字识义”。

运算符与表达式:算术运算符有:+、-、*、/ 、%,C语言中“=”为赋值运算符,运算符把操作对象连接起来表示特定的运算就构成了表达式(例如:pi*r*r、s_z=r*r),表达式更为专业的定义是:常量、变量是表达式,运算符连接起来的表达式是表达式……。

编程者在程序中写表达式,程序被执行时计算机进行表达式计算。对于赋值表达式,计算机执行时,先计算“=”右边的值,然后把结果转换成“=”左边变量类型的值,并赋值(装入)给该变量。

C++提供了丰富的运算符,如关系运算符“>、>=(大于等于)、<、<=、 ==(相等比较)、 !=(不等于)”,计算机执行关系运算时,比较两个对象的关系,结果为真或假,1(非零)表示真,0(零)表示假。

例如“4!=3”的值为真,“(3+2)==5”为真,“3>=4”为假。

命令“cout<<(4!=3)”输出的值是1;命令“cout<<(4<=3)”输出的值是0。

赋值“=”:有“=”算符的表达式称为赋值表达式(例:s=pi*r*r,假设s是整型变量),计算机执行赋值表达式时,先计算“=”号右边的值(pi*r*r,结果是浮点型),然后把结果转换成“=”左边变量(整型变量s)的类型的值(这里要去掉小数点后的数),并赋值(装入)给该变量(s)。凡是表达式,执行运算后都有值,这个赋值表达式的值,就是最后赋值的值。所以,cout<<(x=4+3);输出7,y=(x=3+4); y的值是7。

数据类型:常量、变量都是有特定类型的数据,类型规定了数据占用内存的大小,规定能对它们进行的运算。不同类型的数据,方便表示不同的客观事物属性,如班级人数用整型数表示,体重用浮点型数表示,而姓名用字符串表示。

下面通过一些例子(5.数值计算,整型及浮点型——int、double、6.文字处理,字符型及字符串型——char、string)来介绍各种数据类型、相关的运算及其它们的运用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
表达式语法分析器是一个程序,它可以解析并计算数学表达式。它的实现原理如下: 1. 词法分析:将输入的字符串分解成多个单词,如标识符常量运算符等。这个过程称为词法分析。 2. 语法分析:将分解后的单词按照规则组合成语法树。这个过程称为语法分析。在语法分析过程中,会检查表达式中是否有语法错误,例如括号不匹配或者操作符使用不正确等。如果有错误,则会提示用户。 3. 计算表达式:在语法分析完成后,将语法树上的节点进行计算,得出表达式的结果。 C++代码实现示例: ```cpp #include <iostream> #include <string> #include <map> #include <stack> #include <vector> #include <cmath> using namespace std; // 定义词法分析的单词类型 enum TokenType { TOK_IDENTIFIER, // 标识符 TOK_CONSTANT, // 常数 TOK_PLUS, // + TOK_MINUS, // - TOK_MULTIPLY, // * TOK_DIVIDE, // / TOK_LEFTPAREN, // ( TOK_RIGHTPAREN, // ) TOK_UNKNOWN // 未知类型 }; // 定义语法树节点类型 enum NodeType { NODE_CONSTANT, // 常数节点 NODE_IDENTIFIER, // 标识符节点 NODE_UNARYOP, // 一元运算符节点 NODE_BINARYOP, // 二元运算符节点 NODE_FUNCTION_CALL // 函数调用节点 }; // 定义运算符的优先级 map<TokenType, int> OperatorPrecedence = { {TOK_PLUS, 1}, {TOK_MINUS, 1}, {TOK_MULTIPLY, 2}, {TOK_DIVIDE, 2} }; // 定义词法分析器 class Lexer { public: Lexer(string input) : input(input) {} // 获取下一个单词 TokenType getNextToken(string& tokenValue) { tokenValue = ""; // 跳过空格 while (pos < input.length() && isspace(input[pos])) { pos++; } if (pos >= input.length()) { return TOK_UNKNOWN; } // 判断单词类型 if (isalpha(input[pos])) { // 标识符 while (pos < input.length() && (isalnum(input[pos]) || input[pos] == '_')) { tokenValue += input[pos]; pos++; } return TOK_IDENTIFIER; } else if (isdigit(input[pos])) { // 常数 while (pos < input.length() && (isdigit(input[pos]) || input[pos] == '.')) { tokenValue += input[pos]; pos++; } return TOK_CONSTANT; } else { // 运算符或括号 switch (input[pos]) { case '+': pos++; return TOK_PLUS; case '-': pos++; return TOK_MINUS; case '*': pos++; return TOK_MULTIPLY; case '/': pos++; return TOK_DIVIDE; case '(': pos++; return TOK_LEFTPAREN; case ')': pos++; return TOK_RIGHTPAREN; default: pos++; return TOK_UNKNOWN; } } } private: string input; int pos = 0; }; // 定义语法树节点 class ASTNode { public: ASTNode(NodeType type, string value = "") : type(type), value(value) {} NodeType getType() const { return type; } double evaluate() const { switch (type) { case NODE_CONSTANT: return stod(value); case NODE_IDENTIFIER: return variables[value]; case NODE_UNARYOP: if (value == "-") { return -child->evaluate(); } else { return child->evaluate(); } case NODE_BINARYOP: switch (value[0]) { case '+': return left->evaluate() + right->evaluate(); case '-': return left->evaluate() - right->evaluate(); case '*': return left->evaluate() * right->evaluate(); case '/': return left->evaluate() / right->evaluate(); default: throw "Unknown operator: " + value; } default: throw "Unknown node type"; } } // 释放语法树的内存 void free() { if (child) { child->free(); delete child; child = nullptr; } if (left) { left->free(); delete left; left = nullptr; } if (right) { right->free(); delete right; right = nullptr; } } string value; // 值 ASTNode* child = nullptr; // 子节点 ASTNode* left = nullptr; // 左子节点 ASTNode* right = nullptr; // 右子节点 private: NodeType type; static map<string, double> variables; // 变量表 }; map<string, double> ASTNode::variables; // 定义语法分析器 class Parser { public: Parser(string input) : lexer(input) {} ASTNode* parse() { auto rootNode = parseExpression(); if (currentToken != TOK_UNKNOWN) { throw "Unexpected token: " + currentToken; } return rootNode; } private: // 解析表达式 ASTNode* parseExpression(int precedence = 0) { auto leftNode = parsePrimary(); while (true) { auto token = lexer.getNextToken(currentTokenValue); auto tokenPrecedence = OperatorPrecedence[token]; if (tokenPrecedence == 0 || tokenPrecedence <= precedence) { break; } lexer.getNextToken(currentTokenValue); if (token == TOK_MINUS) { // 一元运算符 auto unaryNode = new ASTNode(NODE_UNARYOP, "-"); unaryNode->child = leftNode; leftNode = unaryNode; } else { // 二元运算符 auto binaryNode = new ASTNode(NODE_BINARYOP, currentTokenValue); binaryNode->left = leftNode; binaryNode->right = parseExpression(tokenPrecedence); leftNode = binaryNode; } } return leftNode; } // 解析基础表达式 ASTNode* parsePrimary() { auto token = lexer.getNextToken(currentTokenValue); ASTNode* node = nullptr; switch (token) { case TOK_IDENTIFIER: // 标识符 node = new ASTNode(NODE_IDENTIFIER, currentTokenValue); break; case TOK_CONSTANT: // 常数 node = new ASTNode(NODE_CONSTANT, currentTokenValue); break; case TOK_LEFTPAREN: // 括号 node = parseExpression(); if (lexer.getNextToken(currentTokenValue) != TOK_RIGHTPAREN) { throw "Expecting right parenthesis"; } break; default: throw "Unexpected token: " + token; } return node; } Lexer lexer; TokenType currentToken = TOK_UNKNOWN; string currentTokenValue; }; int main() { while (true) { cout << "> "; string input; getline(cin, input); if (input == "quit") { break; } try { Parser parser(input); auto rootNode = parser.parse(); cout << rootNode->evaluate() << endl; rootNode->free(); delete rootNode; } catch (const char* error) { cout << error << endl; } } return 0; } ``` 上述代码实现了一个简单的表达式语法分析器,支持基本的运算符和括号,并可以计算表达式的结果。其中,关键的步骤包括词法分析、语法分析、语法树构建和表达式求值。在词法分析中,程序首先会跳过空格,然后根据字符类型确定单词类型,例如标识符常数运算符或括号等。在语法分析中,程序将单词组合成语法树,判断表达式是否符合语法规则,并检查是否有语法错误。在语法树构建完成后,程序对语法树进行遍历,计算表达式的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值