来来来,学习无止境,春节反而有点无聊来一个:I=(++i)+(++i);当i=1初值时候结果是多少
刚才无意间看到的,这种纯粹考试的实际中不会出现但是的确可以考验基础知识 5。 好久不做c语言了。2+3=5 看编译器怎么处理,开不开优化有可能不一样,别这样写。 5。紫薯布丁 本帖最后由 Himem 于 2024-2-10 17:20 编辑
gcc旧版和msvc开优化居然结果是6 哈哈,果然好多老司机都搞不明白这个问题了,而且不同的编译器也搞不懂这个问题
这个看来是个值得讨论的。。。
先说我看到的,说是为6,原因是因为说是在同一时刻,变量值不能两个不同的,但是没有说当i=3时候,怎么又将i值赋给第一个++i,因为此时i已经计算过了=2
最后点我没有理解到。 本帖最后由 Himem 于 2024-2-10 18:33 编辑
1a2b3c 发表于 2024-2-10 17:35
哈哈,果然好多老司机都搞不明白这个问题了,而且不同的编译器也搞不懂这个问题
这个看来是个值得讨论的。 ...
(引用自7楼)
我看汇编是MSC16编译为(i+2)*2 优化后 i*2+4
gcc8结果没错是5 用clion应该是5 1a2b3c 发表于 2024-2-10 17:35
哈哈,果然好多老司机都搞不明白这个问题了,而且不同的编译器也搞不懂这个问题
这个看来是个值得讨论的。 ...
(引用自7楼)
好像谭浩强的c语言里有说到,以前的turbo c里好像结果和现在的不一样 tang_qianfeng 发表于 2024-2-10 20:20
好像谭浩强的c语言里有说到,以前的turbo c里好像结果和现在的不一样
(引用自10楼)
这个故意弄出来的一个代码感觉真的会引起很多问题,涉及到c语言原理上的一些东西,我这个半罐水的半罐水压根搞不懂了
有没有权威一点的高手来解答看看,目的不是这句代码本身,而是一些原理性的, 手头几个编译器试了下, VS2005 给出了 6 的结果,其他几个给出的是 5,看样子这问题本身就很有问题。
本帖最后由 tang_qianfeng 于 2024-2-10 20:52 编辑
1a2b3c 发表于 2024-2-10 20:36
这个故意弄出来的一个代码感觉真的会引起很多问题,涉及到c语言原理上的一些东西,我这个半罐水的半罐水 ...
(引用自11楼)
这个和编译器有关,结果不是唯一的 t3486784401 发表于 2024-2-10 20:42
手头几个编译器试了下, VS2005 给出了 6 的结果,其他几个给出的是 5,看样子这问题本身就很有问题。
...
(引用自12楼)
这种代码,感觉意义不大 一看就是受谭浩强毒害的问题,代码里就不应该出现这类书写方式 kitten 发表于 2024-2-10 20:50
一看就是受谭浩强毒害的问题,代码里就不应该出现这类书写方式
(引用自15楼)
确实这句代码应该是故意写出来的,实际中不会出现这样的情况,因为这一类的是会提前写代码的人知道结果应该怎么运行才会去写(至少我是这样),但是这些编译器正常应该按照什么方式去处理呢,不晓得有没有个标准, 哎搞不懂了,我也不想去太细节研究了,先把基础的if else 搞透彻就已经可以大半罐水了:)😄 tang_qianfeng 发表于 2024-2-10 20:45
这种代码,感觉意义不大
(引用自14楼)
忽然想起来 有时解析协议之类场景确实会这样写
U32_BE = *i++<<24 | *i++<<16 | *i++<<8 | *i++;
也有问题 Himem 发表于 2024-2-13 08:13
忽然想起来 有时解析协议之类场景确实会这样写
U32_BE = *i++
(引用自18楼)
如果是我,我会拆解开来一步步进行,如果可以的话
正因为自己菜搞不懂,就用最简单的写,
就像喔从来没有用过(因为不会)?:这种写法一样,我都是直接if else
😂 Himem 发表于 2024-2-13 08:13
忽然想起来 有时解析协议之类场景确实会这样写
U32_BE = *i++
(引用自18楼)
还有像你这个,我搞不清楚计算先后顺序,所以回用无数个括号。。。
让自己看得懂才行。哈哈 1a2b3c 发表于 2024-2-10 21:01
哎搞不懂了,我也不想去太细节研究了,先把基础的if else 搞透彻就已经可以大半罐水了:)😄 ...
(引用自17楼)
你说的这个我也不会,根本就一次没用过。 这问题属于c语言缺陷{:titter:} 1a2b3c 发表于 2024-2-13 13:16
如果是我,我会拆解开来一步步进行,如果可以的话
正因为自己菜搞不懂,就用最简单的写,
就像喔从来没有 ...
(引用自19楼)
但是面试的时候很多公司莫名其妙喜欢考你懂不懂这种写法。还有很多常见算法。比如说冒泡排序很多公司喜欢考。明明百度一下能看懂能复制粘贴就可以了。平时根本不会去特意记这些算法。包括用结构体定义位变量也是头文件里面直接复制粘贴就会的面试也喜欢考你。 1a2b3c 发表于 2024-2-13 13:18
还有像你这个,我搞不清楚计算先后顺序,所以回用无数个括号。。。
让自己看得懂才行。哈哈 ...
(引用自20楼)
我之前看c语言入门教程就有说不确定优先级加括号是最保险的。 本帖最后由 tomzbj 于 2024-2-15 18:47 编辑
之前我就在知乎答过这个问题, 一句话, 出这种题的该挨揍, 实际工程里写成这样的更该挨揍.
实测, 各个不同平台用gcc编译, 大体上加-O3的话是6, 先算两个++最后求和. 加-O0就成5了, 字面上从右往左进行.
总之, 既然是未定义行为, 5和6都有可能, 也不要争论应该是哪个了, 没有意义.
之前在知乎答题的链接: https://www.zhihu.com/question/347864795/answer/1695354706 Himem 发表于 2024-2-13 08:13
忽然想起来 有时解析协议之类场景确实会这样写
U32_BE = *i++
(引用自18楼)
我反正给学生讲课就要求他们++, --一律单独作为一行来写, 不许这么写在语句里 我们公司不允许这种写法,虽然很短,但是不好维护。 一行代码的写法有啥不好维护的?我觉得只要是干代码的都应该能维护 tomzbj 发表于 2024-2-15 18:46
之前我就在知乎答过这个问题, 一句话, 出这种题的该挨揍, 实际工程里写成这样的更该挨揍.
实测, 各个不同 ...
(引用自25楼)
去看看世界C语言混乱大赛,那些人是不是该被绞死 xy3dg12 发表于 2024-2-19 14:02
去看看世界C语言混乱大赛,那些人是不是该被绞死
(引用自29楼)
哈哈哈 站在工程的角度,确实该绞死 tomzbj 发表于 2024-2-15 18:52
我反正给学生讲课就要求他们++, --一律单独作为一行来写, 不许这么写在语句里 ...
(引用自26楼)
不过记得libc还是linux里,strcpy是 while((*s++ = *t++) != '\0');这么实现的 这就像研究茴香豆的茴字有几种写法,做为深度爱好和顶级高手,研究研究无妨。对绝大多数人,记住:别这么写,足矣 {:lol:} Himem 发表于 2024-2-19 15:59
不过记得libc还是linux里,strcpy是 while((*s++ = *t++) != '\0');这么实现的
(引用自31楼)
看具体实现吧... 这个说来稍微有点话长
稍微靠谱点的库都会把memcpy设计成先按32位或64位来批量复制, 最后多出的几个字节再按单字节复制, 你想想是不是会快很多?
然后strcpy有可能其实就是memcpy, 最后一个长度参数是strlen(s)
但是memcpy不解决源内存和目标内存区域有可能重叠的问题, 要保证内存重叠时也能正常复制的话就得用memmove.
memmove的实现方式又有好几种, 最简单的是判断重叠区域, 找到保证不重叠的小块再对小块用memcpy,
另一种是如果重叠并且s在前d在后, 就倒过来, 从s的最后往前复制.
然后, 许多平台的c库为了简便, 就直接把对外的memcpy函数做成memmove的别名.
感兴趣的话可以自己读读各平台libc的源码. Himem 发表于 2024-2-19 15:59
不过记得libc还是linux里,strcpy是 while((*s++ = *t++) != '\0');这么实现的
(引用自31楼)
你这个是没问题的,它并不是同个变量在同一条语句里多次赋值,没毛病 写法即表达方式,是越容易让人理解越好, 当然是拆开来更容易让人理解。
有那么多精力在写法上绕圈圈,不如花这些精力去研究算法 ibmx311 发表于 2024-2-18 08:43
一行代码的写法有啥不好维护的?我觉得只要是干代码的都应该能维护
(引用自28楼)
一眼看去,头脑反应不过来。
我们要求是写多几行,一看就懂那种。
页:
[1]