[已解决][问题]这段程序在TC和GCC里的结果不同

C、C++和Java语言
头像
hyxuzhimin
帖子: 249
注册时间: 2008-05-09 14:14
送出感谢: 0
接收感谢: 0

[已解决][问题]这段程序在TC和GCC里的结果不同

#1

帖子 hyxuzhimin » 2008-06-13 1:22

我看得视频教程里的一个程序。老师说结果应该是18。当然是在TC上运行的结果。
并且计算了几种可能的结果30、24(错误的)。
没想到在GCC上运行结果竟然是25.
搞不懂为啥会算成这样的?是不是GCC的运算顺序和TC不同。该怎么算才能算出GCC的这种结果?(就用笔算,简单的计算一下)

代码: 全选

#include "stdio.h"
main()
{
	int i=3,j=0;/*The real conclusion is 18. But why it shows 25?*/
	j=i++*++i+i--*--i;
	printf("j=%d",j);
	}
谢谢~~
上次由 hyxuzhimin 在 2008-06-13 19:03,总共编辑 2 次。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

#2

帖子 eexpress » 2008-06-13 1:34

没tc
gcc可能需要带std98这样的参数。试试吧。
● 鸣学
头像
hyxuzhimin
帖子: 249
注册时间: 2008-05-09 14:14
送出感谢: 0
接收感谢: 0

#3

帖子 hyxuzhimin » 2008-06-13 1:44

该怎么做? 参数加在哪儿?
gcc xx.c -std98 -o xx
这样吗?还是下载什么东东?
偶现在在Win里的gcc里运行。下次到ubuntu里看看运行是啥样?
头像
hyxuzhimin
帖子: 249
注册时间: 2008-05-09 14:14
送出感谢: 0
接收感谢: 0

#4

帖子 hyxuzhimin » 2008-06-13 1:50

Ubuntu里的gcc也是25。
std98 是不是 #include "stdio.h" 改掉? 改成什么呢?
偶刚学C,Linux接触不久。请指教~~
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

#5

帖子 eexpress » 2008-06-13 8:38

gcc -g -std=c99 -o total total.c
一个例子。实例。
● 鸣学
头像
hyxuzhimin
帖子: 249
注册时间: 2008-05-09 14:14
送出感谢: 0
接收感谢: 0

#6

帖子 hyxuzhimin » 2008-06-13 10:59

谢谢,等偶回去用linux的gcc试一试。貌似在win里的gcc无法改运行参数。
附件
Wingcc.png
头像
冲浪板
论坛版主
帖子: 7466
注册时间: 2007-05-06 8:19
送出感谢: 0
接收感谢: 5 次

#7

帖子 冲浪板 » 2008-06-13 11:06

所以真作业的时候,不要抖这种机灵,使得兼容性不够强
dbzhang800
帖子: 3182
注册时间: 2006-03-10 15:10
来自: xi'an China
送出感谢: 0
接收感谢: 2 次
联系:

#8

帖子 dbzhang800 » 2008-06-13 11:07

关于i+=++i+++i+++i之类的问题

这种++--多次出现或者是同一个变量在左右值同时出现还有++--……等情况下,表达式值
不定,与实现有关。谁有兴趣可以自己研究。

C和C++标准对这种情况没有定义,结果完全由编译器自己决定。除非你在研究编译器,否则永远不要写这样的代码
头像
hyxuzhimin
帖子: 249
注册时间: 2008-05-09 14:14
送出感谢: 0
接收感谢: 0

#9

帖子 hyxuzhimin » 2008-06-13 13:12

能研究透编译器,自己都可以创造一个语言了— —|||
头像
BigSnake.NET
帖子: 12522
注册时间: 2006-07-02 11:16
来自: 廣州
送出感谢: 0
接收感谢: 7 次
联系:

#10

帖子 BigSnake.NET » 2008-06-13 13:22

代码: 全选

$ cat a.c
#include "stdio.h"
int main()
{
        int i=3,j=0;/*The real conclusion is 18. But why it shows 25?*/
        j=i++*++i+i--*--i;
        printf("j=%d\n",j);
        return 0;
}
$ splint a.c
Splint 3.1.1 --- 03 Nov 2006

a.c: (in function main)
a.c:5:15: Expression has undefined behavior (left operand uses i, modified by
             right operand): i++ * ++i
  Code has unspecified behavior. Order of evaluation of function parameters or
  subexpressions is not defined, so if a value is used and modified in
  different places not separated by a sequence point constraining evaluation
  order, then the result of the expression is unspecified. (Use -evalorder to
  inhibit warning)
a.c:5:15: Expression has undefined behavior (left operand modifies i, used by
             right operand): i++ * ++i
a.c:5:23: Expression has undefined behavior (left operand uses i, modified by
             right operand): i-- * --i
a.c:5:23: Expression has undefined behavior (left operand modifies i, used by
             right operand): i-- * --i
a.c:5:20: Expression has undefined behavior (left operand uses i, modified by
             right operand): i++ * ++i + i-- * --i
a.c:5:20: Expression has undefined behavior (left operand modifies i, used by
             right operand): i++ * ++i + i-- * --i

Finished checking --- 6 code warnings
$ gcc -Wall a.c
a.c: 在函数‘main’中:
a.c:5: 警告: ‘i’上的运算结果可能是未定义的
a.c:5: 警告: ‘i’上的运算结果可能是未定义的
a.c:5: 警告: ‘i’上的运算结果可能是未定义的
$ ./a.out 
j=25
$ gcc -Wall -O a.c
a.c: 在函数‘main’中:
a.c:5: 警告: ‘i’上的运算结果可能是未定义的
a.c:5: 警告: ‘i’上的运算结果可能是未定义的
a.c:5: 警告: ‘i’上的运算结果可能是未定义的
$ ./a.out 
j=18
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。
头像
cnkilior
论坛版主
帖子: 4979
注册时间: 2007-08-05 17:40
送出感谢: 0
接收感谢: 5 次

#11

帖子 cnkilior » 2008-06-13 13:31

有点奇怪!


研究一下!
头像
hyxuzhimin
帖子: 249
注册时间: 2008-05-09 14:14
送出感谢: 0
接收感谢: 0

回复:BigSnake.NET

#12

帖子 hyxuzhimin » 2008-06-13 17:16

我这里可以运行,没有错误。
头像
BigSnake.NET
帖子: 12522
注册时间: 2006-07-02 11:16
来自: 廣州
送出感谢: 0
接收感谢: 7 次
联系:

Re: 回复:BigSnake.NET

#13

帖子 BigSnake.NET » 2008-06-13 17:28

hyxuzhimin 写了:我这里可以运行,没有错误。
我那个有运行错误吗? ..
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。
头像
Strange
帖子: 1823
注册时间: 2006-05-19 9:54
来自: Shanghai
送出感谢: 2 次
接收感谢: 10 次

#14

帖子 Strange » 2008-06-13 17:30

ls看看清
bigsnake贴的是splint的warning

这种题目不要去研究了,没意义的
结果不同也是正常的,标准没有定义,各个编译器实现不同
ニンニク入れますか?
x60 with gentoo
头像
command
帖子: 306
注册时间: 2007-10-14 0:50
来自: GUCAS
送出感谢: 0
接收感谢: 1 次

#15

帖子 command » 2008-06-13 17:37

代码: 全选

	.file	"test.c"
	.section	.rodata
.LC0:
	.string	"j=%d"
	.text
.globl main
	.type	main, @function
main:
	leal	4(%esp), %ecx
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ecx
	subl	$36, %esp
	movl	$3, -12(%ebp)
	movl	$0, -8(%ebp)
	addl	$1, -12(%ebp)
	movl	-12(%ebp), %eax
	movl	%eax, %edx
	imull	-12(%ebp), %edx
	subl	$1, -12(%ebp)
	movl	-12(%ebp), %eax
	imull	-12(%ebp), %eax
	leal	(%edx,%eax), %eax
	movl	%eax, -8(%ebp)
	addl	$1, -12(%ebp)
	subl	$1, -12(%ebp)
	movl	-8(%ebp), %eax
	movl	%eax, 4(%esp)
	movl	$.LC0, (%esp)
	call	printf
	movl	$0, %eax
	addl	$36, %esp
	popl	%ecx
	popl	%ebp
	leal	-4(%ecx), %esp
	ret
	.size	main, .-main
	.ident	"GCC: (GNU) 4.2.4 (Debian 4.2.4-1)"
	.section	.note.GNU-stack,"",@progbits
这是gcc的汇编上面函数的代码,可以看出先计算4*4,然后计算3*3,然后两者相加作为j的值。
OS: Debian GNU/Linux
Version: lenny
Kernel: 2.6.36
Xorg: 1.4.2
CPU: Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz
HD: 320G SATA
Memory: 2G DDRIII
Graphics:Mobility Radeon HD 3450
回复

回到 “C/C++/Java”