找回密码
 注册
搜索
查看: 1897|回复: 18

[讨论] C语言高手进来

[复制链接]
发表于 2011-7-20 15:34:52 | 显示全部楼层 |阅读模式
有个问题,需要C高手确认一下

typedef  enum
{
    list_o,
    list_1,
    list_2,
    list_max
}te_list;



1:  g_bDrvList =  (te_list)para;
2:    g_bDrvList =  para%list_max;

以上两者是不是等价?
发表于 2011-7-22 16:35:22 | 显示全部楼层
哈哈,其实我聊的那些都是浮云,也不一定完完全全的都正确,顶多算是
         我个人的一点理解,很多高手平时忙,木功夫上来看,他们真要看
         到,估计要笑话我了,他们眼里的小儿科了,csdn上不少高手关注
         的,伊莉莎有空也可以去逛逛,你们不能Q,回头有空周末喝两杯
         啊,哈哈
点评回复

使用道具 举报

发表于 2011-7-22 16:26:38 | 显示全部楼层
向具有钻研精神的兄弟姐妹们致敬,我们需要这样的精神。
点评回复

使用道具 举报

 楼主| 发表于 2011-7-22 14:50:22 | 显示全部楼层
上传上去的图怎么变模糊了

点评回复

使用道具 举报

 楼主| 发表于 2011-7-22 14:43:57 | 显示全部楼层
LZ也来帖自己的实验结果

不解释

HOBBY兄,知识面好广!

佩服

<img src="attachments/dvbbs/2011-7/201172214462598359.jpg" border="0" onclick="zoom(this)" onload="if(this.width>document.body.clientWidth*0.5) {this.resized=true;this.width=document.body.clientWidth*0.5;this.style.cursor='pointer';} else {this.onclick=null}" alt="" />

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
点评回复

使用道具 举报

发表于 2011-7-22 13:54:04 | 显示全部楼层
呵呵,兄弟,你确信enum的值域类型一定是整形吗?

  特意针对你说的,我做了一个试验,不妨贴上来给你看看,我在展讯
  平台上随意找了个地方测试的,ads编译,源码、log我都贴给你看看:
  源码:
  typedef  enum
    {
            list_o,
            list_1,
            list_2,
            list_max
    }te_list;

    te_list  g_bDrvList1,g_bDrvList2;

    int para = 0xffffffffffffffff;

    SCI_TRACE_LOW("g_bDrvList1 = %d, g_bDrvList2 = %d, para = %d",
                  g_bDrvList1,g_bDrvList2,para);
       
    g_bDrvList1 =  1.1;
    g_bDrvList2 =  para%list_max;

    SCI_TRACE_LOW("g_bDrvList1 = %d, g_bDrvList2 = %d, para = %d",
                  g_bDrvList1,g_bDrvList2,para);

   (char)para = 'a';
   g_bDrvList1 =  (te_list)para;
   g_bDrvList2 =  para%list_max;

   SCI_TRACE_LOW("g_bDrvList1 = %d, g_bDrvList2 = %d, para = %d",
                 g_bDrvList1,g_bDrvList2,para);

   编译运行结果没有报错,请思考为什么?同时,我也把log打印出来的
   信息给你看看:
   68-28:g_bDrvList1 = 19, g_bDrvList2 = 127, para = -1
   68-29:g_bDrvList1 = 1, g_bDrvList2 = -1, para = -1
   68-30:g_bDrvList1 = 1644167167, g_bDrvList2 = 1, para = 1644167167
   至于为什么,我不再分析,看过思考下就明白的。

   


   然后我又做了一次改变针对上面的两点,看它的值域是不是所说的接近
   整形的数值,上述的源码,我只改了两个地方:
   g_bDrvList1 =  1.6; //第一次是1.1 打印出来是1,因为我用的是%d
   SCI_TRACE_LOW("g_bDrvList1 = %f, g_bDrvList2 = %d, para = %d",
                  g_bDrvList1,g_bDrvList2,para);
   第二次我改用%f输出数据格式。

   最后的打印结果:

   68-5:g_bDrvList1 = 19, g_bDrvList2 = 127, para = -1
   68-6:g_bDrvList1 = 0.000000, g_bDrvList2 = -1, para = 74
   68-7:g_bDrvList1 = 1644167167, g_bDrvList2 = 1, para = 1644167167

   看到了吧,呵呵,

    倒是希望伊莉莎能看到,哈哈
点评回复

使用道具 举报

发表于 2011-7-22 12:57:16 | 显示全部楼层
这个问题有意思
点评回复

使用道具 举报

发表于 2011-7-22 12:52:12 | 显示全部楼层
枚举类型的实际数据类型可能是整形(int)或者大小最接近的整形(在这里可能就是signed char),强制类型转换是按这个实际的整形类型来转换的。
枚举类型的实际整形类型由编译选项来确认!
点评回复

使用道具 举报

发表于 2011-7-22 12:16:06 | 显示全部楼层
楼上牛x
点评回复

使用道具 举报

发表于 2011-7-22 12:06:36 | 显示全部楼层
呵呵,伊莉莎,很简单,你去做一下就知道结果了,做过后也会加深你
      
        对enum类型的理解,对于这种概念性的理解,最好的理解是动手。


  单独就你提问的问题,说一点我个人的理解吧,不一定全部正确,下面:

   1:  g_bDrvList =  (te_list)para;
   2:   g_bDrvList =  para%list_max;

  这两条语句执行的结果可以相同,也可以不同;什么时候两条语句执行后
  g_bDrvList的值相同?那就是传递进来的参数para的值域被限制在list_0
  和list_max之间的时候,两者执行的结果是相同的;什么时候结果不同?
  那就是当传递进来的para的参数值超过list_max的时候,两者执行的结果
  是不同的。


    举个例子:

    在g_bDrvList被赋值之前,如果para的当前值是10(打个比方),那么

    在执行第一种方式
    1:  g_bDrvList =  (te_list)para;
    之后,g_bDrvList的值为10;至于这里为什么没有根据(te_list)的类型
    转换而被限制在list_0和list_max之间,后面我会解释这一点。

    在执行第二种方式
    2:   g_bDrvList =  para%list_max;
    之后,g_bDrvList的值为1;这个结果估计大家都明白,一次求余运算
   
    上面两种情况是否正确,伊莉莎可以做一下验证,下面就是我要说的
    一点个人理解了:

    1:  g_bDrvList =  (te_list)para;
    这条语句看似简单,其实隐藏了很多对我们有用的信息,先看右边
    (te_list)para这个东东本质上是一次运算,也就是把para原来的
    类型值转换为当前的te_list,但这次运算并不对para本身造成影响;
    这点看起来不太好理解,就好比你copy一个文件,copy后edit之后
    再改成另一个名字的文件,但对原来的文件没有进行破坏性的改造;

    这条语句里面还隐藏了另外一条重要的信息,那就是enum的概念本身
    typedef  enum
    {
      list_o,
      list_1,
      list_2,
      list_max
    }te_list;
    这里的声明和定义以及赋初值都操作过了,但表象下面还掩盖了一个
    不稳定因素,就是超范围;这里te_list本身是一个变量,并且指明
    这个变量的类型是enum花括号内的成员中的一名;但成员本身有一个
    值域范围,大多时候,我们使用系统或者说行业约定的序列空间来作
    为值域范围,很多第一个成员序列为0这样来default;但这并不是定
    死的,我也可以定义为-1,有时是为了表示一种错误报告,人们看到
    或收到-1就表示一种error,对人们来说,字符表示更直观,比如:
   
    typedef enum   
    {
       SMS_Send_Error = -1;
       ////////////

    }sms_log;
    这里的言外之意就是说成员值域范围可以在限制的长度范围内即有效
    的范围内进行随意的变化,甚至不同成员可以使用同一值域定位;但
    超出范围就会出错了;最常见的例子,很多在定义enum类型的时候会
    限制一个用户可用的值域空间,例如:

    typedef enum   
    {
       SMS_Send_Error = -1;
       ////////////
       SMS_Send_Max = 0xFFFF FFFF

    }sms_log;

    其中这里的意思就是用户自己定义的有效值域空间不得大于32位,当超过
    时,人们可以根据这个信息进行抛弃或者报错处理;但真正给予的值域
    大于的时候,编译过程并不一定会报错,这个要看编译器;比如ARM目前
    的编译器支持enum类型值域范围达64位,也就是只要赋予的数值不大于
    64位,编译器就不会报错;但这么大的值域范围用于并不一定全部用的
    上。

    理解了上面这些,再回头看伊莉莎的问题,相对来说就比较有些头绪了。

    看这些也许有些头晕,似乎我说的也多了点,大家喜欢看结果,哈哈



    再看这个enum类型的变量g_bDrvList,如果你在ARM上的编译器处理的
    话,下面会有鲜明的对比:
    g_bDrvList = 0xFFFF FFFF FFFF FFFF;// 64bit 不会报错
    g_bDrvList = 0xFFFF FFFF FFFF FFFF F;// 68bit 编译报错

    第二种就是超出了编译器规定的范围,道理就是如此的,理解了这些,
    也就明白了最开始我说的为什么
    1:  g_bDrvList =  (te_list)para;
    就算para是10,不仅编译不会报错,而且还合乎语法的原因了。

     有人会问,编译器是怎么规定的?
     哈哈,编译器其实本质上在我看来,它做的工作就是翻译而已,执行
     的是预处理功能,从这点上看编译器也可以叫预处理器(参见<Android
     基础教程>第三版第二章内容,即android基础教程),
     书上的这点跟我一贯的理解吻合。
     它的工作就是把人们看到的符号语言翻译成机器码,这个大家都知道,
     其实机器码也是中间态,因为还没有具体反映到硬件的执行动作,硬件
     上的与非门等等信号状态及走向的反应才是真正的执行,这点上叫编译
     器是预处理器也是基于这个看法。

     其实编译器去解析人们的符号语言的时候是有一定规范和约定的,你
     比如关键字的check等等,C中的for、if;java中的class、package;
     SQLite中的select、from、where;XML中的xml、version等等这些都
     是关键字,另外还有些约定和规范太多了,说不完,这只是例子。

     编译器是怎么执行这些约定和规范的,这个有点笼统,看个小例子
     就很清楚了:
     现在很流行的Android平台上,大家都晓得每个项目工程都有一个
     AndroidManifest.xml这样的主解析脚本文件,而且里面几乎不变
     的第一行都会写< ? xml  version= " 1.0 " encoding= "utf-
     8"?>
     这里的utf-8就是一种国际编码规范,这里的xml解析语句的意思,
     这里直接告诉JRE:我后面用的是基于这种编码规范的字符语言,
     你按照这种规范解释就行了。

      理解到这里,也就会明白编译器是怎么去执行人们的命令了吧,
      这里也就一个简单又简单的笼统概念,细节太多了,期待高人来
      解答。

      哈哈,不说了,扯了一肚子的闲话
     
   
   

   
    [em08][em08][em08][em08][em08][em08]
点评回复

使用道具 举报

发表于 2011-7-22 11:58:32 | 显示全部楼层
纯路过,很基本的东西,不一样哈
点评回复

使用道具 举报

发表于 2011-7-22 11:14:57 | 显示全部楼层
肯定不等价
点评回复

使用道具 举报

发表于 2011-7-22 11:09:06 | 显示全部楼层
ENUM的取值范围在定义时就指定了, 强制转换只是将变量转换为需要的相同类型,以便于运算,不影响取值范围
点评回复

使用道具 举报

发表于 2011-7-22 09:50:31 | 显示全部楼层
你见过类型转换会改变内存每个字节里的存储数据吗?答案是肯定不能限制
点评回复

使用道具 举报

 楼主| 发表于 2011-7-22 08:29:30 | 显示全部楼层
我问的是这个强制转换,会不会也会使右值的范围限定在ENUM的取值范围内!
点评回复

使用道具 举报

发表于 2011-7-21 19:58:06 | 显示全部楼层
首先类型就不样。
不知道楼主想考大家什么地方。
点评回复

使用道具 举报

发表于 2011-7-21 16:30:56 | 显示全部楼层
一个是强制转换 一个是求余,求余的过程中不知道是否强制装换为te_list
点评回复

使用道具 举报

发表于 2011-7-21 09:04:55 | 显示全部楼层
不 等 价
点评回复

使用道具 举报

发表于 2011-7-21 09:04:08 | 显示全部楼层
不等价。
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-12-26 20:13 , Processed in 0.057806 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表