if ((__res = *cs - *ct++) != 0 || !*cs++)这个运算中的优先级顺.....
if ((__res = *cs - *ct++) != 0 || !*cs++) 我的答案是:我想抽死出这题的人。 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;
}
@@加几个括号能死啊。。。 取值*和取反!同级,结合方向自右向左,在分析下去我就{:dizzy:} if ((__res = *cs - *ct++) != 0 || !*cs++)
-------------------------------------------------------------
|| 运算符是遵循"短路求值" 原则的, 肯定是先左后右. 左边成立后, 右边不执行, ++ 运算无效果. 否则, 有效果.
所以结果是这样的:
if ((__res = *cs - *(ct++)) != 0 || !*cs++)
++ 运算符的优先级比 * 运算符高, 但是考虑到序列点在 if 条件表达式结束, 所以 ++ 的副作用是先赋值后自增. 也就是 ct 的值还是自增之前的.
擦.....脑袋有点乱. 哪里不理解就提出来.
最好楼主自己搞个程序测试一下就明白了. KKK
*ct++
*cs -
__res =
!= 0
*cs++
!
|| 本帖最后由 monkerman 于 2013-12-28 16:37 编辑
// if ((__res = *cs - *ct++) != 0 || !*cs++)
// 试着用伪代码弄一下, 注意缩进对齐, 擦......
若 __res = *cs - *ct 为真
ct++;
我的处理
结束
否则
若 *cs == 0
我的处理
结束
否则
结束
ct++;
cs++;
// 是不是发现, 原来的写法更优雅. 哈哈
呵呵 这个是我今天在公司闲着没事 按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);
/**
* 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: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;
}
还不如原来的代码简单易懂。。 C语言真是博大精深。 有毛病,抽死出这题的人 monkerman 发表于 2013-12-28 16:26
恩 !经过你这样一说 感觉理解上去了!
这样写代码少占空间咋的? 太有内涵了! zxc2769 发表于 2013-12-28 16:46
恩 !经过你这样一说 感觉理解上去了!
这样写代码少占空间咋的? 太有内涵了! ...
生成的代码大小是差不多少的.可以忽略都.
我觉得吧:
1. 至少占用编辑器的空间少. 一眼就能瞅下. 理解的代码的时候, 瞅着一行动脑子就行了. 用 if...else 分拆的话, 眼睛得上下翻动.没准还要滚轮.
2. 个人喜欢这种写法, 简洁, 优雅. 不这么写的话, 会很杂乱.
3. 不丧失易读性的前提下, 越简洁越好. 毕竟代码首先是给人读的. 适当的复杂度可以接受.又不会产生什么未定义行为或者有歧义什么的. {:handshake:} 不同的编译器结果可能不同。纯属为了考试而设计的题。不利于安全设计,不利于他人理解程序。如果这种考试多了,丰田车的故障现象就会非常普遍了。 这样写程序,没有单位会用他。 作死的节奏啊 这段语句没有二义性,可以用于加深C语法的理解。当然__res = 那句提出去就更好了,我认为。
C的||带序列点,且||有短路功能。所以,if里边的实质是先执行完毕||前边部分的所有内容,发生所有副作用之后;再根据结果进行真伪判定,决定是否继续后边的操作。
本帖最后由 dr2001 于 2014-1-23 20:01 编辑
ndust 发表于 2013-12-28 20:35
不同的编译器结果可能不同。纯属为了考试而设计的题。不利于安全设计,不利于他人理解程序。如果这种考试多 ...
看看代码,看看C标准。如果能指出哪里有问题,不防明确指出一下。
||是序列点,实际上if里边是两个独立的,带有判断/短路功能的语句;人家代码这么写是完全没问题的。。。
这么写反而逻辑更清晰一些;一堆if更容易搞乱东西。 由于编译器不同,或者编译器Bug,可能得到错误结果。很难查错的。 和下面代码效果一样
while (count && *cs)
{
if(*cs++ != *ct++)
break;
count --;
}
while (count)
{
if(*cs != *ct)
break;
if(*cs == 0)
break;
ct++;
cs++;
count --;
}
如果要我选,我还是会选最后那种写法
至少看懂代码的时间最后一种最少
页:
[1]