C语言中 . -> & * ** typedef符号或操作符的用法

1. 结论

大家在看数据结构清华版书时,经常会被里面的 * . -> typedef c语言 c++的切换看的云里雾里,运行里面伪代码经常很困扰,网上也大多把c语言和c++看成一起混合编译处理,导致大家单纯想理解c语言造成很多困扰,下面这篇文章仅针对于c语言详细说明上面几个符号的用法,帮助大家理解纯c代码。

先说结论,在C语言中,对于一个结构体类型变量a

a.next
(&a)->next

上面两种写法是等价的

2. 变量名、地址和多级指针

int a = 1;

对于上面这段代码

可以看成在操作系统内部做了上图的操作,首先,创建了一块内存大小为4个字节,首地址0x0000,结束地址为0x0004,对于编译器来说,该内存与变量名a绑定,通过变量名a,编译器能够知道变量类型为int,为什么叫对于编译器来说呢?因为在程序实际运行的过程中,a对于该程序的运行是没有任何意义的,里面可能存储的是 (0x0000)=4类似的语句,变量名a只是为了方便给人看的。

c语言是允许读取和操作地址的,就有以下语句

int* ptr_a = &a;
以下是用C语言实现自下而上的边分析边计算功能的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_STACK_SIZE 100 // 定义操作数栈结构体 typedef struct { int top; int data[MAX_STACK_SIZE]; } OperandStack; // 定义运算符栈结构体 typedef struct { int top; char data[MAX_STACK_SIZE]; } OperatorStack; // 定义操作数和运算符栈的初始化函数 void initOperandStack(OperandStack* stack) { stack->top = -1; } void initOperatorStack(OperatorStack* stack) { stack->top = -1; } // 定义操作数和运算符栈的入栈函数 void pushOperand(OperandStack* stack, int value) { if (stack->top == MAX_STACK_SIZE - 1) { printf("Operand stack overflow!\n"); exit(1); } stack->data[++stack->top] = value; } void pushOperator(OperatorStack* stack, char op) { if (stack->top == MAX_STACK_SIZE - 1) { printf("Operator stack overflow!\n"); exit(1); } stack->data[++stack->top] = op; } // 定义操作数和运算符栈的出栈函数 int popOperand(OperandStack* stack) { if (stack->top == -1) { printf("Operand stack underflow!\n"); exit(1); } return stack->data[stack->top--]; } char popOperator(OperatorStack* stack) { if (stack->top == -1) { printf("Operator stack underflow!\n"); exit(1); } return stack->data[stack->top--]; } // 定义操作数和运算符栈的查看栈顶元素函数 int peekOperand(OperandStack* stack) { if (stack->top == -1) { printf("Operand stack underflow!\n"); exit(1); } return stack->data[stack->top]; } char peekOperator(OperatorStack* stack) { if (stack->top == -1) { printf("Operator stack underflow!\n"); exit(1); } return stack->data[stack->top]; } // 定义操作数和运算符栈是否为空的判断函数 int isOperandStackEmpty(OperandStack* stack) { return stack->top == -1; } int isOperatorStackEmpty(OperatorStack* stack) { return stack->top == -1; } // 定义判断一个字符是否为操作符的函数 int isOperator(char ch) { return ch == '+' || ch == '-' || ch == '*' || ch == '/'; } // 定义判断一个字符是否为数字的函数 int isDigit(char ch) { return isdigit(ch); } // 定义计算函数,根据操作符计算对应的结果 int calculate(int op1, int op2, char op) { switch (op) { case '+': return op1 + op2; case '-': return op1 - op2; case '*': return op1 * op2; case '/': return op1 / op2; default: return 0; } } // 定义边分析边计算的函数 int evaluate(char* expr) { OperandStack operandStack; OperatorStack operatorStack; initOperandStack(&operandStack); initOperatorStack(&operatorStack); int i = 0; while (expr[i] != '\0') { if (isDigit(expr[i])) { // 如果当前字符是数字,则将其转换为整数并入操作数栈 int num = 0; while (isDigit(expr[i])) { num = num * 10 + (expr[i] - '0'); i++; } pushOperand(&operandStack, num); } else if (isOperator(expr[i])) { // 如果当前字符是操作符,则与运算符栈栈顶元素比较优先级 while (!isOperatorStackEmpty(&operatorStack) && peekOperator(&operatorStack) != '(' && ((expr[i] == '*' || expr[i] == '/') || (peekOperator(&operatorStack) == '+' || peekOperator(&operatorStack) == '-'))) { int op2 = popOperand(&operandStack); // 从操作数栈弹出两个操作数 int op1 = popOperand(&operandStack); char op = popOperator(&operatorStack); // 从运算符栈弹出一个运算符 int result = calculate(op1, op2, op); // 根据运算符计算结果 pushOperand(&operandStack, result); // 将计算结果入操作数栈 } pushOperator(&operatorStack, expr[i]); // 将当前操作符入运算符栈 i++; } else if (expr[i] == '(') { // 如果当前字符是左括,则将其入运算符栈 pushOperator(&operatorStack, '('); i++; } else if (expr[i] == ')') { // 如果当前字符是右括,则从运算符栈弹出运算符,并从操作数栈弹出两个操作数进行计算,直到遇到左括为止 while (!isOperatorStackEmpty(&operatorStack) && peekOperator(&operatorStack) != '(') { int op2 = popOperand(&operandStack); int op1 = popOperand(&operandStack); char op = popOperator(&operatorStack); int result = calculate(op1, op2, op); pushOperand(&operandStack, result); } if (!isOperatorStackEmpty(&operatorStack) && peekOperator(&operatorStack) == '(') { popOperator(&operatorStack); } else { printf("Mismatched parentheses in expression!\n"); exit(1); } i++; } else { // 如果当前字符不是数字、操作符、左括或右括,则表示表达式有误 printf("Invalid character in expression!\n"); exit(1); } } // 将剩余的运算符和操作数进行计算 while (!isOperatorStackEmpty(&operatorStack)) { int op2 = popOperand(&operandStack); int op1 = popOperand(&operandStack); char op = popOperator(&operatorStack); int result = calculate(op1, op2, op); pushOperand(&operandStack, result); } // 返回最终的计算结果 return popOperand(&operandStack); } int main() { char expr[100]; printf("Please enter an expression: "); scanf("%s", expr); int result = evaluate(expr); printf("Result: %d\n", result); return 0; } ``` 以上代码实现了一个边分析边计算的表达式求值功能,支持加、减、乘、除四种运算符和括。通过运用操作数栈和运算符栈,可以实现边分析边计算的功能,避免了对表达式进行两次遍历的问题。同时,该代码也支持了错误处理,包括表达式出现非法字符和括不匹配等情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值