搜索
bottom↓
回复: 22

if ((__res = *cs - *ct++) != 0 || !*cs++)这个运算中的优先级顺.....

[复制链接]

出0入0汤圆

发表于 2013-12-28 15:52:19 | 显示全部楼层 |阅读模式
    if ((__res = *cs - *ct++) != 0 || !*cs++)

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-12-28 15:55:50 | 显示全部楼层
我的答案是:我想抽死出这题的人。

出0入0汤圆

 楼主| 发表于 2013-12-28 16:02:01 | 显示全部楼层
XA144F 发表于 2013-12-28 15:55
我的答案是:我想抽死出这题的人。

/**
* This function will compare two strings with specified maximum length
*
* @param cs the string to be compared
* @param ct the string to be compared
* @param count the maximum compare length
*
* @return the result
*/
rt_ubase_t rt_strncmp(const char *cs, const char *ct, rt_ubase_t count)
{
    register signed char __res = 0;

    while (count)
    {
        if ((__res = *cs - *ct++) != 0 || !*cs++)
            break;
        count --;
    }

    return __res;
}

出0入8汤圆

发表于 2013-12-28 16:05:57 | 显示全部楼层
@@加几个括号能死啊。。。

出0入0汤圆

发表于 2013-12-28 16:15:10 | 显示全部楼层
取值*和取反!同级,结合方向自右向左,在分析下去我就

出0入0汤圆

发表于 2013-12-28 16:19:07 | 显示全部楼层
  if ((__res = *cs - *ct++) != 0 || !*cs++)
-------------------------------------------------------------

|| 运算符是遵循"短路求值" 原则的, 肯定是先左后右. 左边成立后, 右边不执行, ++ 运算无效果. 否则, 有效果.

所以结果是这样的:
  1. if ((__res = *cs - *(ct++)) != 0 || !*cs++)
复制代码


++ 运算符的优先级比 * 运算符高, 但是考虑到序列点在 if 条件表达式结束, 所以 ++ 的副作用是先赋值后自增. 也就是 ct 的值还是自增之前的.  

擦.....脑袋有点乱. 哪里不理解就提出来.

最好楼主自己搞个程序测试一下就明白了.

出0入0汤圆

发表于 2013-12-28 16:25:50 | 显示全部楼层
KKK
                               *ct++
                      *cs -
        __res =
                                            != 0  
                                                         *cs++
                                                     !
                                              ||

出0入0汤圆

发表于 2013-12-28 16:26:35 | 显示全部楼层
本帖最后由 monkerman 于 2013-12-28 16:37 编辑
  1. // if ((__res = *cs - *ct++) != 0 || !*cs++)
  2. // 试着用伪代码弄一下, 注意缩进对齐, 擦......
  3. 若 __res = *cs - *ct 为真
  4.         ct++;
  5.         我的处理
  6.         结束
  7. 否则
  8.         若 *cs == 0
  9.                 我的处理
  10.                 结束
  11.         否则
  12.                结束

  13.         ct++;
  14.         cs++;
  15. // 是不是发现, 原来的写法更优雅. 哈哈
复制代码

出0入0汤圆

 楼主| 发表于 2013-12-28 16:29:15 | 显示全部楼层
呵呵 这个是我今天在公司闲着没事 按RTthread的时候 看了下这个函数找到的!

/**
* This function finds a device driver by specified name.
*
* @param name the device driver's name
*
* @return the registered device driver on successful, or RT_NULL on failure.
*/
rt_device_t rt_device_find(const char *name)
{
    struct rt_object *object;
    struct rt_list_node *node;
    struct rt_object_information *information;

    extern struct rt_object_information rt_object_container[];

    /* enter critical */
    if (rt_thread_self() != RT_NULL)
        rt_enter_critical();

    /* try to find device object */
    information = &rt_object_container[RT_Object_Class_Device];
    for (node  = information->object_list.next;
         node != &(information->object_list);
         node  = node->next)
    {
        object = rt_list_entry(node, struct rt_object, list);
        if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
        {
            /* leave critical */
            if (rt_thread_self() != RT_NULL)
                rt_exit_critical();

            return (rt_device_t)object;
        }
    }

    /* leave critical */
    if (rt_thread_self() != RT_NULL)
        rt_exit_critical();

    /* not found */
    return RT_NULL;
}
RTM_EXPORT(rt_device_find);

出0入0汤圆

 楼主| 发表于 2013-12-28 16:30:30 | 显示全部楼层

/**
* This function finds a device driver by specified name.
*
* @param name the device driver's name
*
* @return the registered device driver on successful, or RT_NULL on failure.
*/
rt_device_t rt_device_find(const char *name)
{
    struct rt_object *object;
    struct rt_list_node *node;
    struct rt_object_information *information;

    extern struct rt_object_information rt_object_container[];

    /* enter critical */
    if (rt_thread_self() != RT_NULL)
        rt_enter_critical();

    /* try to find device object */
    information = &rt_object_container[RT_Object_Class_Device];
    for (node  = information->object_list.next;
         node != &(information->object_list);
         node  = node->next)
    {
        object = rt_list_entry(node, struct rt_object, list);
        if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)        {
            /* leave critical */
            if (rt_thread_self() != RT_NULL)
                rt_exit_critical();

            return (rt_device_t)object;
        }
    }

    /* leave critical */
    if (rt_thread_self() != RT_NULL)
        rt_exit_critical();

    /* not found */
    return RT_NULL;
}
RTM_EXPORT(rt_device_find);

出0入0汤圆

发表于 2013-12-28 16:33:10 | 显示全部楼层
zxc2769 发表于 2013-12-28 16:02
/**
* This function will compare two strings with specified maximum length
*

和以下的代码是等价的:

  1. rt_ubase_t rt_strncmp(const char *cs, const char *ct, rt_ubase_t count)
  2. {
  3.     register signed char __res = 0;

  4.     while (count)
  5.     {
  6.         __res = *cs - *ct;
  7.         ct++;
  8.         if(__res != 0){
  9.              break;
  10.         }
  11.         else{
  12.             if(*cs == 0) {
  13.                 cs++;
  14.                 break;
  15.             }
  16.             else{
  17.                cs++;
  18.             }
  19.         }
  20.         count --;
  21.     }

  22.     return __res;
  23. }
复制代码


还不如原来的代码简单易懂。。

出0入0汤圆

发表于 2013-12-28 16:42:33 | 显示全部楼层
C语言真是博大精深。

出0入0汤圆

发表于 2013-12-28 16:45:23 | 显示全部楼层
有毛病,抽死出这题的人

出0入0汤圆

 楼主| 发表于 2013-12-28 16:46:07 | 显示全部楼层

恩 !经过你这样一说 感觉理解上去了!
这样写代码少占空间咋的? 太有内涵了!

出0入0汤圆

发表于 2013-12-28 18:02:26 | 显示全部楼层
zxc2769 发表于 2013-12-28 16:46
恩 !经过你这样一说 感觉理解上去了!
这样写代码少占空间咋的? 太有内涵了! ...


生成的代码大小是差不多少的.  可以忽略都.

我觉得吧:
1. 至少占用编辑器的空间少. 一眼就能瞅下. 理解的代码的时候, 瞅着一行动脑子就行了. 用 if...else 分拆的话, 眼睛得上下翻动.  没准还要滚轮.

2. 个人喜欢这种写法, 简洁, 优雅. 不这么写的话, 会很杂乱.

3. 不丧失易读性的前提下, 越简洁越好. 毕竟代码首先是给人读的. 适当的复杂度可以接受.  又不会产生什么未定义行为或者有歧义什么的.
头像被屏蔽

出0入0汤圆

发表于 2013-12-28 18:10:17 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-12-28 20:35:44 | 显示全部楼层
不同的编译器结果可能不同。纯属为了考试而设计的题。不利于安全设计,不利于他人理解程序。如果这种考试多了,丰田车的故障现象就会非常普遍了。

出0入0汤圆

发表于 2013-12-28 20:57:17 | 显示全部楼层
这样写程序,没有单位会用他。

出0入0汤圆

发表于 2014-1-23 19:41:26 | 显示全部楼层
作死的节奏啊

出0入0汤圆

发表于 2014-1-23 19:57:22 | 显示全部楼层
这段语句没有二义性,可以用于加深C语法的理解。当然__res = 那句提出去就更好了,我认为。

C的||带序列点,且||有短路功能。所以,if里边的实质是先执行完毕||前边部分的所有内容,发生所有副作用之后;再根据结果进行真伪判定,决定是否继续后边的操作。

出0入0汤圆

发表于 2014-1-23 19:58:49 | 显示全部楼层
本帖最后由 dr2001 于 2014-1-23 20:01 编辑
ndust 发表于 2013-12-28 20:35
不同的编译器结果可能不同。纯属为了考试而设计的题。不利于安全设计,不利于他人理解程序。如果这种考试多 ...


看看代码,看看C标准。如果能指出哪里有问题,不防明确指出一下。

||是序列点,实际上if里边是两个独立的,带有判断/短路功能的语句;人家代码这么写是完全没问题的。。。

这么写反而逻辑更清晰一些;一堆if更容易搞乱东西。

出0入0汤圆

发表于 2014-3-1 18:03:22 | 显示全部楼层
  由于编译器不同,或者编译器Bug,可能得到错误结果。很难查错的。

出0入0汤圆

发表于 2014-3-1 18:25:14 | 显示全部楼层
和下面代码效果一样

        while (count && *cs)
    {
            if(*cs++ != *ct++)
                    break;
        count --;
    }
       
        while (count)
    {
            if(*cs != *ct)
                    break;
                if(*cs == 0)
                    break;
                ct++;
                cs++;
        count --;
    }


如果要我选,我还是会选最后那种写法
至少看懂代码的时间最后一种最少
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 20:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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