【问题标题】:Copying elements of an array using for loop vs struct pointers使用for循环与结构指针复制数组元素
【发布时间】:2014-07-21 08:53:19
【问题描述】:

如果我有两个相同大小的数组,比如说,

int pa1[100];
int pa2[100];

我知道,如果在代码中的某个时刻,我想将 pa2 的内容复制到 pa1 中,

pa1 = pa2;

不是正确的方法。相反,我可以使用一个循环。但是我在想,如果我有两个结构指针(ps1,ps2),那么写是有效的:

*ps1 = *ps2;

如果该结构包含一个 100 int 数组,并且我让 ps1 和 ps2 分别指向 pa1 和 pa2,那么前面的指令与复制数组中每个元素的循环有什么区别?

for (int i = 0; i<100; i++) pa1[i] = pa2[i]; 

它有任何性能差异吗?为什么?

我的第一个猜测是使用指针比使用循环更好,但我不确定。我尝试进行网络搜索但没有成功,可能是因为我找不到准确的词语来描述我想知道的内容。

【问题讨论】:

  • 现代编译器可能会将您的两个选项视为相同的操作,并且应该发出相同或相似的代码。在这种情况下最好编写可读性代码。第二个最佳选择是显式调用memcpy(),编译器也可能优化掉它。

标签: c arrays pointers struct


【解决方案1】:

通常编译器在这种情况下使用标准 C 函数 memcpy。它比使用手动编写的循环要快得多。

【讨论】:

    【解决方案2】:

    是的,它可以工作,如下面的程序所示。

    不,您不能真正确定编译器将选择在内部执行的代码。但是编译器很可能会发出非常有效的代码,例如调用 memcopy(但不需要包含)或使用优化的程序集。

    但不能保证。您必须测试或分析生成的程序集输出。

    在可读性部分,我认为复制结构至少与显式循环或调用 memcopy 一样容易阅读。如果这两个数组伴随着与数组相关的其他变量,也可以进入结构,那就更好了。

    #include <stdio.h>
    
    int main() {
    
        struct {
            int t[10];
        } s1, s2;
    
        int i = 0;
        for(i=0; i < 10 ; ++i){
            s1.t[i] = i;
            s2.t[i] = -1;
        }
    
        printf("s1 [%d %d ... %d %d] s2 [%d %d ... %d %d]\n",
            s1.t[0], s1.t[1], s1.t[8], s1.t[9], 
            s2.t[0], s2.t[1], s2.t[8], s2.t[9]);
    
        s2 = s1;
    
        printf("s1 [%d %d ... %d %d] s2 [%d %d ... %d %d]\n", 
            s1.t[0], s1.t[1], s1.t[8], s1.t[9], 
            s2.t[0], s2.t[1], s2.t[8], s2.t[9]);
    
    }
    

    【讨论】:

      【解决方案3】:

      你是说这个吗?

      int pa1[100], pa2[100];
      int *ps1 = pa1, *ps2 = pa2;
      
      // Initialize the arrays
      
      *ps1 = *ps2;
      

      如果是,那么最后一行所做的就是:

      pa1[0] = pa2[0];
      

      没有别的。 如果您需要将一个数组的所有元素复制到另一个数组中,您需要遍历它们。

      编辑:在第二次阅读时,现在我认为您的意思是:

      struct a{
          int v[100];
      };
      
      int pa1[100], pa2[100];
      a *ps1, *ps2;
      
      // Initialize the arrays
      
      ps1 = (a*)pa1;
      ps2 = (a*)pa2;
      
      *ps1 = *ps2;
      

      非常聪明,尽管您不会为您的问题找到明确的答案。这是特定于实现的,尽管许多实现似乎使用 memcpy 或类似的东西,但可能比迭代数组快一点。其次,您的编译器将使用迭代轻松优化两个数组之间的副本,因此差异可能可以忽略不计,并且不值得首先编写结构和指针的额外努力。

      所以,这里真正的问题是:为什么需要这样的优化?

      【讨论】:

      • 啊,我明白了。也许与我刚刚进行的编辑有关?
      • @cassiorenan 解释我对这些结构和数组具体做什么可能需要很长时间。我可以说我正在使用一个资源有限的微控制器和一个严格的实时性能要求应用程序。因此,我需要尽可能地优化每一行代码,以保证最佳的实时性能。我在试图避免循环时想到了这个想法。我一直在想,也许这也取决于MCU如何管理内存,在它的硬件架构层面,我错了吗?
      • @esal26 你在使用现代编译器吗?通过修改代码,您会使 gcc 等编译器更难以优化。 (但是,如果您被 20 年前的错误设置卡住,那么您可能别无选择)
      • @MattMcNabb 我正在使用 avr-gcc
      猜你喜欢
      • 2019-03-22
      • 1970-01-01
      • 2021-09-04
      • 1970-01-01
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      • 2013-06-11
      • 2015-06-10
      相关资源
      最近更新 更多