//  main.c

//  计算器

//  Created by qianfeng on 14-7-15.

//  Copyright (c) 2014年 ___FGY___. All rights reserved.

//iPhone自带计算器不够好,由于你技术出众,你被安排去开发一款iOS新式计算器。

/*项目经理认为计算器第一版要支持表达式求值,所以要求如下:

输入任意表达式 求出他的值(支持负数,不支持小数)

这里支持6种表达式

() * / + -

()优先级最高, * /优先级其次 + -优先级最低

比如输入任意表达式:

(100+2)*2

输出

204

在比如:

输入任意表达式:

(-100-2)*(10-2)/(100-22)

输出

-10

不考虑除法小数的情况.

*/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int weishu(int c);

void yiwei( int *a, int b, int c);

void chyiwei(char *a,int b,int c){//字符串用过删除操作字符+ - * /

int i = 0;

for (i = b; i < c ; i ++)

{

a[i]=a[i+1];

}

a[c] ='\0';

}

void yiwei ( int *a,int b,int c){//数字用过之后往前移动一位

int i ;

for (i = b; i < c;  i ++) {

a[i]=a[i+1];

}

a[c]=0;

}

int weishu(int c){//atoi之后需要统计这个数字的位数

int i ;

int t = 0;

if ( c<0)

{

t = 1;

c = -c;

}

for (  i = 0; c >0;  i++) {

c /= 10;

}

return  i+t;

}

int main(int argc, const char * argv[])

{

char buff[256] = {};

int arr[100]={};

char ch[100] , *p , *p1 ,*p3 ,*p4 = NULL , *p5 =NULL;

int k = 0,k1 = 0, k2 = 1;

fgets(buff, 256, stdin);

unsigned long bu_len = strlen(buff)-1;

buff[bu_len] = '\0';

int i , j ;

for ( i = 0 ;  i < bu_len;  i ++) {//这个循环是把字符串转化成数字与操作字符 + - * 、

if ( buff[i] == '(')

{

ch[k1] = '(';

k1 ++;

p=&buff[i+1];

arr[k]=atoi(p);//判断是否是数字并且存储

i +=( weishu(arr[k]) );//向后移动数据的位数

k++;

} else if (buff[i] == ')')

{

ch[k1] =')';

k1 ++;

}

else if ( buff[i] == 43)

{

ch[k1] = 43;

k1 ++;

}

else if (buff[i] == 45)

{

if ( i != 0)

{

ch[k1]=45;

k1 ++;

}else{//判断是否是数字若是第一次进入则按负数计算

p = &buff[i];

arr[k]=atoi(p);

i +=(weishu(arr[k])-1);

k++;

}

}

else if (buff[i]== '*')

{

ch[k1]='*';

k1 ++;

}

else if ( buff[i]=='/')

{

ch[k1] = '/';

k1 ++;

}

else

{

p = &buff[i];

arr[k]=atoi(p);

i +=(weishu(arr[k])-1);

k++;

}

}//接受在数组里边

int count = 0;

for (  i = 0;  k1 >0;)

{

p4 = strstr( ch,  "(");

p3 = strstr(ch,")");

if ( p4  || p5 == p4  )//此循环是 判断括号内是否是计算完成,当没完成的时候继续完成。

{

if ( p4 == p5)

{

p = strstr(p4, "*");

p1 = strstr(p4, "/");//判断是否有乘法和除法

if (p < p3 || p1 < p3 )

{

if (p || p1)//查找乘法和除法

{

if (p1 && p)

{

if ((p1 - p )>0 && p <p3)//必须是本括号内

{

i = (int)(p -ch);

}

else if ((p1-p)<0 && p1 <p3)

{

i = (int)(p1 - ch);

}

}

else if (p1)//不能为null

{

i = (int)(p1 - ch );

}

else if (p){

i = (int)(p - ch);//不能为null

}

}

else

{

i = (int)(p4-ch+1);//没有* /从括号出开始从左向右计算

}

}

else///没有乘除除的情况

{

i = (int)(p4-ch+1);//从括号后边开始

}

}

else if (p4)//判断是否是前半个括号

{

p5 = p4;

i  = (int)(p4 - ch);

//k2 =3;

}

}

else//没有括号的情况下查找  乘法和除法

{

p = strstr(ch, "*");

p1 = strstr(ch, "/");//判断是否有乘法和除法

if (p || p1)

{

if (p1 && p)

{

if ((p1 - p )>0)

{

i = (int)(p -ch);

}

else if ((p1-p)<0)

{

i = (int)(p1 - ch);

}

}

else if (p1)

{

i = (int)(p1 - ch);

}

else if (p){

i = (int)(p - ch);

}

}

else

{

i = 0;

}

k2 = 2;

}

{

if (ch[i] == '(' && count %2 == 0 )

{

count %= 2;

count ++;

i++;

k2 = 0;

}

else if ( ch[i] == '+')

{

arr[i-count] += arr[i - count+1];

yiwei(arr, i+1-count, k --);

chyiwei(ch, i, k1--);

if (count %2 == 1 && (ch[i-1] =='(' &&ch[i] == ')') )

{

k2 = 1;

chyiwei(ch, i - 1, k1--);

chyiwei(ch, i-1, k1--);

count = 0;

}

}

else if ( ch[i] == '-')

{

arr[i -count] -= arr[i-count+1];

yiwei(arr, i+1-count, k --);

chyiwei(ch, i, k1--);

if (count %2 == 1  && (ch[i-1] =='(' &&ch[i] == ')') )

{

k2 = 1;

chyiwei(ch, i - 1, k1--);

chyiwei(ch, i - 1, k1--);

count = 0;

}

}

else if ( ch[i] == '*')

{

arr[i -count] *= arr[i - count +1];

yiwei(arr, i+1-count, k --);

chyiwei(ch, i, k1--);

if (count %2 == 1 && (ch[i-1] =='(' &&ch[i] == ')') )

{

k2 = 1;

chyiwei(ch, i - 1, k1--);

chyiwei(ch, i - 1, k1--);

count = 0;

}

}

else if (ch[i] == '/')

{

arr[i -count] /= arr[i - count+1];

yiwei(arr, i+1-count, k --);//计算后将数据覆盖

chyiwei(ch, i, k1--);//计算后将操作符覆盖

if (count %2 == 1 && (ch[i-1] =='(' &&ch[i] == ')') )

{

k2 = 1;//若是括号,则删除括号,操作符前移

chyiwei(ch, i - 1, k1--);

chyiwei(ch, i - 1, k1--);

count = 0;

}

}

else if ( ch[i] == ')')

{

count ++ ;//

i++;

//chyiwei(ch, i, k1--);

}

}

}

for (  j = 0;  j < k ;  j ++)

{

printf("%d\t",arr[j]);//shuchu 输出 存的 数据

}

for (  j = 0;  j < k1;  j ++) {

printf("%c\t",ch[j]);   //c操作字符的 输出 要是成功的话字符为空

}

return 0;

}

c 语言简单计算器源码的更多相关文章

  1. Android 简单计算器源码....

    PS:今天算是闲着没事做了一个小型的计算器...顺便熟悉一下Android的布局,组件,以及时间监听的方法...就当是做了一个小小的练习吧...     顺便去对比了一下别人写的代码...有的使用到了 ...

  2. HashMap就是这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前面已经讲了Collection的总览和剖析List集合以及散列表.Map集合.红黑树的基础了: Collection总览 List集合就这么简单[源码剖析] Ma ...

  3. LinkedHashMap就这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前面已经讲了Collection的总览和剖析List集合以及散列表.Map集合.红黑树还有HashMap基础了: Collection总览 List集合就这么简单[ ...

  4. TreeMap就这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前面章节回顾: Collection总览 List集合就这么简单[源码剖析] Map集合.散列表.红黑树介绍 HashMap就是这么简单[源码剖析] LinkedH ...

  5. 简单读读源码 - dubbo多提供者(provider)配置方法

    简单读读源码 - dubbo多提供者(provider)配置方法 消费者端dubbo的yml配置 dubbo: consumer: timeout: 300000 protocol: name: du ...

  6. 使用太过简单jqprint源码也极其简洁易懂

    就像开发一样, 这篇文档如果没有人关心和维护, 里面的内容就会变得老旧, 过时而不再具有参考价值. 所以, 我希望所有看到并喜欢这篇文档的人都一起来维护它. 放心大胆的提交 Pull Request ...

  7. Markdown 标记语言指北 - 源码

    这是上一篇博客的源代码. 这是班刊约稿的一篇文章. 全文约6000字, 预计需要 60 分钟读完. # Markdown 标记语言指北 #### TOC 1. [什么是 Markdown?](#%E4 ...

  8. 详解Go语言调度循环源码实现

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/448 本文使用的go的源码15.7 概述 提到"调度&q ...

  9. List集合就这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前一篇已经讲了Collection的总览:Collection总览,介绍了一些基础知识. 现在这篇主要讲List集合的三个子类: ArrayList 底层数据结构是 ...

随机推荐

  1. 【菜鸟学习Linux】-第一章-Linux环境搭建-安装VMware虚拟机

    本人菜鸟一个,刚毕业才上班2个月,现在用到Linux部署项目,这才开始学习Linux,以下是我在安装Linxu系统是遇到的一些问题,希望能给广大菜鸟们在学习的道路上提供帮助和指导,废话不多说!开工! ...

  2. 2013年 ACM 有为杯 Problem I (DAG)

    有为杯  Problem I DAG  有向无环图 A direct acylic graph(DAG),is a directed graph with no directed cycles . T ...

  3. MySQL学习笔记(3)

    约束 作用:保证数据的完整性,唯一性 根据字段:分为表级约束(针对2个或者2个以上字段使用),列级约束(针对1个字段使用) 约束类型:NOT NULL 非空约束 PRIMARY KEY  主键约束 U ...

  4. Java程序在向mysql中插入数据的时候出现乱码

    今天在往数据库中插入数据的时候中文字符在数据库中就出现了乱码?网上有各种说法,但是适合我的,最终解决我的问题的只有下面一种! 在创建数据库的时候,注意设置编码方式. CREATE DATABASE ` ...

  5. inline函数和一般的函数有什么不同

    1.比如: int g(int x) { return x + x; } int f() { return g(); } 这样f会调用g,然后g返回x + x给f,然后f继续把那个值返回给调用者. 如 ...

  6. Clamp函数

    Clamp函数可以将随机变化的数值限制在一个给定的区间[min, max]内: template<class T> T Clamp(T x, T min, T max) { if (x & ...

  7. 网络技术教程笔记(20)ISDN

    广域网与接入网技术 广域网与接入网技术 常见接入技术--ISDN 综合业务数字网(Integrated Services Digital Network,ISDN)由电话综合数字网IDN演化而成,能够 ...

  8. springmvc结合freemarker,非自定义标签

    参考:http://viralpatel.net/blogs/spring-mvc-freemarker-ftl-example/ 上图: 目录层级: 启动后的访问地址:http://localhos ...

  9. input 输入框获得/失去焦点时隐藏/显示文字(jquery版)

    input输入框在获得或失去焦点时隐藏或显示文字,这样的焦点效果想必很多朋友在填写form表格的时候都曾见识过吧,本文使用jquery实现以下,感兴趣的朋友可以参考下哈 大家可以看效果图的搜索输入框, ...

  10. C功底挑战Java菜鸟入门概念干货(一)

    一.认识Java 1.Java 程序比较特殊,它必须先经过编译,然后再利用解释的方式来运行.  2.Byte-codes 最大的好处是——可越平台运行,可让“一次编写,处处运行”成为可能.  3.使用 ...