if-statement - else if (!*p) 在这段代码中是什么意思
问题描述
我试图了解这个程序是如何工作的,我发现了一些我不明白的东西在这部分
if (!isempty(stack) || *p) {
puts("Invalid parenthesis expression");
while (! isempty(stack))
pop(&stack);
}
else if (!*p)
puts("Valid parenthesis expression");
完整的编码在这里
#include<stdio.h>
#include<malloc.h>
#include <string.h>
typedef struct data{
char parent;
struct data *next;
} DATA;
void push(DATA **stack, char parentheses);
int isempty(DATA *stack);
void pop(DATA **stack);
int top(DATA *stack);
int main(int argc, char const *argv[]){
DATA *stack = NULL;
char parentheses[100];
char * p;
while (fputs("Enter parentheses: ", stdout),
(scanf(" %99[^\n]", parentheses) == 1) && strcmp(parentheses, "-1")) {
for (p = parentheses; *p; ++p) {
if ((*p == '{') || (*p == '[') || (*p == '('))
push(&stack, *p);
else {
char o;
if (*p == '}')
o = '{';
else if (*p == ')')
o = '(';
else if (*p == ']')
o = '[';
else
o = 0;
if (isempty(stack) || (top(stack) != o))
break;
pop(&stack);
}
}
if (!isempty(stack) || *p) {
puts("Invalid parenthesis expression");
while (! isempty(stack))
pop(&stack);
}
else if (!*p)
puts("Valid parenthesis expression");
}
return 0;
}
void push(DATA **stack, char parentheses) {
DATA *node = malloc(sizeof(DATA));
node->parent = parentheses;
node->next = *stack;
*stack = node;
}
int isempty(DATA *stack) {
return (stack == NULL);
}
void pop(DATA **stack) {
DATA *temp = *stack;
*stack = (*stack)->next;
free(temp);
}
int top(DATA *stack) {
return stack->parent;
}
解决方案
!*p
当应用于指针变量时,表达式p
将取消引用该指针,并在逻辑上否定它。在这种情况下,它似乎p
是char *
遍历字符串,这意味着它将获取该位置的字符并为您提供:
- 如果它不为零,则为零;或者
- 如果为零,则为一。
换句话说,它是(相当难看的)C 简写:
if (*p == '\0')
表示指针已到达 C 字符串的末尾。
从更高级别的角度来看,该程序似乎正在评估一个中缀表达式,例如:
{[(3 + 7) / 2] + 6}
并使用堆栈来存储不同的括号。这样做是为了检查括号是否平衡。
找到每个左括号后,将其推入堆栈。然后,每当您找到右括号时,请检查两者:
- 堆栈不为空;和
- 从堆栈中弹出的值是您的关闭值的打开等效值。
其他任何事情都是错误。
最后,在表达式的最后,堆栈应该是空的。否则,右括号比左括号少。
推荐阅读
- ajax - 美德玛特一页结账付款方式问题
- python - 选择具有 id pyspark 列表的多行
- c++ - 修复视频FPS opencv?
- mysql - 尽管有索引,但 MySQL 的选择查询性能很差
- go - “go build -buildmode=c-shared”编译的dll,如何隐藏导出的goruntime函数?
- swift - 在 alamofire manger 类 swift 中添加公钥固定
- c# - 如何在 CSV 文件中随机生成一个单词
- vuejs2 - 当滚动条在VueJs中到达底部时如何执行功能
- node.js - 使用从另一个模块(node.js)导入的函数
- apache-spark - pyspark 加入两个数据框并按最近日期保留行