C++ 与潜伏的臭虫结合

C++ 与潜伏的臭虫结合,c++,arrays,C++,Arrays,如果我们想遍历整个数组并将数组的每个值与数组中的一个数字进行比较,比如说arr[0],那么,为什么建议使用arr[0]初始化int,比如int acomp=arr[0]并将acomp与数组中的每个整数进行比较,而不是将数组中的每个整数与arr[0]进行比较? 例如,在下面的联合法典中,有人向我指出,代码2比代码1好,但我不太清楚为什么 int unionarr(int p, int q){ //Code 1 for(int i=0;i<size;i++)

如果我们想遍历整个数组并将数组的每个值与数组中的一个数字进行比较,比如说arr[0],那么,为什么建议使用arr[0]初始化int,比如int acomp=arr[0]并将acomp与数组中的每个整数进行比较,而不是将数组中的每个整数与arr[0]进行比较? 例如,在下面的联合法典中,有人向我指出,代码2比代码1好,但我不太清楚为什么

int unionarr(int p, int q){            //Code 1
    for(int i=0;i<size;i++)
        if(arr[i]==arr[p])
            arr[i]=arr[q];}

int unionarr(int p, int q){            //Code 2
    int pid=arr[p];
    int qid=arr[q];
        for(int i=0;i<size;i++)
        if(arr[i]==pid)
            arr[i]=qid;}
intunionarr(intp,intq){//code 1

对于(int i=0;i而言,对必须在数组中重复查找的值进行本地复制pid和qid是一种性能优化。

但是,如果任何现代编译器都无法识别并隐式地进行优化,我会感到惊讶。

这是一个正确性问题。

for
循环中的赋值可以修改数组值。您可以修改比较中使用的元素或赋值的右侧。这就是为什么您必须在进入循环之前保存它们。

使用可以比较两者。您关心的是循环中的指令

使用Clang 4.0,组件是:

  • 代码1

    movsxd  rax, dword ptr [rbp - 16]
    mov     ecx, dword ptr [4*rax + arr]
    movsxd  rax, dword ptr [rbp - 8]
    cmp     ecx, dword ptr [4*rax + arr]
    jne     .LBB0_4
    movsxd  rax, dword ptr [rbp - 12]
    mov     ecx, dword ptr [4*rax + arr]
    movsxd  rax, dword ptr [rbp - 16]
    mov     dword ptr [4*rax + arr], ecx
    
  • 代码2

    movsxd  rax, dword ptr [rbp - 24]
    mov     ecx, dword ptr [4*rax + arr]
    cmp     ecx, dword ptr [rbp - 16]
    jne     .LBB0_4
    mov     eax, dword ptr [rbp - 20]
    movsxd  rcx, dword ptr [rbp - 24]
    mov     dword ptr [4*rcx + arr], eax
    

<代码>联合< /COD>是C++中的保留关键字,什么是“代码> int PID=ARR [P];int qID= ARR[q];< /代码>如果您不使用这两个变量?您是指<代码>(ARR[i]=PID)< /C>和<代码> ARR[i]=qid;,不是吗?告诉你其中一个比另一个好的人是在撒谎,因为用优化构建两者,检查生成的程序集是否有差异。代码现在看起来更好了,但你的标题仍然很误导,因为代码中没有
联合
,也不清楚你指的是什么错误。Andom想:是不是编译器无法在第一个代码中进行优化,因为存在别名可能性
&arr[i]=&arr[p]=&arr[q]
?谢谢!如果有人仍然无法理解此答案,请假设arr[]={0,1,1,2},p是1,q是3。如果按代码1进行,我将得到的答案是{0,2,1,2}作为arr[1]当我在for循环中变成2时,它不会改变,因为arr[2]不等于arr[p],因为arr[1]现在变成了2。如果我们按代码1,我们会得到正确的答案,即,{0,2,2,2}。