本节主要讲利用栈来实现一个程序中的成对出现的符号的检测,完成一个类似编译器的符号检测的功能,采用的是链式栈。

一、问题的提出以及解决方法

1.假定有下面一段程序:

#include

#include

int main ()

{

int a[5][5];

int(*p)[5];

p = a[0];

printf ("%d", &a[3][3] - &p[3][3]);

}

这段程序中<>[]{}""这些符号都是成对出现的,假如不是成对出现,那么我的程序在编译的时候将会报错。

2.我们即将要编写的程序的主要目的就是来检测程序中所出现的成对的符号是否都匹配。

3.解决方法:

假定我们要检测的程序是上面的一段程序,那么我们要把每一个字符都进行扫描,当程序遇见字母数字或者非成对的符号的时候直接忽略,当程序遇见了成对出现的符号的左符号时我们将左符号压入栈。当扫描的过程中遇见右括号的时候,我们将栈顶元素弹出,进行匹配,如果匹配程序则继续扫描,如果匹配失败,则报错。如果所有的都匹配成功,那么栈为空且所有字符都扫描失败。如果没有匹配成功,那么就是匹配失败或者栈不为空。

4.算法框架

程序的算法框架如下:

二、具体程序的实现

1.程序的具体实现主要采用链式栈的数据结构,同时链式栈是通过复用单向链表来实现的,这些在点击打开链接这篇博文中都有讲解。所以算法实现的主要部分都是在主函数中实现的,也就是我所谓的上层函数。

2.首先采用在主函数中调用其他函数的方式来实现整个程序的运行。

int main()

{

char *a = "#include #include int main () { int a[5][5]; int(*p)[5]; p = a[0]; printf (\"%d\", &a[3][3] - &p[3][3]); } ";

scan(a);

return 0;

}

定义的是一个字符串数组,将字符串数组的首地址传递给scan,这里直接说字符串数组可能不太确切,关于字符和字符串的问题我始终没有搞清楚,拖到了现在。

3.scan函数接部分

(1)scan函数接收的是字符串数组的指针

int scan (char *a)

(2)调用链式栈的函数进行建栈的操作,返回的是栈指针(因为以后只要涉及到栈的操作都要使用到栈指针)

LinkStack * stack = LinkStack_Create();

(3)因为程序的算法中已经说明,我们要不断的扫描所有的字符,直到整个字符串结束,字符串结束的标志是'\0',这里采用while循环来实现

while (a[i] != '\0')

这里通过传递进来的字符串数组的首地址,我们可以通过这个首地址来定义一个字符数组,然后进行操作。

(4)首先判定数组中的元素是否为成对匹配的符号的左符号,如果是左符号,那么将左符号压进栈。

if (left(a[i]) == 1)

{

LinkStack_Push(stack, (void*)(a + i));

}

在将左符号压进栈的操作中,我们压进栈的是数组元素的地址,这里也是链式栈的可复用性的一个体现。

(5)接下来判定数组中的元素是否为成对匹配的符号的右符号,如果是右符号,那么将栈顶元素弹出,并和相应的右符号进行比较。如果栈顶元素为空或者比较失败,那么将进行报错。

if (right(a[i]) == 1)

{

char* bijiao = (char*)LinkStack_Pop(stack);

if ((bijiao == NULL) || !match(*bijiao, a[i]))

{

printf ("%c\n", a[i]);

ret = 0;

break;

}

}

(6)最后,成功的完成了检测的条件是:栈顶为空且已经检测到了最后一个结束符。

if (LinkStack_Top(stack) == NULL && a[i] == '\0')

{

printf ("编译成功\n");

}

(7)程序执行的过程中还有其他几个子函数

1)检测是否为左符号的函数2)检测是否为右符号的函数3)进行比较的函数

三、具体代码

2.主函数的实现部分代码:

#include

#include

#include "1.h"

/*******************************************************************************

*函数名:left

*参数:char a 传进来的数组元素

*返回值:int类型 如果是左侧符号,那么返回1,不是返回0

*功能:判断传进来的字符是否是左侧字符

*******************************************************************************/

int left (char a)

{

int ret = 0;

switch(a)

{

case '

ret = 1;

break;

case '(':

ret = 1;

break;

case '[':

ret = 1;

break;

case '{':

ret = 1;

break;

case '\'':

ret = 1;

break;

case '\"':

ret = 1;

break;

default:

ret = 0;

break;

}

return ret;

}

/*******************************************************************************

*函数名:right

*参数:char a 传进来的数组元素

*返回值:int类型 如果是右侧符号,那么返回1,不是返回0

*功能:判断传进来的字符是否是右侧字符

*******************************************************************************/

int right (char a)

{

int ret = 0;

switch(a)

{

case '>':

case ')':

case ']':

case '}':

case '\'':

case '\"':

ret = 1;

break;

default:

ret = 0;

break;

}

return ret;

}

/*******************************************************************************

*函数名:right

*参数:char a 传进来的数组元素

*返回值:int类型 如果是右侧符号,那么返回1,不是返回0

*功能:判断传进来的字符是否是右侧字符

*******************************************************************************/

int match(char bijiao, char a)

{

int ret = 0;

int i = 0;

switch(bijiao)

{

case '

ret = (a == '>');

break;

case '(':

ret = (a == ')');

break;

case '[':

ret = (a == ']');

break;

case '{':

ret = (a == '}');

break;

case '\'':

ret = (a == '\'');

break;

case '\"':

ret = (a == '\"');

break;

default:

ret = 0;

break;

}

return ret;

}

/*******************************************************************************

*函数名:scan

*参数:char *a 传进来的字符数组元素的地址

*返回值:int类型 如果是右侧符号,那么返回1,不是返回0

*功能:符号匹配算法的主要实现部分

*******************************************************************************/

int scan (char *a)

{

LinkStack * stack = LinkStack_Create();

int i = 0;

int ret = 0;

while (a[i] != '\0')

{

if (left(a[i]) == 1)

{

LinkStack_Push(stack, (void*)(a + i));

}

if (right(a[i]) == 1)

{

char* bijiao = (char*)LinkStack_Pop(stack);

if ((bijiao == NULL) || !match(*bijiao, a[i]))

{

printf ("%c\n", a[i]);

ret = 0;

break;

}

}

i++;

}

if (LinkStack_Top(stack) == NULL && a[i] == '\0')

{

printf ("编译成功\n");

}

else

{

printf ("出现错误\n");

}

LinkStack_Destroy(stack);

return ret;

}

int main()

{

char *a = "#include #include int main () { int a[5][5]; int(*p)[5]; p = a[0]; printf (\"%d\", &a[3][3] - &p[3][3]); } ";

scan(a);

return 0;

}

c语言栈中符号 的作用是什么,C语言数据结构----栈的应用(程序的符号匹配检测)...相关推荐

  1. c语言中单词的作用与形式,C语言基础教程:单词的用法与规则

    在C语言中,单词是由若干个有序的字符组成的,单词的集合称为词汇.C语言的单词有如下几种:标识符.关键字.运算符.分隔符.常量.字符串和注释符. 下面对上述7种单词的词法规则逐一详述,有些单词,例如,关 ...

  2. c语言在中职的作用,C语言程序下的中职教学论文

    一.树立学生良好的学习信心 在日常的中职计算机教育教学中,应当重视学生对教学内容的看法,大多数学生认为C语言学习相对较为困难,在日常的中职计算机学习中,学生某种程度上缺乏应有的信心以及勇气,而尽管有的 ...

  3. c语言在中职的作用,微课在中职《C语言程序设计》课程教学中的应用探讨

    李晶 [摘 要]现代社会经济的高速发展对我国教育事业提出了更高的要求.在中职学校开展C语言程序设计教学活动时,有效应用微课能够进一步提升课堂教学效果,使学生更深入地理解相关知识.要通过建设课程体系.优 ...

  4. C语言switch中break的作用,C语言switch中break语句的作用

    问题: break在for循环.while循环等循环流程控制中起的作用是停止执行break后面的语句,跳出本次循环,并跳出该循环控制体: 在switch条件选择中,没有了循环控制,break又起什么作 ...

  5. C语言switch中break的作用,C语言中switch...case语句中break的重要性

    在C语言中switch...case语句是经常用到的,下面我介绍一下在使用该语句时候需要注意的一个细节问题.话不多说,直接举例子: 例子1: switch(fruit) { case 1:printf ...

  6. 滑动窗口滤波 c语言,关于中值滤波算法,以及C语言实现(转)

    1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制效果好,在抑制随机噪声的同时能有效保护 ...

  7. c语言指针的概念和作用,指针:C语言的重要概念和特色.pdf

    指针:C语言的重要概念和特色.pdf 一 指 针 :C语 言 的 重 要 概 念 和 特 色 令 小怀 (定西工贸中等专业学校 ,甘肃 陇西 748100) 摘 要 :指针是C语 言的精髓部分 .也是 ...

  8. c语言关键字中英翻译机课程设计,C语言关键字中英翻译机.doc

    C语言关键字中英翻译机.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网址水印. 3.该文档 ...

  9. 在spark的软件栈中_问:Spark Streaming是什么软件栈中的流计算?

    问:Spark Streaming是什么软件栈中的流计算? A:Spark,B:Flume,C:Storm,D:Hive 正确答案: 解析: 问:Spark Streaming是什么软件栈中的流计算? ...

最新文章

  1. R语言ggplot2可视化使用vjust和hjust参数对齐图像中的文本注释信息(左对齐、右对齐、居中)实战
  2. ASP.net 资源请求漏洞利用工具PadBuster
  3. 队列化栈栈化队列(力扣)
  4. 批处理之显示隐藏文件
  5. 强化学习2——有模型强化学习MDP(搬砖马尔科夫,贝尔曼等式)
  6. [回归分析][14]--Logistic回归
  7. LWUIT显示中文问题
  8. 在 SAP Spartacus 里如何调用 hybris 里实现的自定义 API
  9. 龙芯.NET正式发布 开源共享与开发者共成长
  10. 技术干货|基于Apache Hudi 的CDC数据入湖「内附干货PPT下载渠道」
  11. python递归求13的n次方_Python题目:递归的简单题目,求阶乘,求n-m的累积和,求斐波那契...
  12. 报错 hint: Updates were rejected because the remote contains work that you do 解决方法
  13. 30天敏捷结果(1):总体认识Getting Result敏捷方法
  14. 6. 缓存 - 《APS.NET本质论》
  15. 大杂烩 -- Iterator 和 Iterable 区别和联系
  16. Python|进程调度算法
  17. 计算机专业学生实习目的,计算机专业学生的实习目的
  18. 算法:计算股票的最大收益(动态规划经典案例)
  19. 有意思的教程:July, 2018
  20. TCP三次握手、四次握手过程,以及原因分析

热门文章

  1. Async Python 竟不比sync Python 快,怎么回事?
  2. 为什么要发明面向对象编程?
  3. 面试稳了!网易资深工程师详解运维面经!
  4. 如何用 Python 快速抓取 Google 搜索?
  5. 库克:苹果从没有垄断;微信搜索升级;微软发布首款支持 Linux 的 Office 应用 | 极客头条...
  6. 特斯拉皮卡,会大卖吗?
  7. 十行代码实现十亿图片检索,我们把它开源了
  8. 500+ 精选 Java 面试题大放送
  9. 将 30 万行代码从 Flow 迁移到 TypeScript 是一种怎样的体验?
  10. IoT 时代,安全危机爆发