zxc2769 发表于 2013-12-28 15:52:19

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

    if ((__res = *cs - *ct++) != 0 || !*cs++)

XA144F 发表于 2013-12-28 15:55:50

我的答案是:我想抽死出这题的人。

zxc2769 发表于 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;
}

prow 发表于 2013-12-28 16:05:57

@@加几个括号能死啊。。。

竹风xu 发表于 2013-12-28 16:15:10

取值*和取反!同级,结合方向自右向左,在分析下去我就{:dizzy:}

monkerman 发表于 2013-12-28 16:19:07

if ((__res = *cs - *ct++) != 0 || !*cs++)
-------------------------------------------------------------

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

所以结果是这样的:
if ((__res = *cs - *(ct++)) != 0 || !*cs++)

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

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

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

90999 发表于 2013-12-28 16:25:50

KKK
                               *ct++
                      *cs -
      __res =
                                          != 0
                                                         *cs++
                                                   !
                                              ||

monkerman 发表于 2013-12-28 16:26:35

本帖最后由 monkerman 于 2013-12-28 16:37 编辑

// if ((__res = *cs - *ct++) != 0 || !*cs++)
// 试着用伪代码弄一下, 注意缩进对齐, 擦......
若 __res = *cs - *ct 为真
      ct++;
      我的处理
      结束
否则
      若 *cs == 0
                我的处理
                结束
      否则
               结束

      ct++;
      cs++;
// 是不是发现, 原来的写法更优雅. 哈哈

zxc2769 发表于 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;
    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);

zxc2769 发表于 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;
    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);

mitchell 发表于 2013-12-28 16:33:10

zxc2769 发表于 2013-12-28 16:02
/**
* This function will compare two strings with specified maximum length
*


和以下的代码是等价的:

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

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

    return __res;
}

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

374184600 发表于 2013-12-28 16:42:33

C语言真是博大精深。

ryq0110 发表于 2013-12-28 16:45:23

有毛病,抽死出这题的人

zxc2769 发表于 2013-12-28 16:46:07

monkerman 发表于 2013-12-28 16:26


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

monkerman 发表于 2013-12-28 18:02:26

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

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

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

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

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

chiooo1 发表于 2013-12-28 18:10:17

ndust 发表于 2013-12-28 20:35:44

不同的编译器结果可能不同。纯属为了考试而设计的题。不利于安全设计,不利于他人理解程序。如果这种考试多了,丰田车的故障现象就会非常普遍了。

jdw924 发表于 2013-12-28 20:57:17

这样写程序,没有单位会用他。

qwert1213131 发表于 2014-1-23 19:41:26

作死的节奏啊

dr2001 发表于 2014-1-23 19:57:22

这段语句没有二义性,可以用于加深C语法的理解。当然__res = 那句提出去就更好了,我认为。

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

dr2001 发表于 2014-1-23 19:58:49

本帖最后由 dr2001 于 2014-1-23 20:01 编辑

ndust 发表于 2013-12-28 20:35
不同的编译器结果可能不同。纯属为了考试而设计的题。不利于安全设计,不利于他人理解程序。如果这种考试多 ...

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

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

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

SH_LLY 发表于 2014-3-1 18:03:22

由于编译器不同,或者编译器Bug,可能得到错误结果。很难查错的。

AKG 发表于 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 --;
    }


如果要我选,我还是会选最后那种写法
至少看懂代码的时间最后一种最少
页: [1]
查看完整版本: if ((__res = *cs - *ct++) != 0 || !*cs++)这个运算中的优先级顺.....