标题:就来冒泡一下~写个冒泡排序玩玩~
只看楼主
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 10楼 九转星河
不会啊,怎么会越界?j 的初始值会判断,如果j的值等于len,根本不会进循环啊。

或许,但是优化思路是尽可能的减少计算次数。

程序代码:
    for(i=0;i<10-1;i++)    //10 - 1也是,每次外循环都要计算一次,虽然外循环的次数不多,但能省就省掉,引入一个变量保存这个值

        for(j=i+1;j<10;j++)
            if(a[j-1]>a[j])
            {  
                int t=a[j];  
                a[j]=a[j+1]; //这里j + 1已经计算过一次了,就不应该再计算第二次。 
                a[j+1]=t;  
            }  
    } 


[此贴子已经被作者于2017-5-8 20:10编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 20:04
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 11楼 renkejun1942
想到了个题外话~

从减少运算次数方面考虑
你说i=i+1和i+=1和i++比较是不是i++的执行效率会高些呢~

看到几乎所有for循环都是写i++而没有什么人会去写i=i+1的~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 20:10
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 12楼 九转星河
都不快,++i 最快。
i++有一个拷贝的过程,而前缀没有。

i = i + 1 和 i += 1
这个话题,你稍微等等,我记得有一个讲解,我看的并不仔细,所以记不太清楚了,等会儿手打给你。
是ICC编译器作者之一写的一个面试题的讲解。

[此贴子已经被作者于2017-5-8 20:12编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 20:10
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 13楼 renkejun1942
程序代码:
#include<stdio.h>
#include<time.h>
int main()
{
    double duration=0;
    int i=0;
    int s=10;
    clock_t TIME_START=0;
    clock_t TIME_END=0;

    while (s--)
    {
        TIME_START=clock();

        for (i=0;i<100000000;++i);

        TIME_END=clock();

        duration=(double)(TIME_END-TIME_START)/CLOCKS_PER_SEC;

        printf("%f\n",duration);
  
        TIME_START=clock();

         for (i=0;i<100000000;i++);

        TIME_END=clock();

        duration=(double)(TIME_END-TIME_START)/CLOCKS_PER_SEC;
   
        printf("%f\n\n",duration);
    }

    return 0;
}


感觉其实差不多~也许是小范围内运算差距不大~


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 20:42
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
《C专家编程》
A.3 C语言中不同的增值语句的区别何在

  考虑下面四条语句:
      x = x + 1;
      ++x;
      x++;
      x += 1;
  显然,这四条语句的功能是相等,它们都是把x的值增加1.如果像现在这样不考虑前后的上下文环境,它们之间并没有什么区别。应试者需要(隐式或显示的)提供适当的上下文环境,以便回答这个问题并找出这四条语句之间的区别。注意,最后一条语句是一种在算法语言中表达“x等于x加上1”的便捷方法。因此,这条语句仅供参考,我们需要寻找的是其他三条语句的独特性质。

  绝大多数C程序员可以立即指出++x是一种前缀自增,当它先增加x的值然后再在周围的表达式中使用x的值。而x++是一种后缀自增,它先在周围的表达式中使用x的值然后再增加x的值。有些人认为C语言存在++和--操作符的唯一原因是*p++在PDP-11机器上可以用一条单一的机器指令来表示。事实上并非如此,这个特性继承了PDP-7上的B语言,但自增和自减操作符在所有的硬件系统中的应用之广令人难以置信。

  有些程序员则在此处未作深入考虑,忽视了当x不是一个简单的变量而是一个涉及数组的表达式时,像 x += 1这样的形式是很有用的。如果你有一个复杂的数组引用,并需要证明同一种下标形式在两种引用中都可以使用,那么:
node[ i >> 3 ] += -( 0x01 << ( i & 0x7 ) );

就是你应该采用的方法。这个例子是我直接从操作系统的代码中取出来的,只有数据名作为了改动。优秀的应试者还能够指出左值只被计算了一次。这一点非常重要,因为下面的语句:
mang[ i++ ] += y;

被当作
mang[ i ] = mang[ i ] + y;
i++;

而不是
mang[ i++ ] = mang[ i++ ] + y;


  以前,当我们对一些申请Sun的Pascal编译器队伍的位置上候选人进行面试时,最好的那位候选人解释说这些区别于编译器的中间代码有关,例如++x表示取x的地址,增加它的内容,然后把值放在寄存器中;x++则表示取x的地址,把它的值装入寄存器中,然后增加内存中的x的值。顺便问一句,使用编译器术语,另外两条语句应该怎么描述?

  尽管Kernighan 和 Ritchie 认为自增操作比直接加1更有效率,但目前所使用的当代编译器通常在这方面都做得很好,使这几种方法的速度都一样。如果没有任何能够显示它们之间区别的相关上下文环境,现代的编译器在编译这些语句时应该产生相同的指令。它们应该是增加一个变量时最快的一种指令。你可以在喜欢的编译器上编译这些代码,编译器应该有一个选项,可以产生一个汇编指令列表。你也可以把编译器设置为调试模式,这样也常常可以使检查对应的C语句和汇编指令更为容易。不要使用优化选项,因为这些语句有可能因为优化而被精简掉。

。。。。。。。。。。。。。。。。。。。(省略2段)

  所以,有时候区别就在于哪一个在源代码中看上去更好看一点。一般较短的形式比较长的形式更容易阅读一些。然而,过度简洁也会导致代码难以阅读。当我还是一个系统编程研究生班级的助教时,一位学生让我看一些代码,他说代码里存在一个未知的BUG,但是由于代码过于紧张,所以无法把它找出来。在一些高年级的C程序员的嘲笑中,我们系统的把类似下面的单行代码:
frotz[ --j + i++ ] += --y;

扩展为功能相同但长度更长的:
--y;
--j;
frotz[ j + i ] = frotz[ j + i ] + y;
i++;

这让那位喜爱玩弄技巧的程序员颇感懊恼,使用这种方法,我们一下子就发现其中一个操作位置有误。

教训:不要在一行代码里实现太多的功能。

这种做法并不能使编译器产生的代码更有效率,而且会使你丧失调试代码的机会。正如K&R 所指出的那样,人人都知道调试比第一次编写代码要难上一倍。所以如果在编写代码时把自己的聪明发挥到极致,那么在调试时怎么办?

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 20:46
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 14楼 九转星河
你的clock()函数返回的也是处理器的嘀嗒数么?怎么感觉不像啊。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 20:48
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 14楼 九转星河
GCC 用-S选项,你看下++i 和i++产生的汇编码是不是一样的。

代码写简单点。

只要有++i 和 i++就行了。

在我的电脑上,我用的笨办法,写了2段C代码,分别看汇编码:(如果我没对比错,真是一样的耶。)
程序代码:
int
main( void )
{
int i = 5;
++i;

return 0;
}

程序代码:
    .file    "ceshi5.c"
    .def    ___main;    .scl    2;    .type    32;    .endef
    .text
    .globl    _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
LFB0:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $16, %esp
    call    ___main
    movl    $5, 12(%esp)
    addl    $1, 12(%esp)
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE0:
    .ident    "GCC: (GNU) 5.3.0"

程序代码:
int
main( void )
{
int i = 5;
i++;

return 0;
}

程序代码:
    .file    "ceshi6.c"
    .def    ___main;    .scl    2;    .type    32;    .endef
    .text
    .globl    _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
LFB0:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $16, %esp
    call    ___main
    movl    $5, 12(%esp)
    addl    $1, 12(%esp)
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE0:
    .ident    "GCC: (GNU) 5.3.0"




[此贴子已经被作者于2017-5-8 20:58编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 20:50
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 17楼 renkejun1942
我的对比过也是一样耶~

程序代码:
    .file    "a.c"
    .def    ___main;    .scl    2;    .type    32;    .endef
    .text
    .align 2
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    andl    $-16, %esp
    movl    $0, %eax
    addl    $15, %eax
    addl    $15, %eax
    shrl    $4, %eax
    sall    $4, %eax
    movl    %eax, -8(%ebp)
    movl    -8(%ebp), %eax
    call    __alloca
    call    ___main
    movl    $0, -4(%ebp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    $0, %eax
    leave
    ret

好像我的真的不是gcc5.3.0这个没有显示gcc版本~~~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 21:09
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 18楼 九转星河
要不要卸载了,重新安装。
我百度了一下更新,还挺麻烦的。

我靠,我突然发现我背着一个错误的答案走了这么长的一段时间,我一直认为前缀比后缀快,原来……是一样的,我靠。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 21:09
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 19楼 renkejun1942
先谢过了~这个感觉要花较多时间~还是等有时间再弄吧~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 21:11



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-476788-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.144703 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved