精华内容
下载资源
问答
  • 数据结果,C语言表达式求值,堆栈经典应用。输入表达式,如1+2*3,输出运算后的值
  • 本文开创性地分析了序列点在C语言表达式作用:序列点左边操作数要先于其右边操作数求。讨论了逗号操作符,、逻辑与操作符&&、逻辑或操作符||和条件操作符?:问号处需要序列点原因。举例分析了序列点...
  • C语言表达式.docx

    2020-12-23 00:26:19
    一实验目的 帮助学生熟练掌握栈的基本操作 并通过用算符优先法对表达式求值的过程深刻领会用 栈解决实际问题的基本方法 二实验内容 编写程序实现从键盘终端输入语法正确的算术表达式计算出表达式的值 为了避免算符的...
  • C语言表达式

    2011-10-04 19:22:26
    c语言编写一个表达式值的程序 同时,还支持小数运算
  • C语言提供一种特殊的运算符——逗号运算符。...整个逗号表达式的值是表达式2的值。例如,上面的逗号表达式“3+5,6+8”的值为14。又如,逗号表达式 a=3*5,a*4对此表达式的求解,读者可能会有两种不同的理解:一种认...

    C语言提供一种特殊的运算符——逗号运算符。用它将两个表达式连接起来。如:

    3+5,6+8

    称为逗号表达式,又称为“顺序求值运算符”。逗号表达式的一般形式为

    表达式1,表达式2

    逗号表达式的求解过程是:先求解表达式1,再求解表达式2。整个逗号表达式的值是表达式2的值。例如,上面的逗号表达式“3+5,6+8”的值为14。又如,逗号表达式

    a=3*5,a*4

    对此表达式的求解,读者可能会有两种不同的理解:

    一种认为“3*5,a*4”是一个逗号表达式,先求出此逗号表达式的值, 如果a的原值为3,则逗号表达式的值为12,将12赋给a,因此最后a的值为12。另一种认为:“a=3*5”是一个赋值表达式”,“a*4”是另一个表达式,二者用逗号相连,构成一个逗号表达式。

    这两者哪一个对呢?赋值运算符的优先级别高于逗号运算符,因此应先求解a=3*5(也就是把“a=3*5”作为一个表达式)。经计算和赋值后得到a的值为15,然后求解a*4,得60。整个逗号表达式的值为60。

    一个逗号表达式又可以与另一个表达式组成一个新的逗号表达式,如(a=3*5,a*4),a+5 先计算出a的值等于15,再进行a*4的运算得60(但a值未变,仍为15),再进行a+5得20,即整个表达式的值为20。

    d4b0007e7a8304e14aae1fedbd3d4795.png

    逗号表达式的一般形式可以扩展为

        表达式1,表达式2,表达式3……表达式n

    它的值为表达式n的值。

      逗号运算符是所有运算符中级别最低的。因此,下面两个表达式的作用是不同的:

      ① x=(a=3,6*3)

      ② x=a=3,6*a

      第①个是一个赋值表达式,将一个逗号表达式的值赋给x,x的值等于18。第②个是逗号表达式,它包括一个赋值表达式和一个算术表达式,x的值为3。

      其实,逗号表达式无非是把若干个表达式“串联”起来。在许多情况下,使用逗号表达式的目的只是想分别得到各个表达式的值,而并非一定需要得到和使用整个逗号表达式的值,逗号表达式最常用于循环语句(for语句)中.

    a0fe1f4ce1c465df22a427328d515759.png

     请注意并不是任何地方出现的逗号都是作为逗号运算符。例如函数参数也是用逗号来间隔的。如

    printf("%d,%d,%d",a,b,c);

      上一行中的“a,b,c”并不是一个逗号表达式,它是printf函数的3个参数,参数间用逗号间隔。

    如果改写为

    printf("%d,%d,%d",(a,b,c),b,c);

    则“(a,b,c)”是一个逗号表达式,它的值等于c的值。括弧内的逗号不是参数间的分隔符而是逗号运算符。括弧中的内容是一个整体,作为printf函数的一个参数。

    C语言表达能力强,其中一个重要方面就在于它的表达式类型丰富,运算符功能强,因而c使用灵活,适应性强。

    希望以上分享对你有所帮助jq.qq.com
    展开全文
  • C语言表达式表达式的值

    千次阅读 2014-05-14 19:11:55
    今天突然发现如果能很好理解表达式

    今天突然发现如果能很好的理解表达式和表达式的值的概念,可以使编程代码变的更整洁。很多时候我们总是忘记从最基本的概念开始考虑问题。我觉得我们有必要把C/C++标准看下,在里面肯定有很多我们一直困惑的问题的答案。


    C语言是基于结构化程序设计思想的程序设计语言,结构化的程序由函数组成,而函数由语句组成。语句的标志是分号,语句去掉分号后就成了表达式。记忆关键词:常量表达式,关系表达式,运算表达式,逻辑表达式,赋值表达式,逗号表达式……


    下面分别介绍各种表达式的值:

    #include <stdio.h>
    
    #define PrintInt(expr) printf("%s:%d\n",#expr,(expr))
    
    
    int main(int argc,char **argv)
    {
        int a=3,b=5;
        PrintInt(4);  // 常量表达式的值是其本身
        PrintInt((a>b));  // 关系表达式的值是关系比较的结果(true/false,1/0)
        PrintInt((a+b));  // 运算表达式的值是运算结果
        PrintInt((a&b));  // 逻辑表达式的值是逻辑运算结果
        PrintInt((a=4));  // ! 赋值表达式的值是=右边表达式的值
        PrintInt((a++,9));  // ! 逗号表达式的值是最后一个表达式的值
        c=a+b,b+1;    // 到目前为a=4,b=5
        PrintInt(c);  // 需要结合运算符优先级,,运算符优先级最低
        c=(a+b),b+1;
        PrintInt(c);  // 同上
        c=(a+b,b+1);
        PrintInt(c);  // 很容易理解 
        return 0 ;
    }
    
    运行结果:



    简单的巧用表达式的值例子:

    int a = bTest?(0):(i++,1);  // 在bTest为false的情况下使a=1,并且需要使i加1
    



    展开全文
  • /* 表达式输入一个表达式如 1+2*3#程序可计算出结果为 7 支持以下符号 + - * / ( ) ^ . 可以计算整数小数 其中^表示次方2^5 表示 2 5 次方 */ /*头文件*/ #include <stdio.h> #include <malloc.h> #include ...
  • 关于C语言表达式问题解释

    千次阅读 2015-11-01 01:35:27
    很多新手对于C的表达式(如i++ + ++i)这一问题感到十分疑惑,不能很好地理解,今日小轩献丑,准备为新手们解释一下,如有不通之处,请各位同道指出。 首先,贴上裘老解释:...
    很多新手对于C的表达式求值(如i++ + ++i)这一问题感到十分的疑惑,不能很好地理解,今日小轩献丑,准备为新手们解释一下,如有不通之处,请各位同道指出。

    首先,贴上裘老的解释:http://bbs.csdn.net/topics/370153775

    其次,是小轩认为要掌握这个问题需要的一些基础知识:


    1.变量的访问种类与副作用的产生
    在程序设计中经常用到“数”这一概念,在程序设计语言中,“数”被抽象为“量”,在C语言中,“量”分为“变量”和“常量”两种。其中与变量相关的内容较多,主要为访问类型和属性两大类(本文解释表达式求值问题,此问题与变量的属性无过多牵连,所以会在另外一篇文章中向大家介绍变量的属性)。C语言中访问类型有两种:透明引用和真引用;透明引用指不产生副作用的访问,而真引用与之恰好相反,指产生副作用的访问。
    那么,什么是副作用呢?副作用指编译器系统对一个变量实行的数值改变的过程,简单来说,就是改变一个变量的数值。

    第一个基础知识介绍完了,现在举个例子说明一下:
    printf("%d",a+1);这里编译器对变量a的访问属于透明引用,没有修改变量a的值(即没有产生副作用)
    if(++a) a=0;7 这里的对变量a的两个访问都属于真引用,都修改了变量a的值(即都产生了副作用)


    2.序列点的定义,作用及其存在位置
    序列点,也称顺序点,对于编译器系统而言,它是一个瞬间,一个在此序列点之前的全部的副作用都必须要实现的瞬间,也就是说,编译器系统处理到存在序列点的地方时,前面的所有副作用都已产生(即被真引用的变量都已改变它的数值),序列点存在的意义是为了保证编译工作的有序性和有效性。
    有序性:多个不同的序列点的存在使源程序中处于不同序列点之间并被多次真引用的变量的副作用的产生有序化。
    有效性:序列点的存在可以使编译器各模块之间相互通信,序列点就是他们的通信方式,可以保证编译器各模块工作的有效性。

    那么,都什么地方存在序列点呢?C FAQs中明确写道:
    1.完整表达式(表达式语句或不为任何其他表达式的子表达式的表达式)的尾部,即“;”处
    2.“||”、“&&”、“?:”或逗号操作符处
    3.函数调用处(参数求值完毕,函数被实际调用之前)

    关于序列点的基础知识就这么多,现在让我们看几个例子:
    a=1;本例中有一个序列点,位于结束符处,有一个副作用,在唯一的序列点之前有效。
    a=1,b=2,c=3;本例中有三个序列点,分别位于两个逗号操作符处和结束符处,变量a的副作用在第一个序列点之前有效,变量b的副作用在第二个序列点之前,第一个序列点之后有效,变量c的副作用在第二个序列点之后,第三个序列点之前有效。
    if(a==1 && ++b>0)本例中有两个序列点,分别位于"&&"处和语句结束符处(由于if语句的特殊性,没有结束符,但if内的表达式是一个完整表达式,所以也存在序列点),变量a被透明引用,没有产生副作用,即第一个序列点之前没有副作用产生,变量b被真引用,在第一个序列点之后,第二个序列点之前实现其副作用。
    printf("%d",a);本例中有两个序列点,分别位于函数调用处和结束符处(函数中的“,”是分隔符,用来分割参数,不是逗号操作符),两个序列点之前及其相对应的序列点之后均没有副作用
    a=0xffffffff,a++,c=malloc(a),*c=1;                本例中有五个序列点,分别位于三个逗号操作符处、函数调用处和结束符处,变量a的第一个副作用在第一个序列点之前有效,第二个副作用在第一个序列点之后,第二个序列点之前有效,变量c的第一个副作用在第二个序列点之后,第三个序列点(第三个序列点是函数表达式内的那个)之前有效,第三个序列点与第四个序列点之间没有副作用,变量c的第二个副作用在地四个序列点之后,第五个序列点之前有效。


    3.对于前缀运算和后缀运算的解释
    前缀运算,主要包括前缀自增运算(++i)和前缀自减运算(--i),相对应的,后缀运算主要包括后缀自增运算(i++)和后缀自减运算(i--)。
    前缀运算与后缀运算的差别主要在于其副作用实现依据的序列点的不同。
    前缀运算的副作用在本句结束符处的序列点之前有效,而后缀运算的副作用在本句结束符处的序列点之后有效。

    举例:
    a++;本例中有一个副作用和一个序列点,其中副作用由后缀运算产生,所以在本句结束之前,变量a的值都不改变,在本句结束之后,变量a的值改变。
    --a;本例中有一个副作用和一个序列点,其中副作用由前缀运算产生,所以在本句结束之前,变量a的值就已经改变。


    4.C语言一个重要的规则
    ANSI/ISO C标准中有这样的描述:在上一个和下一个序列点之间,一个对象所保存的值至多只能被表达式的求值修改一次,而且只有在确定将要保存的值的时候才能访问前一个值。

    我做具体解释如下:
    在上一个和下一个序列点之间指的就是相邻的两个序列点,一个对象所保存的值至多只能被表达式求值修改一次指的是一个变量的值只能修改一次,只有在确定将要保存的值的时候才能访问前一个值指的是将要用来计算表达式计算的每个变量的值都应该是确定的;整合化简后,可以改述为:在两个相邻的序列点之间,对于同一个变量只能进行一次真引用。

    现举例如下:
    a=1,b=2,a=b;本例中有三个序列点和副作用,且相邻序列点之间对同一变量进行真引用的次数没有超过一次,所以本表达式合法。
    a=a+1;本例中有一个序列点和一个副作用,变量a在寻列点之间出现两次,但对变量a的真引用的次数只有一次,没有违反我们刚才的规则,所以本表达式同样合法。
    a[b=2]=++b;本例中有一个序列点和两个副作用,变量b的第一个副作用对变量b就行了一次真引用,就变量b的值修改为2,变量b的第二个副作用源自于前缀自增表达式,两个副作用都在同两个序列点之间,所以编译器不知道是先进行第一个副作用还是先进行第二个副作用了,所以就有了四种结果(a[2]=2、a[2]=3、a[3]=2、a[3]=3)了,这是我们不希望看到的,所以本表达式不合法。
    a[b=2]=b--;本例中有两个序列点和两个副作用,但是变量b的第二个副租用源自于后缀运算,这个副作用在本句结束符处的序列点之后有效,所以本句还可以解释为a[2]=2,b=1;这样的表达式符合我们的规则,所以本表达式合法。

    注:我这里指的表达式不合法不是说表达式不能通过编译器的编译,指的是可以通过编译但结果未知(就像a[b=2]=++b这个例子一样有四种解释方案,结果自然未知),我们习惯上统称此类问题为UB问题(未定义问题)。未定义问题主要是因为C语言标准没有明确规定遇到这种问题时编译器应如何处理,所以,对于未定义问题不同编译器给出的结果可能不同,可能相同,例如char c="asdf";在VC6.0和LCC-WIN32的结果就是不同的。


    下面回到主题,我们终于可以看看i++ + ++i了!在本例中,只有一个序列点(未写出全句),但在这个序列点之前访问了两次变量i,其中有一次访问为真引用,这样就使表达式产生了二义性(后面的i自加后,前面的i是自加前的i还是自加后的i?),所以这个表达式就成为了未定义问题。




    ok,写到这里,这篇文章就差不多该结稿了,我希望新手们将本文多读几遍,就算不能全部理解,也要能记下多少就记多少,以后多练练,就回了;至于老手们,看后如果找到了什么不恰当的地方,还请指出,我一定会努力修改,使本文日臻完美的。
    展开全文
  • 先将中缀表达式转换为后缀表达式,再求 中缀转后缀可以借鉴该博文 表达式可以借鉴该博文 我代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #define maxsize 100 #...

    说明

    本程序支持括号以及小数计算


    基本思想

    先将中缀表达式转换为后缀表达式,再求值
    中缀转后缀可以借鉴该博文
    表达式求值可以借鉴该博文


    我的代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define maxsize 100
    #define N 7
    typedef struct{//运算符栈
    	char data[maxsize];
    	int top;
    }seqOperate;
    
    typedef struct{//运算数栈
    	double data[maxsize];
    	int top;
    }seqData;
    
    char operators[maxsize] = { '+', '-', '*', '/','=','(',')'};
    
    int priotiry(char ch){//运算符优先级
    	switch(ch){
    	case '+':
    		return 1;
    	case '-':
    		return 1;
    	case '*':
    		return 2;
    	case '/':
    		return 2;
    	case '(':
    		return 0;
    	case ')':
    		return 0;
    	default:return -1;
    	}
    }
    //判断运算符栈是否为空
    int isEmptyOp(seqOperate *s1){
    	if(s1->top == -1)
    		return 1;
    	else
    		return 0;
    }
    
    //从运算符栈中弹出一个运算符
    char popo(seqOperate *s1){
    	if(!isEmptyOp(s1)){
    		char ch=s1->data[s1->top];
    		s1->top--;
    		return ch;
    	}
    	else
    		return 'F';
    }
    //运算符入栈
    void pusho(seqOperate *s1,char ch){
    	s1->top++;
    	s1->data[s1->top]=ch;
    }
    //获取栈顶元素
    char getTopo(seqOperate *s1){
    	return s1->data[s1->top];
    }
    //初始化运算符栈
    void initSeqOperate(seqOperate *s1){
    	//s1=(seqOperate*)malloc(sizeof(seqOperate));
    	s1->top=-1;
    }
    //初始化运算数栈
    void initSeqData(seqData *s2){
    	s2->top=-1;
    }
    //运算数入栈
    void pushd(seqData *s2,double d){
    	s2->top++;
    	s2->data[s2->top]=d;
    }
    double popd(seqData *s2){
    	double d;
    	d=s2->data[s2->top];
    	s2->top--;
    	return d;
    }
    //判断所给字符是否为运算符
    int isOperate(char ch){
    	int i;
    	for (i = 0; i < N; i++)
    	{
    		if (operators[i] == ch)
    		{
    			return 1;
    		}
    	}
    	return 0;
    }
    char * infixToAffix(char *str){
    	seqOperate *s1;
    	int i=0,j=0;
    	char ch;
    	static char result[maxsize];
    	s1=(seqOperate*)malloc(sizeof(seqOperate));//在codeblocks和vc++6.0上都需要这一句,dev-c++上不需要,请视情况而定
    //	char result[maxsize];
    	initSeqOperate(s1);
    	while(str[i]!='\0'){
    		if(str[i]=='.'||(str[i]<='9'&&str[i]>='0')){
    			result[j++]=str[i];
    		}
    		else{
    			result[j++]='#';//将数字字符串和操作符分开--转换时定界的功能
    			if(str[i]=='+'||str[i]=='-'){
    				if(isEmptyOp(s1)){
    					pusho(s1,str[i]);
    				}
    				else{
    					while(getTopo(s1)!='('&&!isEmptyOp(s1)){
    						ch=popo(s1);
    						result[j++]=ch;
    					}
    					pusho(s1,str[i]);
    				}
    			}
    			else if(str[i]==')'){
    				ch=popo(s1);
    				while(ch!='('){
    					result[j++]=ch;
    					ch=popo(s1);
    				}
    			}
    			else if(str[i]=='*'||str[i]=='/'||str[i]=='('){
    				pusho(s1,str[i]);
    			}
    		}
    		i++;
    	}
    	while(!isEmptyOp(s1)){
    		ch=popo(s1);
    		result[j++]=ch;
    	}
    //	printf("-------\n");
    //	printf("%s\n",result);
    	return result;
    }
    double getAffixValue(char *res){
    	seqData *s2;
    	double sum,t,a,b,result;
    	int i=0;
    	s2=(seqData *)malloc(sizeof(seqData));
    	initSeqData(s2);
    	while(res[i]!='\0'){
    		if(res[i]<='9'&&res[i]>='0'){
    			sum=0;
    			t=10;
    			sum=res[i]-'0';
    			i++;
    			while((res[i]<='9'&&res[i]>='0')||res[i]=='.'){//字符串转double
    				if(res[i]!='.'){
    					if( t == 10)
    						sum = sum * t + res[i] - 48;
    					else
    					{
    						sum += ( res[i] - 48 ) * t;
    						t = t*0.1;
    					}
    				}
    				else{
    					t=0.1;
    				}
    				i++;
    			}
    		//	printf("%lf %d\n",sum,i);
    			pushd(s2,sum);
    
    		}
    		if(res[i]=='+'||res[i]=='-'||res[i]=='*'||res[i]=='/'){
    			a=popd(s2);
    			b=popd(s2);
    			if(res[i]=='+')
    				pushd(s2,b+a);
    			if(res[i]=='-')
    				pushd(s2,b-a);
    			if(res[i]=='*')
    				pushd(s2,b*a);
    			if(res[i]=='/')
    				pushd(s2,b/a);
    		}
    		i++;
    
    	}
    	result=popd(s2);
    	//printf("最终结果为:%lf",result);
    	return result;
    }
    int main(){
    	int n,m;
    	char * res;
    	char str[maxsize];
    	double result;
    	scanf("%d",&n);
    	while(n--){
    		scanf("%s",str);
    		res = infixToAffix(str);
    		//printf("result%s\n",res);
    		result=getAffixValue(res);
    		m=(int)result;
    		if(result-m==0)
    			printf("%d\n",m);
    		else
    			printf("%.2lf\n",result);
    	}
    }
    

    ps:欢迎评论指正

    展开全文
  • C语言表达式顺序

    2013-12-22 22:24:57
    一个C语言程序jiajia.c如下:  [code=c]#include int main() {  long i;  i=0;  printf("%ld\n",(++i)+(++i)+(++i));  }[/code] 该程序在X86、linux机器上编译后运行结果为7,而在SPARC/SUNOS机器上编译后...
  • 表达式是由运算符(包括括号)、操作数(常量、变量、函数等,是一个操作符操作于其上的数)按照一定的规则组成的式子;...在表达式的后边加个分号就是表达式语句。除了控制语句外,几乎都是表达式语句。如...
  • #include <stdio.h> int main() { int y, x = 10; y = (x++)+(--x)+(x++); printf("%d\n", y); } 这个程序输出结果为什么是27?
  • c语言表达式顺序

    千次阅读 2007-09-23 21:29:00
    c语言没有明确规定表达式的求值顺序!除了逻辑表达式的短路求值! 例如下面的程序:int a = 10;int func(){ a = 5; return 5;}a + func()的值就不定。在gcc下是先计算func,所以值为10java明确规定了求值顺序是从...
  • 地址的数据类型和所用的运算符决定了表达式的类型。在SCL中可能有下列表达式:一、表达式概述:1、算术表达式算术表达式是由算术运算符构成的。其允许处理数字类数据类型。下表显示所有可能的运算符和指出依据地址的...
  • 表达式 (4(3) 的值为 _ 0 2.表达式 :x=(2) 的值为 1 1 3.如果有变量定义 :int i=1,j=8,a; 则表达式 :a=i+(j%4!=0) 的值为 _ 1 1 4.表达式 :x=(7+6%4/2 的值为 1 0 5.如果有变量定义 :int x, 则表达式 :x=-3*4%-6/50 ...
  • C语言提供一种特殊的运算符——逗号运算符。...整个逗号表达式的值是表达式2的值。例如,上面的逗号表达式“3+5,6+8”的值为14。又如,逗号表达式 a=3*5,a*4对此表达式的求解,读者可能会有两种不同...
  • C基本程序步骤由语句 (statements) 组成,而大多数语句都由表达式 expression) 构成。因此,我们先学习表达式。 1 表达式表达式(expression)由运算符和运算对象组成。最简单的表达式是一个单独运算对象,以此为...
  • c语言表达式

    2012-11-14 19:48:28
    本程序是关于C语言表达式的表达和求,属于数据结构中的一些东西。
  • 接下来就为大家讲解一下这份由iMindMap制作的C语言表达式思维导图。C语言表达式一共有五块内容。一、算术运算符顾名思义,算术运算符就是我们在进行算式计算时使用到运算符。图片1:算术运算符在C语言中,根据参与...
  • c语言表达式题库.doc

    2020-03-12 08:31:46
    表达式(4(3) 的值为_ 0 2.表达式:x=(2) 的值为1 1 3.如果有变量定义:int i=1,j=8,a;则表达式:a=i+(j%4!=0) 的值为_1 1 4.表达式:x=(7+6%4/2 的值为1 0 5.如果有变量定义:int x,则表达式:x=-3*4%-6/50 的值为1 0 6....
  • c语言实现表达式

    千次阅读 2020-03-14 12:10:48
    要求从键盘输入任意包含加减乘除算术四则运算表达式,都能求。操作数类型可以设定为double。 以下是代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 50...
  • 一、目的理解中缀表达式值的过程理解中缀转后缀表达式值的过程掌握堆栈应用二、问题描述缀表达式,其中包含括号,加减乘除,乘方等运算,利用中缀表达式,对表达式分析并求中缀表达式转换为后缀形式,...
  • C语言提供一种特殊的运算符——逗号运算符。用它将两个表达式连接...整个逗号表达式的值是表达式2的值。例如,上面的逗号表达式“3+5,6+8”的值为14。又如,逗号表达式 a=3*5,a*4对此表达式的求解,读者可能会...
  • 我们今天继续看一下,如何使用栈完成标准四则混合运算表达式。不同于后缀表达式,遇到一个运算符就可以直接从栈里取两个数进行运算。在标准四则混合运算表达式中(或者我们称之为中缀表达式),遇到一个操作符...
  • c语言表达式计算顺序

    2020-03-28 11:18:57
    C 语言中,任何表达式的子表达式求顺序是未指定的,编译器可能以任意顺序对这个表达式求,而且同一表达式再度求时可能会采用另一种顺序。 C 中有运算符从左到右 / 从右到左结合性,但没有从左到右 / 从右到左...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,827
精华内容 1,930
关键字:

c语言表达式的值

c语言 订阅