打印

一个很好的问题:(char)i=(char)j; i值是多少?

[复制链接]
4603|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
highgear|  楼主 | 2009-4-20 21:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
int i, j;
i=0x1234;
j=0x5678;
(char)i = (char) j;

最后i是多少呢?


以下纯引用,不予评论 
*************************************************************************************
冷漠 发表于 2009-4-18 11:13 侃单片机 ←返回版面    

33楼: 请教highgear大师: 

刘前辈:(char)i=TH0;  //有什么理论可以?谢谢大家。
*****************************************************************

前辈问的是有什么“理论”可以,不是要你随意叙述“相当于”。

highgear:
(char)i=TH0; 
相当于:
*(char*)(&i)=TH0;

没错!叙述十分准确。可是这个“相当于”又是根据什么理论?是所有C编译器依据的规则吗?

就算是C51,根据highgear“大师”的说法:无法解释下面:

int i,j;
(char)i=(char)j;

只有把理论搞清楚,才可能使大家应用自如。而理论还包含文字的叙述。否则,岂不是说:

根据:(char)i 相当于*(char*)(&i) ,所以下面也正确?

             (char)i=(char)j;  
上式“相当于”:  *(char*)(&i)=*(char*)(&j);  //????????


回去再请教一下所长,多给咱菜鸟讲清楚一点。
冷漠 发表于 2009-4-18 12:27 侃单片机 ←返回版面    

36楼: highgear总是喜欢创新添加编写国际教材的新内容。 

 除非他自己做编译器,“世界上流行的编译器都做错了,水平太低了,下面2个式子绝对应该是等同的,”谁不同谁错!

      (char)i=(char)j; 
*(char*)(&i)=*(char*)(&j);    


   17: main() 
    18: { 
    19:  
    20: int i,j; 
    21: (char)i=(char)j; 
C:0x000F    850B08   MOV      0x08,0x0B
    22: *(char*)(&i)=*(char*)(&j);    
    23:   
C:0x0012    850A08   MOV      0x08,0x0A
    24: } 
C:0x0015    22       RET      
C:0x0016    00       NOP   

highgear:
瞎扯淡,冷漠这叫什么编译器.....
瞎扯淡,OS实际上就是裸奔.......

讲习所的人总是知道一点,就无限发挥, “天才”一般都是这样性格。
“咱不看书,照样创新。”
这个“相当于”,又是讲习所的创新?


明天告诉highgear,编译器理论是怎么讲的。讲习所今天要赶快讨论呀,否则,连输3个1,000¥,可真是有点说不过去了。

今后还怎么在21IC混? 
冷漠 发表于 2009-4-20 08:52 侃单片机 ←返回版面    

37楼: 出差3天,highgear也没拿出个“理论”解释? 

这可如何做“领军型人才”?
自己不知道可以请教所长啊。

32楼不过是把圈圈、xwj的精彩结论有改头换面复述了一遍,把别人的东西写进自己的**,再进一步请教就没声了。

让所长给你讲讲一个变量有几个特征?编译器是如何表述/表示、表达这几个特征的。

如若连最基本的概念都弄不清,还讨论什么OS?
 
****************************************************************************
 
相关链接:http://www.21icbbs.com/club/bbs/list.asp?Page=2&boardid=11&t=3303925&p=2&tp=%C7%EB%BD%CC%C8%A6%C8%A6%A1%A2xwj%B4%F3%CF%C0

相关帖子

沙发
highgear|  楼主 | 2009-4-20 21:39 | 只看该作者

这里就先说说理论,抛砖引玉

理论上(char)i = (char) j; 不成立。
*(char*) &i = (char) j; 理论上成立。

使用特权

评论回复
板凳
ayb_ice| | 2009-4-20 21:51 | 只看该作者

这样只能保证I的低半字节正确

高字节未知

使用特权

评论回复
地板
HWM| | 2009-4-21 08:39 | 只看该作者

理论上,

“(char)i = (char)j;”和“*(char*)&i = (char)j;”没啥差异,但它们的结果却有可能是匪夷所思,特别是int采用大端表示。

所以千万别去冒这种险!

使用特权

评论回复
5
冷漠| | 2009-4-21 10:49 | 只看该作者

唉!所长老矣,尚能饭否?

讲习所的人:“不要信ANSI的,我们讲习所定的标准才是世界通用的。”
这种人咱拿他也没办法。

若在20年以前,所长说“理论上 (char)i = (char) j; 不成立。”绝对正确。那时的C语言无论是教材上还是标准文本上就是这么定的:——左值的类型cast只能用指针类型,而其他类型只能用于右值cast。
这都是老皇历啦!

再往前10年,连 i=j; 这样的左右值标准赋值表达都不允许,那时的左值只允许用指针类型值!这更是老老皇历啦!那时我可能还没出生呢。

所长真是老古董文物级宝贝了,教highgear这个讲习所门童拿IT历史博物馆的古老技术理论到今天2009年的21IC论坛上来说事!?

世界是发展的,C早就进化啦。

且看下面:

#define uchar unsigned  char  
#define uint unsigned  int
#define ulong unsigned  long

main( )
{
ulong i;
uint j;
(uchar)i=(uchar)j;
 (uint)i=(uchar)j;
i=(uint)j;
}

     7: main() 
     8: { 
     9: ulong i; 
    10: uint j; 
    11:  
    12: (uchar)i=(uchar)j; 
C:0x0003    AF0D     MOV      R7,0x0D
C:0x0005    8F08     MOV      0x08,R7
    13: (uint)i=(uchar)j; 
C:0x0007    750800   MOV      0x08,#0x00
C:0x000A    8F09     MOV      0x09,R7
    14: i=(uint)j; 
    15:   
C:0x000C    E4       CLR      A
C:0x000D    8F0B     MOV      0x0B,R7
C:0x000F    850C0A   MOV      0x0A,0x0C
C:0x0012    F509     MOV      0x09,A
C:0x0014    F508     MOV      0x08,A
    16: } 
C:0x0016    22       RET      

这就是当今新的C标准!
所长可以拿任何“现代”C编译器运行一下,证实一下,看看最新的C编译器理论是什么?!
别忘了前两年**C语言“结构不能拷贝”的事,那次就因C“理论”落伍而失意了一回。
这次要不要我像学长1952一样把书搬出来给你看?

讲习所的人一定要说“咱不看书,照样编写国际标准教材。”

那咱冷漠也没办法,也只能贻笑大方。

使用特权

评论回复
6
highgear|  楼主 | 2009-4-21 11:26 | 只看该作者

wxj1952们果然本性不改

0

使用特权

评论回复
7
HWM| | 2009-4-21 12:35 | 只看该作者

哦,不能这样玩难道就不能换个形式“char(i) = (char)j”玩?

错不在形式上,而在理念上。

程序要写的整洁,清晰,无疑义,才是第一位的。至于其他的雕虫小技都是第二位的玩意儿。

使用特权

评论回复
8
冷漠| | 2009-4-21 15:40 | 只看该作者

讲习所的人就这么点素质?C#能通过!我保证。

“visual c++ 会给出一个编译错误: ”.......
*****************************************************************
highgear就这么点本事?

我给您来一条:

cout<<"YOU ARE PIG ";

我保证C++能通过。20年前的版本也行。 



为啥我Turbo C通不过呢?“讲习所的人真是习性不改。”拿C#说事啦!

看来我这本《C Primer Plus 》美国人又在瞎扯淡了,崇洋媚外嘛。中国的大学教育啊,应该拿咱讲习所长的博客做教本。

唉!地球人啊。还是等我讲习所看大门的highgear领军式人物写一本吧。

使用特权

评论回复
9
zyok| | 2009-4-21 15:50 | 只看该作者

真是一对冤家...

使用特权

评论回复
10
音乐乐乐| | 2009-4-21 15:58 | 只看该作者

没看出问题好在哪儿,要是偶看到有人写这样的程序第一个

使用特权

评论回复
11
冷漠| | 2009-4-21 16:16 | 只看该作者

讲习所怎么出这样的人?

昨天一帮同事谈起陈景润。highgear也过来插一杠子,嘴一撇:“陈景润有什么了不起,现在计算机发展那么快,用双核酷睿,证明一个哥德巴赫猜想,一秒钟都不要!.......”
哇!众皆哗然。

奥运期间,同事间谈起北京的建筑,为何国际招标,——央视、鸟巢,中国人一个也拿不到,钱都进了洋人的腰包。
很简单的道理,中国的建筑水平还在“裸奔”阶段,还未进入到OS那样力求简明而优雅的解决方案的研究阶段。highgear也来插一杠子,眼一斜,“央视大楼有什么好看,大裤衩子似的。”
哇!众皆愕然。

咱办公室有一位,因恋爱问题有点精神不正常,一天到晚看谁都不顺眼,说话不着边际,没有逻辑:“美国的汉堡包有什么好吃,咱天津的煎饼要是打到美国去,那美国人还不疯啦。”
哇!极像highgear。

上面的几件事情不是我冷漠故意造谣吧?highgear要否认我就把你的帖子贴上来,当然当然,这也没啥,如今什么人都有,只是:

谁愿意跟这种人讨论什么问题?!他逻辑思维不正常。

使用特权

评论回复
12
McuPlayer| | 2009-4-21 17:06 | 只看该作者

单片机圈成娱乐圈了

使用特权

评论回复
13
冷漠| | 2009-4-21 17:57 | 只看该作者

12楼:没看出问题好在哪儿,要是偶看到有人写这样的程序第

这让俺想起前2年学长1952,也是讲了这么一种类似简化的另类方法:数组的拷贝可以借助结构来实现。

那时最强烈反对的人也是所长,他说“理论上”结构根本不允许拷贝,只能用memcpy():

“要是偶看到有人用结构拷贝这样的程序,第一个辞退!”

20年前的C是绝对不可以结构拷贝的,但是现在的C标准早就进化了!

最终结果是:冷漠被老板录用。所长带着男人的尊严离开了21IC。

俺为此事耿耿于怀,因当时1952用的论证书籍、资料都是俺到图书馆查的,这好像是我把所长得罪了。

难道这就是highgear总缠着俺过不去的原因?俺把他干爹得罪了,他恨不得咬死俺。

如若真是如此,俺倒情愿不要这份工作,换取所长回归21IC。

昨天看到Hotpower说是他把所长“气”走了,俺倒有些释怀。

希望所长别把对学长1952的怨恨迁怒于俺,俺在办公室最大的口碑就是对老同志老前辈的尊重。

咱今后一定像尊重您一样尊重您的干儿子highgear, 且盼望您的回归。

看来所长的回归,由于highgear前期工作不力,而遥遥无期。
俺今后只要注意谦让/忍让所长的干儿子highgear,助其傲视群雄,纵横论坛,鹤立**群,虎落平川,孤高自许,自命不凡;而不要总是受人驱使,卑微傀儡,垂帘听政,俯仰由人,......这样不久,所长就一定会尽快回归21IC的。

使用特权

评论回复
14
red1986| | 2009-4-21 20:50 | 只看该作者

FF?

看了半天没有看出所以然来,继续……

使用特权

评论回复
15
highgear|  楼主 | 2009-4-21 22:40 | 只看该作者

我就不说wxj1952的马甲冷漠了,他们表演也辛苦了

技术问题不是用胡搅蛮缠歪理能解决的,懂就是懂,不懂就是不懂,不懂装懂只能遭到鄙视。

“C#能通过!我保证“,你能保证什么,可笑啊。C#下一样给出一个编译错误:
The left-hand side of an assignment must be a variable, property or indexer


回到 (char)i = (char) j; 上。
这个问题在于 (char)i, 强制相当于(呵呵, 又是相当于)通知编译器程序员很清楚地知道不同类型之间秘诀,请尽可能的转换为另一种类型,而且程序员知道其中的风险。(char) i 返回一个数值,注意,不是地址,也不是存储空间的数值,而是数值0x34,没有存储空间。
(char) i = (char) j; 相当于
0x34 = (char) j;
所以说,"理论"上不成立。
而 (char*) &i 也返回一个数值,是某个**存储空间***地址的数值,因而可以赋值。


完全赞同 HWM 8楼的意见:
" 错不在形式上,而在理念上。
程序要写的整洁,清晰,无疑义,才是第一位的。", 也是我前面的帖子“
这种(char) i 依赖于编译器及其内部处理的方式并不是好主意,应该使用更明确的语法。“ 的本意。

HWM 8楼的意见同样适用于“数组的拷贝可以借助结构来实现“,错不在形式上,而在理念上。至于辞退......, 过分了点, 而且........, 而且wxj952们肯定会哭天喊地。



使用特权

评论回复
16
John_Lee| | 2009-4-23 03:40 | 只看该作者

尽量不要使用“左值强制类型转换”

在C标准中,已经说明了“强制不能产生左值(A cast does not yield an lvalue)”[ISO/ANSI 9899-1990 6.3.4, cast operators, footnote 44],但有趣的是,这个说明是个footnote,令人感到标准的态度不是很绝对。于是一些激进的编译器支持了这一特性:如Keil C,gcc等。

在gcc的扩展特性中,这一特性被称为“Generalized Lvalues”(广义左值),以下表达式都是允许的:

(a, b) += 5 // 同义于 a, b += 5
(a ? b : c) = 5 // 同义于 (a ? b = 5 : (c = 5))
(int)a += 5  // 同义于 (int)(a = (char *)(int) ((int)a + 5)),a 为 char*类型

可能“广义左值”有用处,但它也可能由于理解上的问题而造成一些潜在的错误(毕竟不是主流,很少使用,显得语法比较怪异),并且,这些“广义左值”表达式其实都可以用标准的表达式语法代替。

目前普遍的共识是:使用“广义左值”得到的好处远远小于它带来的麻烦。

为了C标准的统一性和减少不必要的麻烦,gcc从4.1.1起,去除了“广义左值”的特性(Support for generalized lvalues have been removed in GCC-4.1.1 according to the C standard.)

总的来说,“广义左值”远未达到实用的程度,大家不必为了一个不着边际的东西浪费时间精力。

使用特权

评论回复
17
taoest| | 2009-4-23 17:23 | 只看该作者

文字游戏

搞工程的人,就不要搞文字有些。写程序就好好写。写些有歧义的,或者十分难以理解的语句做什么。
(char)i = (char) j;这种东西,你写出来就算了,还要拿出来丢人。

使用特权

评论回复
18
HUANGQI412| | 2009-4-23 17:33 | 只看该作者

哎,整天玩这些

使用特权

评论回复
19
艾森豪威尔| | 2009-4-24 15:36 | 只看该作者

好久没来这了

列位咋不干点正经事?
这个话题很无聊啊
还有人因此借题发挥,互搞人身攻击,
真是中国科技界的耻辱

扯乎~~

使用特权

评论回复
20
xuyiyi| | 2010-7-22 09:01 | 只看该作者
打酱油路过

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

1222

帖子

61

粉丝